blob: bdc7bd097a119a725834913ce7ddd7daf01276b3 [file] [log] [blame]
// Copyright 2019 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 "src/developer/debug/zxdb/client/substatement.h"
#include "gtest/gtest.h"
#include "src/developer/debug/zxdb/client/arch_info.h"
#include "src/developer/debug/zxdb/client/memory_dump.h"
#include "src/developer/debug/zxdb/symbols/mock_module_symbols.h"
#include "src/developer/debug/zxdb/symbols/process_symbols_test_setup.h"
namespace zxdb {
TEST(SubstatementTest, GetSubstatementCallsForMemory) {
ArchInfo arch;
Err err = arch.Init(debug_ipc::Arch::kX64);
ASSERT_FALSE(err.has_error()) << err.msg();
ProcessSymbolsTestSetup setup;
setup.InjectMockModule();
SymbolContext symbol_context(ProcessSymbolsTestSetup::kDefaultLoadAddress);
constexpr TargetPointer kStartAddr = ProcessSymbolsTestSetup::kDefaultLoadAddress;
debug_ipc::MemoryBlock dump;
dump.address = kStartAddr;
dump.valid = true;
dump.data = std::vector<uint8_t>{
0xbf, 0xe0, 0xe5, 0x28, 0x00, // mov edi, 0x28e5e0
0x48, 0x89, 0xde, // mov rsi, rbx [inline routine]
0x48, 0x8d, 0x7c, 0x24, 0x0c, // lea rdi, [rsp + 0xc] [code block]
0xe8, 0xce, 0x00, 0x00, 0x00 // call +0xce (relative to next instruction).
};
dump.size = dump.data.size();
AddressRange abs_extent(kStartAddr, kStartAddr + dump.size);
// Containing function the current location is inside.
auto containing_function = fxl::MakeRefCounted<Function>(DwarfTag::kSubprogram);
containing_function->set_code_ranges(
symbol_context.AbsoluteToRelative(AddressRanges({abs_extent})));
// Inline function that counts as a call.
auto inline_function = fxl::MakeRefCounted<Function>(DwarfTag::kInlinedSubroutine);
constexpr TargetPointer kInlineStart = kStartAddr + 5;
inline_function->set_code_ranges(symbol_context.AbsoluteToRelative(
AddressRanges(AddressRange(kInlineStart, kInlineStart + 3))));
// Lexical scope. This should not count toward the inline calls.
auto block = fxl::MakeRefCounted<CodeBlock>(DwarfTag::kLexicalBlock);
constexpr TargetPointer kBlockStart = kStartAddr + 8;
block->set_code_ranges(
AddressRanges(symbol_context.AbsoluteToRelative(AddressRange(kBlockStart, kBlockStart + 5))));
containing_function->set_inner_blocks({LazySymbol(inline_function), LazySymbol(block)});
Location loc(kStartAddr, FileLine("file.cc", 21), 0, symbol_context, containing_function);
std::vector<SubstatementCall> result =
GetSubstatementCallsForMemory(&arch, &setup.process(), loc, abs_extent, MemoryDump({dump}));
ASSERT_EQ(2u, result.size());
EXPECT_EQ(kStartAddr + 5, result[0].call_addr);
EXPECT_EQ(kStartAddr + 5, result[0].call_dest);
EXPECT_EQ(inline_function.get(), result[0].inline_call.get());
EXPECT_EQ(kStartAddr + 0xd, result[1].call_addr);
EXPECT_EQ(kStartAddr + 0xe0, result[1].call_dest);
EXPECT_FALSE(result[1].inline_call);
}
} // namespace zxdb