// 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 "src/developer/debug/zxdb/symbols/module_symbols_impl.h"

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <gtest/gtest.h>

#include "src/developer/debug/zxdb/common/string_util.h"
#include "src/developer/debug/zxdb/symbols/compile_unit.h"
#include "src/developer/debug/zxdb/symbols/dwarf_binary_impl.h"
#include "src/developer/debug/zxdb/symbols/elf_symbol.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/input_location.h"
#include "src/developer/debug/zxdb/symbols/line_details.h"
#include "src/developer/debug/zxdb/symbols/resolve_options.h"
#include "src/developer/debug/zxdb/symbols/symbol_context.h"
#include "src/developer/debug/zxdb/symbols/test_symbol_module.h"
#include "src/developer/debug/zxdb/symbols/type.h"
#include "src/developer/debug/zxdb/symbols/variable.h"

namespace zxdb {

namespace {

class ScopedUnlink {
 public:
  explicit ScopedUnlink(const char* name) : name_(name) {}
  ~ScopedUnlink() { EXPECT_EQ(0, unlink(name_)); }

 private:
  const char* name_;
};

}  // namespace

// Trying to load a nonexistent file should error.
TEST(ModuleSymbols, NonExistantFile) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName() + "_NONEXISTANT", "");
  // Should fail to load.
  EXPECT_FALSE(setup.Init().ok());
}

// Trying to load a random file should error.
TEST(ModuleSymbols, BadFileType) {
  char temp_name[] = "/tmp/zxdb_symbol_test.txtXXXXXX";
  int fd = mkstemp(temp_name);
  ASSERT_LT(0, fd) << "Could not create temporary file: " << temp_name;

  // Just use the file name itself as the contents of the file.
  ScopedUnlink unlink(temp_name);
  EXPECT_LT(0, write(fd, temp_name, strlen(temp_name)));
  close(fd);

  // The load should fail.
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName() + "_NONEXISTANT", "");
  ASSERT_FALSE(setup.Init("", false).ok());
}

TEST(ModuleSymbols, GetMappedLength) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(), "");
  ASSERT_TRUE(setup.Init("/build_dir").ok());

  // The checked-in test .so's last PROGBITS segment record is:
  //
  //   [15] .got.plt          PROGBITS         0000000000002000  00002000
  //       0000000000000030  0000000000000000  WA       0     0     8
  //
  // So 0x3008 offset + 0x30 = 0x2030 ending offset. This will likely change if the checked-in
  // test .so is updated. Just verify the results with "readelf -S"
  EXPECT_EQ(0x2030u, setup.symbols()->GetMappedLength());
}

TEST(ModuleSymbols, Basic) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(), "");
  ASSERT_TRUE(setup.Init("/build_dir").ok());

  // Make a symbol context with some load address to ensure that the addresses round-trip properly.
  SymbolContext symbol_context(0x18000);

  // MyFunction() should have one implementation.
  std::vector<Location> addrs = setup.symbols()->ResolveInputLocation(
      symbol_context,
      InputLocation(Identifier(IdentifierComponent(TestSymbolModule::kMyFunctionName))));
  ASSERT_EQ(1u, addrs.size());

  // On one occasion Clang generated a symbol file that listed many functions in this file starting
  // at offset 0. This obviously causes problems and the test fails below with bafflingly incorrect
  // line numbers. The problem went away after forcing recompilation of that file. It might be an
  // intermittent Clang bug or some random corruption. If this assert hits, check the function start
  // addresses in the DWARF dump, there should be no functions starting at offset 0 in the file.
  ASSERT_NE(0u, addrs[0].address());

  // That address should resolve back to the function name (don't know the exact file path the
  // compiler generated so just check the name).
  auto locations =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[0].address()));
  ASSERT_EQ(1u, locations.size());
  EXPECT_TRUE(locations[0].is_symbolized());
  EXPECT_TRUE(StringEndsWith(locations[0].file_line().file(), "/zxdb_symbol_test.cc"));
  EXPECT_EQ(109, locations[0].file_line().line());
  EXPECT_EQ("/build_dir", locations[0].file_line().comp_dir());

  // The function symbol should have a compilation unit with a C-style language defined and the name
  // should contain the file.
  ASSERT_TRUE(locations[0].symbol());
  fxl::RefPtr<CompileUnit> unit = locations[0].symbol().Get()->GetCompileUnit();
  ASSERT_TRUE(unit);
  EXPECT_NE(std::string::npos, unit->name().find("zxdb_symbol_test.cc"));
  EXPECT_TRUE(DwarfLangIsCFamily(unit->language()));
}

