Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2418,7 +2418,7 @@ .emplace(sect_name.GetCString(), module_section_list->FindSectionByName(sect_name)) .first; - if (section_it->second && section_it->second->GetFileSize()) + if (section_it->second) symbol_section_sp = section_it->second; } Index: lldb/trunk/unittests/ObjectFile/ELF/CMakeLists.txt =================================================================== --- lldb/trunk/unittests/ObjectFile/ELF/CMakeLists.txt +++ lldb/trunk/unittests/ObjectFile/ELF/CMakeLists.txt @@ -1,7 +1,17 @@ add_lldb_unittest(ObjectFileELFTests TestELFHeader.cpp + TestObjectFileELF.cpp LINK_LIBS lldbPluginObjectFileELF + lldbPluginSymbolVendorELF lldbCore ) + +add_dependencies(ObjectFileELFTests yaml2obj) +add_definitions(-DYAML2OBJ="$") + +set(test_inputs + sections-resolve-consistently.yaml + ) +add_unittest_inputs(ObjectFileELFTests "${test_inputs}") Index: lldb/trunk/unittests/ObjectFile/ELF/Inputs/sections-resolve-consistently.yaml =================================================================== --- lldb/trunk/unittests/ObjectFile/ELF/Inputs/sections-resolve-consistently.yaml +++ lldb/trunk/unittests/ObjectFile/ELF/Inputs/sections-resolve-consistently.yaml @@ -0,0 +1,50 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x0000000000400180 +Sections: + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x0000000000400158 + AddressAlign: 0x0000000000000004 + Content: 040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B6 + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000400180 + AddressAlign: 0x0000000000000010 + Content: 554889E58B042500106000890425041060005DC3 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000601000 + AddressAlign: 0x0000000000000004 + Content: 2F000000 + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000601004 + AddressAlign: 0x0000000000000004 + Size: 0x0000000000000004 +Symbols: + Global: + - Name: Y + Type: STT_OBJECT + Section: .data + Value: 0x0000000000601000 + Size: 0x0000000000000004 + - Name: _start + Type: STT_FUNC + Section: .text + Value: 0x0000000000400180 + Size: 0x0000000000000014 + - Name: X + Type: STT_OBJECT + Section: .bss + Value: 0x0000000000601004 + Size: 0x0000000000000004 +... Index: lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp =================================================================== --- lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ lldb/trunk/unittests/ObjectFile/ELF/TestObjectFileELF.cpp @@ -0,0 +1,105 @@ +//===-- TestObjectFileELF.cpp -----------------------------------*- C++ -*-===// +// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/Section.h" +#include "lldb/Host/HostInfo.h" +#include "llvm/Support/FileUtilities.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" +#include "gtest/gtest.h" + +#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h" + +extern const char *TestMainArgv0; + +using namespace lldb_private; +using namespace lldb; + +class ObjectFileELFTest : public testing::Test { +public: + void SetUp() override { + HostInfo::Initialize(); + ObjectFileELF::Initialize(); + SymbolVendorELF::Initialize(); + + m_inputs_folder = llvm::sys::path::parent_path(TestMainArgv0); + llvm::sys::path::append(m_inputs_folder, "Inputs"); + llvm::sys::fs::make_absolute(m_inputs_folder); + } + + void TearDown() override { + SymbolVendorELF::Terminate(); + ObjectFileELF::Terminate(); + HostInfo::Terminate(); + } + +protected: + llvm::SmallString<128> m_inputs_folder; +}; + +#define ASSERT_NO_ERROR(x) \ + if (std::error_code ASSERT_NO_ERROR_ec = x) { \ + llvm::SmallString<128> MessageStorage; \ + llvm::raw_svector_ostream Message(MessageStorage); \ + Message << #x ": did not return errc::success.\n" \ + << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \ + << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \ + GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \ + } else { \ + } + +TEST_F(ObjectFileELFTest, SectionsResolveConsistently) { + llvm::SmallString<128> yaml = m_inputs_folder; + llvm::sys::path::append(yaml, "sections-resolve-consistently.yaml"); + llvm::SmallString<128> obj = m_inputs_folder; + ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile( + "sections-resolve-consistently-%%%%%%", "obj", obj)); + + llvm::FileRemover remover(obj); + const char *args[] = {YAML2OBJ, yaml.c_str(), nullptr}; + llvm::StringRef obj_ref = obj; + const llvm::StringRef *redirects[] = {nullptr, &obj_ref, nullptr}; + ASSERT_EQ(0, llvm::sys::ExecuteAndWait(YAML2OBJ, args, nullptr, redirects)); + uint64_t size; + ASSERT_NO_ERROR(llvm::sys::fs::file_size(obj, size)); + ASSERT_GT(size, 0u); + + ModuleSpec spec{FileSpec(obj, false)}; + spec.GetSymbolFileSpec().SetFile(obj, false); + auto module_sp = std::make_shared(spec); + SectionList *list = module_sp->GetSectionList(); + ASSERT_NE(nullptr, list); + + auto bss_sp = list->FindSectionByName(ConstString(".bss")); + ASSERT_NE(nullptr, bss_sp); + auto data_sp = list->FindSectionByName(ConstString(".data")); + ASSERT_NE(nullptr, data_sp); + auto text_sp = list->FindSectionByName(ConstString(".text")); + ASSERT_NE(nullptr, text_sp); + + const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"), + eSymbolTypeAny); + ASSERT_NE(nullptr, X); + EXPECT_EQ(bss_sp, X->GetAddress().GetSection()); + + const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"), + eSymbolTypeAny); + ASSERT_NE(nullptr, Y); + EXPECT_EQ(data_sp, Y->GetAddress().GetSection()); + + const Symbol *start = module_sp->FindFirstSymbolWithNameAndType( + ConstString("_start"), eSymbolTypeAny); + ASSERT_NE(nullptr, start); + EXPECT_EQ(text_sp, start->GetAddress().GetSection()); +}