diff --git a/llvm/test/tools/dsymutil/X86/fat-object-compatible-triple.test b/llvm/test/tools/dsymutil/X86/fat-object-compatible-triple.test new file mode 100644 index 000000000000..e5f15c79ae13 --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/fat-object-compatible-triple.test @@ -0,0 +1,23 @@ +# Verify that dsymutil can match an object file by compatible triple when there +# is no exact string match (e.g. the debug map triple has a version suffix that +# the object file triple lacks). + +# RUN: dsymutil -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s + +# RUN: dsymutil --linker parallel -f -oso-prepend-path=%p/../Inputs -y %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s + +# The fat-test.o object reports its x86_64 slice as "x86_64-apple-darwin". +# Using "x86_64-apple-darwin20" here exercises the compatible-triple fallback: +# the strings differ, but the triples are compatible (same arch, vendor, OS kind). +--- +triple: 'x86_64-apple-darwin20' +objects: + - filename: fat-test.o + symbols: + - { sym: _x86_64_var, objAddr: 0x0, binAddr: 0x1000, size: 0x4 } +... + +# CHECK: .debug_info contents: +# CHECK: DW_TAG_variable +# CHECK-NOT: {{DW_TAG|NULL}} +# CHECK: DW_AT_name{{.*}}"x86_64_var" diff --git a/llvm/tools/dsymutil/BinaryHolder.cpp b/llvm/tools/dsymutil/BinaryHolder.cpp index 58751bddd3ba..5cd399000703 100644 --- a/llvm/tools/dsymutil/BinaryHolder.cpp +++ b/llvm/tools/dsymutil/BinaryHolder.cpp @@ -155,13 +155,25 @@ BinaryHolder::ObjectEntry::getObjects() const { } Expected BinaryHolder::ObjectEntry::getObject(const Triple &T) const { + // Prefer an exact match, but settle for a compatible match if there is one. + object::ObjectFile const *CompatibleMatch = nullptr; for (const auto &Obj : Objects) { if (const auto *MachO = dyn_cast(Obj.get())) { - if (MachO->getArchTriple().str() == T.str()) + llvm::Triple ObjTriple = MachO->getArchTriple(); + if (ObjTriple.str() == T.str()) return *MachO; - } else if (Obj->getArch() == T.getArch()) - return *Obj; + if (!CompatibleMatch && ObjTriple.isCompatibleWith(T)) + CompatibleMatch = MachO; + } else { + llvm::Triple ObjTriple = Obj->makeTriple(); + if (ObjTriple.str() == T.str()) + return *Obj; + if (!CompatibleMatch && ObjTriple.isCompatibleWith(T)) + CompatibleMatch = Obj.get(); + } } + if (CompatibleMatch) + return *CompatibleMatch; return errorCodeToError(object::object_error::arch_not_found); }