// Tests that querying an address far from the last address in the module won't return anything.
TEST(ModuleSymbols, OffEnd) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(), "");
  ASSERT_TRUE(setup.Init("/build_dir").ok());

  constexpr uint64_t kLoadAddress = 0x100000;
  SymbolContext symbol_context(kLoadAddress);

  // Check an address far past the end of the test module.
  std::vector<Location> addrs = setup.symbols()->ResolveInputLocation(
      symbol_context, InputLocation(kLoadAddress + 0x1000000000));
  ASSERT_EQ(1u, addrs.size());

  // It should not have a matching symbol (the last ELF symbol in the module shouldn't match it
  // just because it's the previous thing).
  EXPECT_FALSE(addrs[0].has_symbols());
}

TEST(ModuleSymbols, LineDetailsForAddress) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(), "");
  ASSERT_TRUE(setup.Init("/build_dir").ok());

  // Make a symbol context with some load address to ensure that the addresses round-trip properly.
  SymbolContext symbol_context(0x18000);

  // Get the canonical file name to test.
  auto file_matches = setup.symbols()->FindFileMatches("line_lookup_symbol_test.cc");
  ASSERT_EQ(1u, file_matches.size());
  const std::string file_name = file_matches[0];

  // The file name should be canonical and lack any redundant "." or "..".
  EXPECT_EQ("../../src/developer/debug/zxdb/symbols/test_data/line_lookup_symbol_test.cc",
            file_name);

  // Get address of line 28 which is a normal line with code on both sides.
  int const kLineToQuery = 28;
  ResolveOptions options;
  options.symbolize = false;
  std::vector<Location> addrs;
  addrs = setup.symbols()->ResolveInputLocation(
      symbol_context, InputLocation(FileLine(file_name, kLineToQuery)), options);
  ASSERT_LE(1u, addrs.size());
  auto locations =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[0].address()));
  ASSERT_EQ(1u, locations.size());
  EXPECT_EQ(kLineToQuery, locations[0].file_line().line());
  EXPECT_EQ(file_name, locations[0].file_line().file());
  EXPECT_EQ("/build_dir", locations[0].file_line().comp_dir());

  // Lookup the line info. Normally we expect one line table entry for this but don't want to assume
  // that since the compiler could emit multiple entries for it.
  LineDetails line_details =
      setup.symbols()->LineDetailsForAddress(symbol_context, addrs[0].address(), false);
  EXPECT_EQ(file_name, line_details.file_line().file());
  EXPECT_EQ(kLineToQuery, line_details.file_line().line());
  EXPECT_EQ("/build_dir", line_details.file_line().comp_dir());
  ASSERT_FALSE(line_details.entries().empty());
  uint64_t begin_range = line_details.entries().front().range.begin();
  uint64_t end_range = line_details.entries().back().range.end();
  EXPECT_LT(begin_range, end_range);

  // The address before the beginning of the range should be the previous line.
  LineDetails prev_details =
      setup.symbols()->LineDetailsForAddress(symbol_context, begin_range - 1, false);
  EXPECT_EQ(kLineToQuery - 1, prev_details.file_line().line());
  EXPECT_EQ(file_name, prev_details.file_line().file());
  EXPECT_EQ("/build_dir", prev_details.file_line().comp_dir());
  ASSERT_FALSE(prev_details.entries().empty());
  EXPECT_EQ(begin_range, prev_details.entries().back().range.end());

  // The end of the range (which is non-inclusive) should be the next line.
  LineDetails next_details =
      setup.symbols()->LineDetailsForAddress(symbol_context, end_range, false);
  EXPECT_EQ(kLineToQuery + 1, next_details.file_line().line());
  EXPECT_EQ(file_name, next_details.file_line().file());
  EXPECT_EQ("/build_dir", next_details.file_line().comp_dir());
  ASSERT_FALSE(next_details.entries().empty());
  EXPECT_EQ(end_range, next_details.entries().front().range.begin());
}

