| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "garnet/bin/zxdb/symbols/code_block.h" |
| #include "garnet/bin/zxdb/symbols/symbol_context.h" |
| #include "gtest/gtest.h" |
| |
| namespace zxdb { |
| |
| TEST(CodeBlock, ContainsAddress) { |
| auto block = fxl::MakeRefCounted<CodeBlock>(Symbol::kTagLexicalBlock); |
| |
| SymbolContext context = SymbolContext::ForRelativeAddresses(); |
| |
| // No code range: contains all addresses. |
| EXPECT_TRUE(block->ContainsAddress(context, 0)); |
| EXPECT_TRUE(block->ContainsAddress(context, 0x2000)); |
| |
| // Set some ranges. |
| block->set_code_ranges(AddressRanges( |
| AddressRanges::kCanonical, |
| {AddressRange(0x1000, 0x2000), AddressRange(0x3000, 0x3001)})); |
| |
| // Blocks should count the beginning but not the end as inside them. |
| EXPECT_TRUE(block->ContainsAddress(context, 0x1000)); |
| EXPECT_TRUE(block->ContainsAddress(context, 0x1100)); |
| EXPECT_FALSE(block->ContainsAddress(context, 0x2000)); |
| |
| EXPECT_FALSE(block->ContainsAddress(context, 0x2fff)); |
| EXPECT_TRUE(block->ContainsAddress(context, 0x3000)); |
| EXPECT_FALSE(block->ContainsAddress(context, 0x3001)); |
| EXPECT_FALSE(block->ContainsAddress(context, 0x3002)); |
| |
| // Test with a non-relative symbol context. |
| constexpr uint64_t kBase = 0x10000000; |
| SymbolContext base_context(kBase); |
| EXPECT_FALSE(block->ContainsAddress(base_context, 0x1000)); |
| EXPECT_TRUE(block->ContainsAddress(base_context, kBase + 0x1000)); |
| } |
| |
| TEST(CodeBlock, GetMostSpecificChild) { |
| auto outer = fxl::MakeRefCounted<CodeBlock>(Symbol::kTagLexicalBlock); |
| |
| // Outer has two ranges. |
| outer->set_code_ranges(AddressRanges( |
| AddressRanges::kCanonical, |
| {AddressRange(0x1000, 0x2000), AddressRange(0x3000, 0x3001)})); |
| |
| // There are two inner blocks, one covers partially the first range, the |
| // other covers exactly the second range. |
| auto first_child = fxl::MakeRefCounted<CodeBlock>(Symbol::kTagLexicalBlock); |
| first_child->set_code_ranges(AddressRanges(AddressRange(0x1000, 0x2000))); |
| |
| auto second_child = fxl::MakeRefCounted<CodeBlock>(Symbol::kTagLexicalBlock); |
| second_child->set_code_ranges(AddressRanges(AddressRange(0x3000, 0x3001))); |
| |
| // Append the child ranges. |
| std::vector<LazySymbol> outer_inner; |
| outer_inner.emplace_back(first_child); |
| outer_inner.emplace_back(second_child); |
| outer->set_inner_blocks(outer_inner); |
| |
| // The first child has yet another child. |
| auto child_child = fxl::MakeRefCounted<CodeBlock>(Symbol::kTagLexicalBlock); |
| child_child->set_code_ranges(AddressRanges(AddressRange(0x1000, 0x1100))); |
| std::vector<LazySymbol> inner_inner; |
| inner_inner.emplace_back(child_child); |
| first_child->set_inner_blocks(inner_inner); |
| |
| // The second child has an inner child with no defined range. |
| auto child_child2 = fxl::MakeRefCounted<CodeBlock>(Symbol::kTagLexicalBlock); |
| std::vector<LazySymbol> inner_inner2; |
| inner_inner2.emplace_back(child_child2); |
| second_child->set_inner_blocks(inner_inner2); |
| |
| SymbolContext context = SymbolContext::ForRelativeAddresses(); |
| |
| // Querying for something out-of-range. |
| EXPECT_EQ(nullptr, outer->GetMostSpecificChild(context, 0x1)); |
| |
| // Something in the first level of children but not in the second. |
| EXPECT_EQ(first_child.get(), outer->GetMostSpecificChild(context, 0x1200)); |
| |
| // Lowest level of child. |
| EXPECT_EQ(child_child.get(), outer->GetMostSpecificChild(context, 0x1000)); |
| EXPECT_EQ(child_child2.get(), outer->GetMostSpecificChild(context, 0x3000)); |
| } |
| |
| } // namespace zxdb |