Merge pull request #481 from rjmansfield/macho-archs-support

Add -d archs data source for Mach-O universal binaries
diff --git a/src/bloaty.cc b/src/bloaty.cc
index 631b96b..5232959 100644
--- a/src/bloaty.cc
+++ b/src/bloaty.cc
@@ -2147,7 +2147,8 @@
           "$0   $1\n", absl::BytesToHexString(file_info.build_id_).c_str(),
           file_info.filename_.c_str());
     }
-    THROWF("Debug file(s) did not match any input file:\n$0\nInput Files:\n$1",
+    THROWF("Debug file(s) build ID did not match any input file build "
+           "ID:\n$0\nInput Files:\n$1",
            unused_debug.c_str(), input_files.c_str());
   }
 }
diff --git a/src/dwarf.cc b/src/dwarf.cc
index 1d1603d..eb68bc1 100644
--- a/src/dwarf.cc
+++ b/src/dwarf.cc
@@ -668,6 +668,12 @@
 
     std::string dwo_path = ConstructDwoPath(dwo_info);
     if (!dwo_path.empty() && &cu == &cu.skeleton()) {
+      // Check if DWO file exists before trying to open it
+      if (!std::filesystem::exists(dwo_path)) {
+        fprintf(stderr, "Warning: DWO file not found: %s\n", dwo_path.c_str());
+        continue;
+      }
+
       auto file = MmapInputFileFactory().OpenFile(dwo_path);
       dwarf::File dwo_dwarf;
       cu.dwarf().open(*file, &dwo_dwarf, sink);
diff --git a/src/dwarf/line_info.cc b/src/dwarf/line_info.cc
index 1b83e5e..a3630db 100644
--- a/src/dwarf/line_info.cc
+++ b/src/dwarf/line_info.cc
@@ -264,6 +264,9 @@
           }
         }
       }
+      if (file_name.directory_index >= include_directories_.size()) {
+        THROW("directory index out of range");
+      }
       filenames_.push_back(file_name);
     }
   }
diff --git a/tests/dwarf/debug_info/missing-dwo-file.test b/tests/dwarf/debug_info/missing-dwo-file.test
new file mode 100644
index 0000000..a2578e8
--- /dev/null
+++ b/tests/dwarf/debug_info/missing-dwo-file.test
@@ -0,0 +1,66 @@
+# Test that missing .dwo files produce a warning but don't fail analysis.
+
+# RUN: %yaml2obj %s -o %t.obj
+# RUN: %bloaty %t.obj -d compileunits 2>&1 | %FileCheck %s
+
+# CHECK: Warning: DWO file not found: /nonexistent/path/missing.dwo
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_DYN
+  Machine:         EM_X86_64
+ProgramHeaders:
+  - Type:            PT_LOAD
+    Flags:           [ PF_X, PF_R ]
+    FirstSec:        .text
+    LastSec:         .text
+    VAddr:           0x1000
+    Align:           0x1000
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x1000
+    AddressAlign:    0x10
+    Size:            0x50
+  - Name:            .debug_addr
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x1
+    Content:         '0010000000000000'
+DWARF:
+  debug_str:
+    - /nonexistent/path/missing.dwo
+    - /some/comp/dir
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_comp_dir
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_GNU_dwo_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_GNU_dwo_id
+              Form:            DW_FORM_data8
+            - Attribute:       DW_AT_GNU_addr_base
+              Form:            DW_FORM_sec_offset
+  debug_info:
+    - Version:         4
+      AbbrevTableID:   0
+      AbbrOffset:      0x0
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x1
+          Values:
+            # comp_dir offset (points to "/some/comp/dir")
+            - Value:           0x22
+            # dwo_name offset (points to "/nonexistent/path/missing.dwo")
+            - Value:           0x0
+            # dwo_id
+            - Value:           0x1234567890abcdef
+            # addr_base
+            - Value:           0x0