TEST(ModuleSymbols, ResolveLineInputLocation) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(), "");
  ASSERT_TRUE(setup.Init("/build_dir").ok());

  // Make a symbol context with some load address to ensure that the addresses round-trip properly.
  SymbolContext symbol_context(0x18000);

  // Get the canonical file name to test.
  auto file_matches = setup.symbols()->FindFileMatches("line_lookup_symbol_test.cc");
  ASSERT_EQ(1u, file_matches.size());
  const std::string file_name = file_matches[0];

  // Basic one, look for line 27 which is a normal statement.
  ResolveOptions options;
  options.symbolize = false;
  std::vector<Location> addrs;
  addrs = setup.symbols()->ResolveInputLocation(symbol_context,
                                                InputLocation(FileLine(file_name, 27)), options);
  ASSERT_LE(1u, addrs.size());
  auto locations =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[0].address()));
  ASSERT_EQ(1u, locations.size());
  EXPECT_EQ(27, locations[0].file_line().line());
  EXPECT_EQ(file_name, locations[0].file_line().file());
  EXPECT_EQ("/build_dir", locations[0].file_line().comp_dir());

  // Absolute path should be supported.
  locations = setup.symbols()->ResolveInputLocation(
      symbol_context, InputLocation(FileLine("/build_dir/" + file_name, 27)), options);
  ASSERT_EQ(1u, locations.size());
  EXPECT_EQ(addrs[0].address(), locations[0].address());

  // Line 26 is a comment line, looking it up should get the following line.
  addrs = setup.symbols()->ResolveInputLocation(symbol_context,
                                                InputLocation(FileLine(file_name, 26)), options);
  ASSERT_LE(1u, addrs.size());
  locations =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[0].address()));
  ASSERT_EQ(1u, locations.size());
  EXPECT_EQ(27, locations[0].file_line().line());
  EXPECT_EQ(file_name, locations[0].file_line().file());
  EXPECT_EQ("/build_dir", locations[0].file_line().comp_dir());

  // Line 15 is the beginning of the templatized function. There should be two matches since its
  // instantiated twice.
  addrs = setup.symbols()->ResolveInputLocation(symbol_context,
                                                InputLocation(FileLine(file_name, 15)), options);
  ASSERT_EQ(2u, addrs.size());
  locations =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[0].address()));
  ASSERT_EQ(1u, locations.size());
  EXPECT_EQ(15, locations[0].file_line().line());
  EXPECT_EQ(file_name, locations[0].file_line().file());
  EXPECT_EQ("/build_dir", locations[0].file_line().comp_dir());
  locations =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[1].address()));
  ASSERT_EQ(1u, locations.size());
  EXPECT_EQ(15, locations[0].file_line().line());
  EXPECT_EQ(file_name, locations[0].file_line().file());
  EXPECT_EQ("/build_dir", locations[0].file_line().comp_dir());

  // Line 17 is only present in one of the two template instantiations.  We should only find it once
  // (see note below about case #2).
  addrs = setup.symbols()->ResolveInputLocation(symbol_context,
                                                InputLocation(FileLine(file_name, 17)), options);
  ASSERT_TRUE(addrs.size() == 1u || addrs.size() == 2u);
  locations =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[0].address()));
  ASSERT_EQ(1u, locations.size());
  EXPECT_EQ(17, locations[0].file_line().line());
  EXPECT_EQ("/build_dir", locations[0].file_line().comp_dir());
  if (addrs.size() == 2u) {
    // MSVC in debug mode will emit the full code in both instantiations of the template which is
    // valid. To be more robust this test allows that form even though Clang doesn't do this. The
    // important thing is that looking up line 17 never gives us line 19 (which is the other
    // template instantiation).
    locations =
        setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(addrs[1].address()));
    EXPECT_EQ(17, locations[0].file_line().line());
  }
}

