aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux/dump_symbols.cc
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-05-05 17:09:20 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-05-05 17:09:20 +0000
commitb0ec96cee2ab186c9e7e480d03751588f0640bf1 (patch)
tree40fc8df4fbbf5542c27cad2919c025fe3881457f /src/common/linux/dump_symbols.cc
parentBreakpad symbol dumper: Define the ByteBuffer and ByteCursor classes. (diff)
downloadbreakpad-b0ec96cee2ab186c9e7e480d03751588f0640bf1.tar.xz
Breakpad Linux dumper: Make StabsReader independent of endianness and word size.
StabsReader simply applies a reinterpret_cast to treat the stab entry data as an array of 'struct nlist' structures, making the parser specific on the host endianness, word size, and alignment rules. On Mac OS X, a single fat binary file may contain object files of different ABIs, of which the user chooses one at run time. This patch changes the parser to read the data using the google_breakpad:: ByteCursor class, which can handle different endiannesses and word sizes. The StabsReader constructor now takes arguments indicating the endianness of the data and the size of each entry's value field. The patch changes src/common/linux/dump_symbols.cc to pass the new argument. This patch changes the StabsReader unit tests to use the google_breakpad:: TestAssembler classes to generate test data, rather than reading it from a file. This makes it easy to generate test data in various endiannesses and word sizes. It also adds tests for the new parser behaviors. a=jimblandy, r=thestig git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@583 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/linux/dump_symbols.cc')
-rw-r--r--src/common/linux/dump_symbols.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index c3648e9a..da4263f7 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -123,17 +123,31 @@ static const ElfW(Shdr) *FindSectionByName(const char *name,
return NULL;
}
-static bool LoadStabs(const ElfW(Shdr) *stab_section,
+static bool LoadStabs(const ElfW(Ehdr) *elf_header,
+ const ElfW(Shdr) *stab_section,
const ElfW(Shdr) *stabstr_section,
Module *module) {
+ // Figure out what endianness this file is.
+ bool big_endian;
+ if (elf_header->e_ident[EI_DATA] == ELFDATA2LSB)
+ big_endian = false;
+ else if (elf_header->e_ident[EI_DATA] == ELFDATA2MSB)
+ big_endian = true;
+ else {
+ fprintf(stderr, "bad data encoding in ELF header: %d\n",
+ elf_header->e_ident[EI_DATA]);
+ return false;
+ }
// A callback object to handle data from the STABS reader.
DumpStabsHandler handler(module);
// Find the addresses of the STABS data, and create a STABS reader object.
+ // On Linux, STABS entries always have 32-bit values, regardless of the
+ // address size of the architecture whose code they're describing.
uint8_t *stabs = reinterpret_cast<uint8_t *>(stab_section->sh_offset);
uint8_t *stabstr = reinterpret_cast<uint8_t *>(stabstr_section->sh_offset);
google_breakpad::StabsReader reader(stabs, stab_section->sh_size,
stabstr, stabstr_section->sh_size,
- &handler);
+ big_endian, 4, &handler);
// Read the STABS data, and do post-processing.
if (!reader.Process())
return false;
@@ -330,7 +344,7 @@ static bool LoadSymbols(const std::string &obj_file, ElfW(Ehdr) *elf_header,
const ElfW(Shdr) *stabstr_section = stab_section->sh_link + sections;
if (stabstr_section) {
found_debug_info_section = true;
- if (!LoadStabs(stab_section, stabstr_section, module))
+ if (!LoadStabs(elf_header, stab_section, stabstr_section, module))
fprintf(stderr, "%s: \".stab\" section found, but failed to load STABS"
" debugging information\n", obj_file.c_str());
}