diff options
Diffstat (limited to 'src/common/linux')
-rw-r--r-- | src/common/linux/dump_symbols.cc | 36 | ||||
-rw-r--r-- | src/common/linux/dwarf_cfi_to_module.cc | 10 | ||||
-rw-r--r-- | src/common/linux/dwarf_cfi_to_module_unittest.cc | 14 |
3 files changed, 37 insertions, 23 deletions
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 79d7ad36..3df31372 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -46,6 +46,7 @@ #include <cstring> #include <string> +#include "common/dwarf/bytereader-inl.h" #include "common/dwarf/dwarf2diehandler.h" #include "common/linux/dump_stabs.h" #include "common/linux/dump_symbols.h" @@ -278,6 +279,9 @@ static bool LoadDwarfCFI(const string &dwarf_filename, const ElfW(Ehdr) *elf_header, const char *section_name, const ElfW(Shdr) *section, + bool eh_frame, + const ElfW(Shdr) *got_section, + const ElfW(Shdr) *text_section, Module *module) { // Find the appropriate set of register names for this file's // architecture. @@ -321,11 +325,19 @@ static bool LoadDwarfCFI(const string &dwarf_filename, dwarf_filename.c_str(), elf_header->e_ident[EI_CLASS]); return false; } + // Provide the base addresses for .eh_frame encoded pointers, if + // possible. + byte_reader.SetCFIDataBase(section->sh_addr, cfi); + if (got_section) + byte_reader.SetDataBase(got_section->sh_addr); + if (text_section) + byte_reader.SetTextBase(got_section->sh_addr); dwarf2reader::CallFrameInfo::Reporter dwarf_reporter(dwarf_filename, section_name); - dwarf2reader::CallFrameInfo parser(cfi, cfi_size, &byte_reader, - &handler, &dwarf_reporter); + dwarf2reader::CallFrameInfo parser(cfi, cfi_size, + &byte_reader, &handler, &dwarf_reporter, + eh_frame); parser.Start(); return true; } @@ -379,7 +391,25 @@ static bool LoadSymbols(const std::string &obj_file, ElfW(Ehdr) *elf_header, // information, the other debugging information could be perfectly // useful. LoadDwarfCFI(obj_file, elf_header, ".debug_frame", - dwarf_cfi_section, module); + dwarf_cfi_section, false, 0, 0, module); + } + + // Linux C++ exception handling information can also provide + // unwinding data. + const ElfW(Shdr) *eh_frame_section = + FindSectionByName(".eh_frame", sections, section_names, + elf_header->e_shnum); + if (eh_frame_section) { + // Pointers in .eh_frame data may be relative to the base addresses of + // certain sections. Provide those sections if present. + const ElfW(Shdr) *got_section = + FindSectionByName(".got", sections, section_names, elf_header->e_shnum); + const ElfW(Shdr) *text_section = + FindSectionByName(".text", sections, section_names, + elf_header->e_shnum); + // As above, ignore the return value of this function. + LoadDwarfCFI(obj_file, elf_header, ".eh_frame", + eh_frame_section, true, got_section, text_section, module); } if (!found_debug_info_section) { diff --git a/src/common/linux/dwarf_cfi_to_module.cc b/src/common/linux/dwarf_cfi_to_module.cc index d7946a0e..603acc0e 100644 --- a/src/common/linux/dwarf_cfi_to_module.cc +++ b/src/common/linux/dwarf_cfi_to_module.cc @@ -46,12 +46,10 @@ bool DwarfCFIToModule::Entry(size_t offset, uint64 address, uint64 length, uint8 version, const string &augmentation, unsigned return_address) { assert(!entry_); - // The latest CFI format version we understand is version 3. - if (version > 3) - return false; - // We only handle non-augmented DWARF unwinding data at the moment. - if (!augmentation.empty()) - return false; + + // If dwarf2reader::CallFrameInfo can handle this version and + // augmentation, then we should be okay with that, so there's no + // need to check them here. // Get ready to collect entries. entry_ = new Module::StackFrameEntry; diff --git a/src/common/linux/dwarf_cfi_to_module_unittest.cc b/src/common/linux/dwarf_cfi_to_module_unittest.cc index de769393..d7b08aef 100644 --- a/src/common/linux/dwarf_cfi_to_module_unittest.cc +++ b/src/common/linux/dwarf_cfi_to_module_unittest.cc @@ -78,20 +78,6 @@ struct DwarfCFIToModuleFixture { class Entry: public DwarfCFIToModuleFixture, public Test { }; -TEST_F(Entry, IgnoreVersion) { - ASSERT_FALSE(handler.Entry(0xf120e638, 0x2851bc1f7a181d6dULL, - 0x40589a48d66e5a88ULL, 4, "", 0x1ad80491)); - module.GetStackFrameEntries(&entries); - EXPECT_EQ(0U, entries.size()); -} - -TEST_F(Entry, IgnoreAugmentation) { - ASSERT_FALSE(handler.Entry(0x3f9d228a, 0xcf9a94bb805cf5a4ULL, - 0xe6c41bf958d4c171ULL, 3, "snazzy", 0x444a14f3)); - module.GetStackFrameEntries(&entries); - EXPECT_EQ(0U, entries.size()); -} - TEST_F(Entry, Accept) { ASSERT_TRUE(handler.Entry(0x3b8961b8, 0xa21069698096fc98ULL, 0xb440ce248169c8d6ULL, 3, "", 0xea93c106)); |