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
diff --git a/src/common/mac/dump_syms.h b/src/common/mac/dump_syms.h
index f7d391f..34e8397 100644
--- a/src/common/mac/dump_syms.h
+++ b/src/common/mac/dump_syms.h
@@ -53,8 +53,9 @@
 
 class DumpSymbols {
  public:
-  explicit DumpSymbols(SymbolData symbol_data)
+  DumpSymbols(SymbolData symbol_data, bool handle_inter_cu_refs)
       : symbol_data_(symbol_data),
+        handle_inter_cu_refs_(handle_inter_cu_refs),
         input_pathname_(),
         object_filename_(),
         contents_(),
@@ -134,7 +135,8 @@
   // on failure, report the problem and return false.
   bool ReadDwarf(google_breakpad::Module *module,
                  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
   // |macho_reader|, and record it in |module|.  If |eh_frame| is true,
@@ -149,6 +151,9 @@
   // The selection of what type of symbol data to read/write.
   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.
   // This is the path given to Read, for use in error messages.
   NSString *input_pathname_;
diff --git a/src/common/mac/dump_syms.mm b/src/common/mac/dump_syms.mm
index cd19f72..c8c3a35 100644
--- a/src/common/mac/dump_syms.mm
+++ b/src/common/mac/dump_syms.mm
@@ -253,7 +253,8 @@
 
 bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
                             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.
   ByteReader byte_reader(macho_reader.big_endian()
                          ? dwarf2reader::ENDIANNESS_BIG
@@ -261,19 +262,24 @@
 
   // Construct a context for this file.
   DwarfCUToModule::FileContext file_context(selected_object_name_,
-                                            module);
+                                            module,
+                                            handle_inter_cu_refs);
 
   // Build a dwarf2reader::SectionMap from our mach_o::SectionMap.
   for (mach_o::SectionMap::const_iterator it = dwarf_sections.begin();
-       it != dwarf_sections.end(); it++) {
-    file_context.section_map[it->first] =
-      make_pair(reinterpret_cast<const char *>(it->second.contents.start),
-                it->second.contents.Size());
+       it != dwarf_sections.end(); ++it) {
+    file_context.AddSectionToSectionMap(
+        it->first,
+        reinterpret_cast<const char *>(it->second.contents.start),
+        it->second.contents.Size());
   }
 
   // Find the __debug_info section.
-  std::pair<const char *, uint64> debug_info_section
-      = file_context.section_map["__debug_info"];
+  dwarf2reader::SectionMap::const_iterator debug_info_entry =
+      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!
   if (!debug_info_section.first) {
     fprintf(stderr, "%s: __DWARF segment of file has no __debug_info section\n",
@@ -295,7 +301,7 @@
     // Make a Dwarf2Handler that drives our DIEHandler.
     dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
     // 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,
                                                &byte_reader,
                                                &die_dispatcher);
@@ -374,11 +380,13 @@
   LoadCommandDumper(const DumpSymbols &dumper,
                     google_breakpad::Module *module,
                     const mach_o::Reader &reader,
-                    SymbolData symbol_data)
+                    SymbolData symbol_data,
+                    bool handle_inter_cu_refs)
       : dumper_(dumper),
         module_(module),
         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 SymtabCommand(const ByteBuffer &entries, const ByteBuffer &strings);
@@ -388,6 +396,7 @@
   google_breakpad::Module *module_;  // WEAK
   const mach_o::Reader &reader_;
   const SymbolData symbol_data_;
+  const bool handle_inter_cu_refs_;
 };
 
 bool DumpSymbols::LoadCommandDumper::SegmentCommand(const Segment &segment) {
@@ -408,8 +417,10 @@
 
   if (segment.name == "__DWARF") {
     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;
+      }
     }
     if (symbol_data_ != NO_CFI) {
       mach_o::SectionMap::const_iterator debug_frame
@@ -509,7 +520,7 @@
 
   // Walk its load commands, and deal with whatever is there.
   LoadCommandDumper load_command_dumper(*this, module.get(), reader,
-                                        symbol_data_);
+                                        symbol_data_, handle_inter_cu_refs_);
   if (!reader.WalkLoadCommands(&load_command_dumper))
     return false;
 
diff --git a/src/tools/mac/dump_syms/dump_syms_tool.mm b/src/tools/mac/dump_syms/dump_syms_tool.mm
index 68321db..fd1b61e 100644
--- a/src/tools/mac/dump_syms/dump_syms_tool.mm
+++ b/src/tools/mac/dump_syms/dump_syms_tool.mm
@@ -46,15 +46,17 @@
 using std::vector;
 
 struct Options {
-  Options() : srcPath(), arch(), cfi(true) { }
+  Options() : srcPath(), arch(), cfi(true), handle_inter_cu_refs(true) { }
   NSString *srcPath;
   const NXArchInfo *arch;
   bool cfi;
+  bool handle_inter_cu_refs;
 };
 
 //=============================================================================
 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))
     return false;
@@ -97,6 +99,7 @@
   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-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-?: Usage\n");
 }
@@ -106,7 +109,7 @@
   extern int optind;
   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) {
       case 'a': {
         const NXArchInfo *arch_info =
@@ -122,6 +125,9 @@
       case 'c':
         options->cfi = false;
         break;
+      case 'r':
+        options->handle_inter_cu_refs = false;
+        break;
       case '?':
       case 'h':
         Usage(argc, argv);