Fix mac dump_syms after r1163.

R=mark@chromium.org

Review URL: https://breakpad.appspot.com/592002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1175 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
thestig@chromium.org 2013-05-08 17:41:12 +00:00
parent df6f45b04b
commit 7304a2c187
3 changed files with 40 additions and 18 deletions

View file

@ -53,8 +53,9 @@ namespace google_breakpad {
class DumpSymbols { class DumpSymbols {
public: public:
explicit DumpSymbols(SymbolData symbol_data) DumpSymbols(SymbolData symbol_data, bool handle_inter_cu_refs)
: symbol_data_(symbol_data), : symbol_data_(symbol_data),
handle_inter_cu_refs_(handle_inter_cu_refs),
input_pathname_(), input_pathname_(),
object_filename_(), object_filename_(),
contents_(), contents_(),
@ -134,7 +135,8 @@ class DumpSymbols {
// on failure, report the problem and return false. // on failure, report the problem and return false.
bool ReadDwarf(google_breakpad::Module *module, bool ReadDwarf(google_breakpad::Module *module,
const mach_o::Reader &macho_reader, const mach_o::Reader &macho_reader,
const mach_o::SectionMap &dwarf_sections) const; const mach_o::SectionMap &dwarf_sections,
bool handle_inter_cu_refs) const;
// Read DWARF CFI or .eh_frame data from |section|, belonging to // Read DWARF CFI or .eh_frame data from |section|, belonging to
// |macho_reader|, and record it in |module|. If |eh_frame| is true, // |macho_reader|, and record it in |module|. If |eh_frame| is true,
@ -149,6 +151,9 @@ class DumpSymbols {
// The selection of what type of symbol data to read/write. // The selection of what type of symbol data to read/write.
const SymbolData symbol_data_; const SymbolData symbol_data_;
// Whether to handle references between compilation units.
const bool handle_inter_cu_refs_;
// The name of the file or bundle whose symbols this will dump. // The name of the file or bundle whose symbols this will dump.
// This is the path given to Read, for use in error messages. // This is the path given to Read, for use in error messages.
NSString *input_pathname_; NSString *input_pathname_;

View file

@ -253,7 +253,8 @@ class DumpSymbols::DumperLineToModule:
bool DumpSymbols::ReadDwarf(google_breakpad::Module *module, bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
const mach_o::Reader &macho_reader, const mach_o::Reader &macho_reader,
const mach_o::SectionMap &dwarf_sections) const { const mach_o::SectionMap &dwarf_sections,
bool handle_inter_cu_refs) const {
// Build a byte reader of the appropriate endianness. // Build a byte reader of the appropriate endianness.
ByteReader byte_reader(macho_reader.big_endian() ByteReader byte_reader(macho_reader.big_endian()
? dwarf2reader::ENDIANNESS_BIG ? dwarf2reader::ENDIANNESS_BIG
@ -261,19 +262,24 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
// Construct a context for this file. // Construct a context for this file.
DwarfCUToModule::FileContext file_context(selected_object_name_, DwarfCUToModule::FileContext file_context(selected_object_name_,
module); module,
handle_inter_cu_refs);
// Build a dwarf2reader::SectionMap from our mach_o::SectionMap. // Build a dwarf2reader::SectionMap from our mach_o::SectionMap.
for (mach_o::SectionMap::const_iterator it = dwarf_sections.begin(); for (mach_o::SectionMap::const_iterator it = dwarf_sections.begin();
it != dwarf_sections.end(); it++) { it != dwarf_sections.end(); ++it) {
file_context.section_map[it->first] = file_context.AddSectionToSectionMap(
make_pair(reinterpret_cast<const char *>(it->second.contents.start), it->first,
reinterpret_cast<const char *>(it->second.contents.start),
it->second.contents.Size()); it->second.contents.Size());
} }
// Find the __debug_info section. // Find the __debug_info section.
std::pair<const char *, uint64> debug_info_section dwarf2reader::SectionMap::const_iterator debug_info_entry =
= file_context.section_map["__debug_info"]; file_context.section_map().find(".debug_info");
assert(debug_info_entry != file_context.section_map().end());
const std::pair<const char*, uint64>& debug_info_section =
debug_info_entry->second;
// There had better be a __debug_info section! // There had better be a __debug_info section!
if (!debug_info_section.first) { if (!debug_info_section.first) {
fprintf(stderr, "%s: __DWARF segment of file has no __debug_info section\n", fprintf(stderr, "%s: __DWARF segment of file has no __debug_info section\n",
@ -295,7 +301,7 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
// Make a Dwarf2Handler that drives our DIEHandler. // Make a Dwarf2Handler that drives our DIEHandler.
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler); dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
// Make a DWARF parser for the compilation unit at OFFSET. // Make a DWARF parser for the compilation unit at OFFSET.
dwarf2reader::CompilationUnit dwarf_reader(file_context.section_map, dwarf2reader::CompilationUnit dwarf_reader(file_context.section_map(),
offset, offset,
&byte_reader, &byte_reader,
&die_dispatcher); &die_dispatcher);
@ -374,11 +380,13 @@ class DumpSymbols::LoadCommandDumper:
LoadCommandDumper(const DumpSymbols &dumper, LoadCommandDumper(const DumpSymbols &dumper,
google_breakpad::Module *module, google_breakpad::Module *module,
const mach_o::Reader &reader, const mach_o::Reader &reader,
SymbolData symbol_data) SymbolData symbol_data,
bool handle_inter_cu_refs)
: dumper_(dumper), : dumper_(dumper),
module_(module), module_(module),
reader_(reader), reader_(reader),
symbol_data_(symbol_data) { } symbol_data_(symbol_data),
handle_inter_cu_refs_(handle_inter_cu_refs) { }
bool SegmentCommand(const mach_o::Segment &segment); bool SegmentCommand(const mach_o::Segment &segment);
bool SymtabCommand(const ByteBuffer &entries, const ByteBuffer &strings); bool SymtabCommand(const ByteBuffer &entries, const ByteBuffer &strings);
@ -388,6 +396,7 @@ class DumpSymbols::LoadCommandDumper:
google_breakpad::Module *module_; // WEAK google_breakpad::Module *module_; // WEAK
const mach_o::Reader &reader_; const mach_o::Reader &reader_;
const SymbolData symbol_data_; const SymbolData symbol_data_;
const bool handle_inter_cu_refs_;
}; };
bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) { bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) {
@ -408,9 +417,11 @@ bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) {
if (segment.name == "__DWARF") { if (segment.name == "__DWARF") {
if (symbol_data_ != ONLY_CFI) { if (symbol_data_ != ONLY_CFI) {
if (!dumper_.ReadDwarf(module_, reader_, section_map)) if (!dumper_.ReadDwarf(module_, reader_, section_map,
handle_inter_cu_refs_)) {
return false; return false;
} }
}
if (symbol_data_ != NO_CFI) { if (symbol_data_ != NO_CFI) {
mach_o::SectionMap::const_iterator debug_frame mach_o::SectionMap::const_iterator debug_frame
= section_map.find("__debug_frame"); = section_map.find("__debug_frame");
@ -509,7 +520,7 @@ bool DumpSymbols::ReadSymbolData(Module** out_module) {
// Walk its load commands, and deal with whatever is there. // Walk its load commands, and deal with whatever is there.
LoadCommandDumper load_command_dumper(*this, module.get(), reader, LoadCommandDumper load_command_dumper(*this, module.get(), reader,
symbol_data_); symbol_data_, handle_inter_cu_refs_);
if (!reader.WalkLoadCommands(&load_command_dumper)) if (!reader.WalkLoadCommands(&load_command_dumper))
return false; return false;

View file

@ -46,15 +46,17 @@ using google_breakpad::DumpSymbols;
using std::vector; using std::vector;
struct Options { struct Options {
Options() : srcPath(), arch(), cfi(true) { } Options() : srcPath(), arch(), cfi(true), handle_inter_cu_refs(true) { }
NSString *srcPath; NSString *srcPath;
const NXArchInfo *arch; const NXArchInfo *arch;
bool cfi; bool cfi;
bool handle_inter_cu_refs;
}; };
//============================================================================= //=============================================================================
static bool Start(const Options &options) { static bool Start(const Options &options) {
DumpSymbols dump_symbols(options.cfi ? ALL_SYMBOL_DATA : NO_CFI); DumpSymbols dump_symbols(options.cfi ? ALL_SYMBOL_DATA : NO_CFI,
options.handle_inter_cu_refs);
if (!dump_symbols.Read(options.srcPath)) if (!dump_symbols.Read(options.srcPath))
return false; return false;
@ -97,6 +99,7 @@ static void Usage(int argc, const char *argv[]) {
fprintf(stderr, "\t-a: Architecture type [default: native, or whatever is\n"); fprintf(stderr, "\t-a: Architecture type [default: native, or whatever is\n");
fprintf(stderr, "\t in the file, if it contains only one architecture]\n"); fprintf(stderr, "\t in the file, if it contains only one architecture]\n");
fprintf(stderr, "\t-c: Do not generate CFI section\n"); fprintf(stderr, "\t-c: Do not generate CFI section\n");
fprintf(stderr, "\t-r: Do not handle inter-compilation unit references\n");
fprintf(stderr, "\t-h: Usage\n"); fprintf(stderr, "\t-h: Usage\n");
fprintf(stderr, "\t-?: Usage\n"); fprintf(stderr, "\t-?: Usage\n");
} }
@ -106,7 +109,7 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
extern int optind; extern int optind;
signed char ch; signed char ch;
while ((ch = getopt(argc, (char * const *)argv, "a:ch?")) != -1) { while ((ch = getopt(argc, (char * const *)argv, "a:chr?")) != -1) {
switch (ch) { switch (ch) {
case 'a': { case 'a': {
const NXArchInfo *arch_info = const NXArchInfo *arch_info =
@ -122,6 +125,9 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
case 'c': case 'c':
options->cfi = false; options->cfi = false;
break; break;
case 'r':
options->handle_inter_cu_refs = false;
break;
case '?': case '?':
case 'h': case 'h':
Usage(argc, argv); Usage(argc, argv);