TEST(ModuleSymbols, ResolveGlobalVariable) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(), "");
  ASSERT_TRUE(setup.Init().ok());

  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  ResolveOptions options;
  options.symbolize = true;
  std::vector<Location> addrs;

  // Look up "kGlobal" which should be a variable of type "int" at some nonzero location.
  Identifier global_name = TestSymbolModule::SplitName(TestSymbolModule::kGlobalName);
  addrs =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(global_name), options);
  ASSERT_LE(1u, addrs.size());
  EXPECT_TRUE(addrs[0].symbol());
  const Variable* var = addrs[0].symbol().Get()->As<Variable>();
  ASSERT_TRUE(var);
  EXPECT_EQ(TestSymbolModule::kGlobalName, var->GetFullName());
  const Type* var_type = var->type().Get()->As<Type>();
  ASSERT_TRUE(var_type);
  EXPECT_EQ("int", var_type->GetFullName());

  // This variable doesn't have an address because in the current checked-in file, it's expressed as
  // a DWARF expression that the SymbolModule doesn't evaluate. In a normal expression, the
  // symbol match will trigger the necessary logic in the expression evaluation system. This
  // expression might change and that's OK.
  EXPECT_EQ(0u, addrs[0].address());

  // Look up the class static.
  addrs = setup.symbols()->ResolveInputLocation(
      symbol_context,
      InputLocation(TestSymbolModule::SplitName(TestSymbolModule::kClassStaticName)), options);
  ASSERT_LE(1u, addrs.size());
  EXPECT_TRUE(addrs[0].symbol());
  var = addrs[0].symbol().Get()->As<Variable>();
  ASSERT_TRUE(var);
  EXPECT_EQ(TestSymbolModule::kClassStaticName, var->GetFullName());
  var_type = var->type().Get()->As<Type>();
  ASSERT_TRUE(var_type);
  EXPECT_EQ("int", var_type->GetFullName());

  // As above, there's no address for the current symbol file.
  EXPECT_EQ(0u, addrs[0].address());

  // Annotate the global variable as a register. This lookup should fail since registers can't be
  // looked up in the symbols (this tests that ModuleSymbolsImpl filters out bad special component
  // types).
  Identifier register_name;
  register_name.AppendComponent(
      IdentifierComponent(SpecialIdentifier::kRegister, TestSymbolModule::kGlobalName));
  addrs =
      setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(register_name), options);
  ASSERT_TRUE(addrs.empty());
}

TEST(ModuleSymbols, ResolvePLTEntry) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(),
                         TestSymbolModule::GetStrippedCheckedInTestFileName());
  ASSERT_TRUE(setup.Init().ok());

  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  ResolveOptions options;
  options.symbolize = true;

  // Name->PLT symbol.
  auto result = setup.symbols()->ResolveInputLocation(
      symbol_context,
      InputLocation(Identifier(
          IdentifierComponent(SpecialIdentifier::kPlt, TestSymbolModule::kPltFunctionName))),
      options);

  ASSERT_EQ(1u, result.size());
  EXPECT_TRUE(result[0].is_valid());
  EXPECT_EQ(TestSymbolModule::kPltFunctionOffset, result[0].address());

  const ElfSymbol* elf_symbol = result[0].symbol().Get()->As<ElfSymbol>();
  ASSERT_TRUE(elf_symbol);
  EXPECT_EQ(ElfSymbolType::kPlt, elf_symbol->elf_type());
  EXPECT_EQ(TestSymbolModule::kPltFunctionName, elf_symbol->linkage_name());

  // Now look up the address and expect to get the symbol back.
  result = setup.symbols()->ResolveInputLocation(
      symbol_context, InputLocation(TestSymbolModule::kPltFunctionOffset), options);
  ASSERT_EQ(1u, result.size());

  elf_symbol = result[0].symbol().Get()->As<ElfSymbol>();
  ASSERT_TRUE(elf_symbol);
  EXPECT_EQ(ElfSymbolType::kPlt, elf_symbol->elf_type());
  EXPECT_EQ(TestSymbolModule::kPltFunctionName, elf_symbol->linkage_name());
}

TEST(ModuleSymbols, ResolveMainFunction) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(),
                         TestSymbolModule::GetStrippedCheckedInTestFileName());
  ASSERT_TRUE(setup.Init().ok());

  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  // The sample module is a shared library with no main function, so there should be nothing found.
  InputLocation input_loc((Identifier(IdentifierComponent(SpecialIdentifier::kMain))));
  ResolveOptions options;
  auto addrs = setup.symbols()->ResolveInputLocation(symbol_context, input_loc, options);
  EXPECT_TRUE(addrs.empty());

  // Inject a function named "main" (but not marked in the symbols as the official main function).
  // This is kind of a hack. The ModuleSymbolsImpl is using a real symbol file and need to be able
  // to generate the function symbol from the SymbolRef for this call to succeed. So we can't just
  // inject a fake SymbolRef. Instead, redirect "main" in the index to an existing function
  // ("MyFunction").
  auto my_function_matches = setup.symbols()->index_.FindExact(
      Identifier(IdentifierComponent(TestSymbolModule::kMyFunctionName)));
  ASSERT_EQ(1u, my_function_matches.size());
  auto main_node = setup.symbols()->index_.root().AddChild(IndexNode::Kind::kFunction, "main");
  main_node->AddDie(my_function_matches[0]);

  // Query for $main again. Since nothing is marked as the main function, the one named "main"
  // should be returned. Since we redirected the index above, this will actually be "MyFunction".
  addrs = setup.symbols()->ResolveInputLocation(symbol_context, input_loc, options);
  ASSERT_EQ(1u, addrs.size());
  EXPECT_EQ(TestSymbolModule::kMyFunctionName, addrs[0].symbol().Get()->GetFullName());

  // Now mark a different function as the official main one (kNamespaceFunctionName).
  auto anon_function_matches = setup.symbols()->index_.FindExact(
      TestSymbolModule::SplitName(TestSymbolModule::kNamespaceFunctionName));
  ASSERT_EQ(1u, anon_function_matches.size());
  setup.symbols()->index_.main_functions().push_back(anon_function_matches[0]);

  // Query again. Now that a function is explicitly marked as the main one,
  // only it should be returned.
  addrs = setup.symbols()->ResolveInputLocation(symbol_context, input_loc, options);
  ASSERT_EQ(1u, addrs.size());
  EXPECT_EQ(TestSymbolModule::kNamespaceFunctionName, addrs[0].symbol().Get()->GetFullName());
}

