aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux/dump_symbols.cc
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-03-16 16:37:50 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-03-16 16:37:50 +0000
commita76aaa1442d765410da36d743ef92748ea1b815e (patch)
tree885e4efe8329d3362869680e0e6156fbb9ff0d65 /src/common/linux/dump_symbols.cc
parentBreakpad DWARF parser: Add support for parsing .eh_frame encoded pointers. (diff)
downloadbreakpad-a76aaa1442d765410da36d743ef92748ea1b815e.tar.xz
Breakpad Linux dumper: Parse the .eh_frame section.
Extend google_breakpad::CFISection with the ability to produce .eh_frame data. Entry headers have a different format, and pointers can be encoded in new and fascinating ways. Extend dwarf2reader::CallFrameInfo to be able to parse either DWARF CFI or .eh_frame data, as determined by an argument to the constructor. Cope with variations in header formats, encoded pointers, and additional data in 'z' augmentation data blocks. Extend the unit tests appropriately. Extend dump_syms to look for a .eh_frame section, and if it is present, find the necessary base addresess and parse its contents. There's no need for DwarfCFIToModule to check the version numbers; if CallFrameInfo can parse it, DwarfCFIToModule should be able to handle it. Adjust tests accordingly. a=jimblandy, r=nealsid git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@552 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/linux/dump_symbols.cc')
-rw-r--r--src/common/linux/dump_symbols.cc36
1 files changed, 33 insertions, 3 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) {