aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linux')
-rw-r--r--src/common/linux/dump_symbols.cc36
-rw-r--r--src/common/linux/dwarf_cfi_to_module.cc10
-rw-r--r--src/common/linux/dwarf_cfi_to_module_unittest.cc14
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));