TEST(ModuleSymbols, SkipPrologue) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(),
                         TestSymbolModule::GetStrippedCheckedInTestFileName());
  ASSERT_TRUE(setup.Init().ok());

  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  InputLocation input_fn_loc((Identifier(IdentifierComponent(TestSymbolModule::kMyFunctionName))));

  // Query the function by name with no prologue skipping.
  ResolveOptions no_skip_options;
  no_skip_options.symbolize = true;
  no_skip_options.skip_function_prologue = false;
  auto no_skip_addrs =
      setup.symbols()->ResolveInputLocation(symbol_context, input_fn_loc, no_skip_options);
  ASSERT_EQ(1u, no_skip_addrs.size());
  EXPECT_EQ(TestSymbolModule::kMyFunctionAddress, no_skip_addrs[0].address());
  EXPECT_EQ(TestSymbolModule::kMyFunctionName,
            no_skip_addrs[0].symbol().Get()->As<Function>()->GetFullName());

  // Now with prologue skipping.
  ResolveOptions skip_options;
  skip_options.symbolize = true;
  skip_options.skip_function_prologue = true;
  auto skip_addrs =
      setup.symbols()->ResolveInputLocation(symbol_context, input_fn_loc, skip_options);
  ASSERT_EQ(1u, skip_addrs.size());
  EXPECT_EQ(no_skip_addrs[0].address() + TestSymbolModule::kMyFunctionPrologueSize,
            skip_addrs[0].address());
  EXPECT_EQ(TestSymbolModule::kMyFunctionName,
            skip_addrs[0].symbol().Get()->As<Function>()->GetFullName());

  // Query by line. No skipping.
  InputLocation input_line_loc(FileLine("zxdb_symbol_test.cc", TestSymbolModule::kMyFunctionLine));
  no_skip_addrs =
      setup.symbols()->ResolveInputLocation(symbol_context, input_line_loc, no_skip_options);
  ASSERT_EQ(1u, no_skip_addrs.size());
  EXPECT_EQ(TestSymbolModule::kMyFunctionAddress, no_skip_addrs[0].address());
  EXPECT_EQ(TestSymbolModule::kMyFunctionName,
            no_skip_addrs[0].symbol().Get()->As<Function>()->GetFullName());

  // With skipping.
  skip_addrs = setup.symbols()->ResolveInputLocation(symbol_context, input_line_loc, skip_options);
  ASSERT_EQ(1u, skip_addrs.size());
  EXPECT_EQ(TestSymbolModule::kMyFunctionAddress + TestSymbolModule::kMyFunctionPrologueSize,
            skip_addrs[0].address());
  EXPECT_EQ(TestSymbolModule::kMyFunctionName,
            skip_addrs[0].symbol().Get()->As<Function>()->GetFullName());

  // Query by address. No skipping.
  InputLocation input_addr_loc(TestSymbolModule::kMyFunctionAddress);
  no_skip_addrs =
      setup.symbols()->ResolveInputLocation(symbol_context, input_addr_loc, no_skip_options);
  ASSERT_EQ(1u, no_skip_addrs.size());
  EXPECT_EQ(TestSymbolModule::kMyFunctionAddress, no_skip_addrs[0].address());
  EXPECT_EQ(TestSymbolModule::kMyFunctionName,
            no_skip_addrs[0].symbol().Get()->As<Function>()->GetFullName());

  // With skipping.
  skip_addrs = setup.symbols()->ResolveInputLocation(symbol_context, input_addr_loc, skip_options);
  ASSERT_EQ(1u, skip_addrs.size());
  EXPECT_EQ(TestSymbolModule::kMyFunctionAddress + TestSymbolModule::kMyFunctionPrologueSize,
            skip_addrs[0].address());
  EXPECT_EQ(TestSymbolModule::kMyFunctionName,
            skip_addrs[0].symbol().Get()->As<Function>()->GetFullName());
}

TEST(ModuleSymbols, ElfSymbols) {
  TestSymbolModule setup(TestSymbolModule::GetCheckedInTestFileName(),
                         TestSymbolModule::GetStrippedCheckedInTestFileName());
  ASSERT_TRUE(setup.Init().ok());

  // Give it a non-relative context to make sure that things are relative-ized going in and out.
  SymbolContext symbol_context(0x1000000);

  // Virtual tables have ELF symbols but not DWARF symbols, so to test that we read the ELF symbols
  // properly, look one up.
  const char kVirtualDerivedVtableName[] = "_ZTV14VirtualDerived";
  const char kVirtualDerivedVtableUnmangledName[] = "vtable for VirtualDerived";
  Identifier vtable_identifier(
      IdentifierComponent(SpecialIdentifier::kElf, kVirtualDerivedVtableName));
  std::vector<Location> result = setup.symbols()->ResolveInputLocation(
      symbol_context, InputLocation(vtable_identifier), ResolveOptions());
  ASSERT_EQ(1u, result.size());

  // It should have found the ELF symbol.
  ASSERT_TRUE(result[0].symbol());
  auto elf_symbol = result[0].symbol().Get()->As<ElfSymbol>();
  ASSERT_TRUE(elf_symbol);
  EXPECT_EQ(kVirtualDerivedVtableName, elf_symbol->linkage_name());
  EXPECT_EQ(kVirtualDerivedVtableUnmangledName, elf_symbol->GetFullName());

  // The returned address should match the symbol info except for relative/absolute.
  uint64_t absolute_addr = result[0].address();
  EXPECT_EQ(absolute_addr, symbol_context.RelativeToAbsolute(elf_symbol->relative_address()));

  // Looking up by that address should give back the name.
  result = setup.symbols()->ResolveInputLocation(symbol_context, InputLocation(absolute_addr),
                                                 ResolveOptions());
  ASSERT_EQ(1u, result.size());

  // Symbols, names, and addresses should match as above.
  ASSERT_TRUE(result[0].symbol());
  elf_symbol = result[0].symbol().Get()->As<ElfSymbol>();
  ASSERT_TRUE(elf_symbol);
  EXPECT_EQ(kVirtualDerivedVtableName, elf_symbol->linkage_name());
  EXPECT_EQ(kVirtualDerivedVtableUnmangledName, elf_symbol->GetFullName());
  EXPECT_EQ(result[0].address(), symbol_context.RelativeToAbsolute(elf_symbol->relative_address()));
}

// Loads the stripped binary and ensures that exported symbols can still be found (these symbols
// will be present only in the ELF ".dynsym" table).
TEST(ModuleSymbols, StrippedElfSymbols) {
  // Supply only the stripped binary name.
  TestSymbolModule setup(TestSymbolModule::GetStrippedCheckedInTestFileName(),
                         TestSymbolModule::GetStrippedCheckedInTestFileName());
  ASSERT_TRUE(setup.Init().ok());

  // Give it a non-relative context to make sure that things are relative-ized going in and out.
  SymbolContext symbol_context(0x1000000);

  const char kSymName[] = "_Z9GetIntPtrv";
  std::vector<Location> result = setup.symbols()->ResolveInputLocation(
      symbol_context,
      InputLocation(Identifier(IdentifierComponent(SpecialIdentifier::kElf, kSymName))),
      ResolveOptions());
  ASSERT_EQ(1u, result.size());

  // It should have found the ELF symbol.
  ASSERT_TRUE(result[0].symbol());
  auto elf_symbol = result[0].symbol().Get()->As<ElfSymbol>();
  ASSERT_TRUE(elf_symbol);
  EXPECT_EQ(kSymName, elf_symbol->linkage_name());
  EXPECT_EQ("GetIntPtr()", elf_symbol->GetFullName());
}

}  // namespace zxdb
