From d98ed0219d45b6e66fdab6773e2c4f77f6b0e3eb Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Mon, 21 Jul 2025 14:24:50 +0530 Subject: [PATCH 01/25] big archive recognition implementation --- llvm/docs/CommandGuide/llvm-symbolizer.rst | 18 ++- .../llvm/DebugInfo/Symbolize/Symbolize.h | 26 ++++ llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 102 +++++++++++++-- .../test/DebugInfo/Inputs/big-archive-32.yaml | 119 ++++++++++++++++++ .../test/DebugInfo/Inputs/big-archive-64.yaml | 26 ++++ .../DebugInfo/Inputs/big-archive-elf-1.yaml | 68 ++++++++++ .../DebugInfo/Inputs/big-archive-elf-2.yaml | 68 ++++++++++ .../DebugInfo/symbolize-big-archive-elf.test | 24 ++++ .../symbolize-big-archive-xcoff.test | 26 ++++ llvm/tools/llvm-symbolizer/Opts.td | 6 +- 10 files changed, 469 insertions(+), 14 deletions(-) create mode 100644 llvm/test/DebugInfo/Inputs/big-archive-32.yaml create mode 100644 llvm/test/DebugInfo/Inputs/big-archive-64.yaml create mode 100644 llvm/test/DebugInfo/Inputs/big-archive-elf-1.yaml create mode 100644 llvm/test/DebugInfo/Inputs/big-archive-elf-2.yaml create mode 100644 llvm/test/DebugInfo/symbolize-big-archive-elf.test create mode 100644 llvm/test/DebugInfo/symbolize-big-archive-xcoff.test diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst index 2da1b2470a83e..8f3a132139fe9 100644 --- a/llvm/docs/CommandGuide/llvm-symbolizer.rst +++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst @@ -535,16 +535,20 @@ MACH-O SPECIFIC OPTIONS .. option:: --default-arch If a binary contains object files for multiple architectures (e.g. it is a - Mach-O universal binary), symbolize the object file for a given architecture. - You can also specify the architecture by writing ``binary_name:arch_name`` in - the input (see example below). If the architecture is not specified in either - way, the address will not be symbolized. Defaults to empty string. + Mach-O universal binary or an AIX archive with architecture variants), + symbolize the object file for a given architecture. You can also specify + the architecture by writing ``binary_name:arch_name`` in the input (see + example below). For AIX archives, the format ``archive.a(member.o):arch`` + is also supported. If the architecture is not specified in either way, + the address will not be symbolized. Defaults to empty string. .. code-block:: console $ cat addr.txt /tmp/mach_universal_binary:i386 0x1f84 /tmp/mach_universal_binary:x86_64 0x100000f24 + /tmp/archive.a(member.o):ppc 0x1000 + /tmp/archive.a(member.o):ppc64 0x2000 $ llvm-symbolizer < addr.txt _main @@ -553,6 +557,12 @@ MACH-O SPECIFIC OPTIONS _main /tmp/source_x86_64.cc:8 + _foo + /tmp/source_ppc.cc:12 + + _foo + /tmp/source_ppc64.cc:12 + .. option:: --dsym-hint If the debug info for a binary isn't present in the default location, look for diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index fb8f3d8af6b1b..5144085f3e23c 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -29,6 +29,12 @@ #include #include +#if defined(_AIX) +# define SYMBOLIZE_AIX 1 +#else +# define SYMBOLIZE_AIX 0 +#endif + namespace llvm { namespace object { class ELFObjectFileBase; @@ -202,6 +208,12 @@ class LLVMSymbolizer { Expected getOrCreateObject(const std::string &Path, const std::string &ArchName); + /// Return a pointer to object file at specified path, for a specified + /// architecture that is present inside an archive file + Expected getOrCreateObjectFromArchive(StringRef ArchivePath, + StringRef MemberName, + const std::string &ArchName); + /// Update the LRU cache order when a binary is accessed. void recordAccess(CachedBinary &Bin); @@ -226,6 +238,20 @@ class LLVMSymbolizer { std::map, std::unique_ptr> ObjectForUBPathAndArch; + struct ArchiveCacheKey { + std::string ArchivePath; // Storage for StringRef + std::string MemberName; // Storage for StringRef + std::string ArchName; // Storage for StringRef + + // Required for map comparison + bool operator<(const ArchiveCacheKey &Other) const { + return std::tie(ArchivePath, MemberName, ArchName) < + std::tie(Other.ArchivePath, Other.MemberName, Other.ArchName); + } + }; + + std::map> ObjectForArchivePathAndArch; + Options Opts; std::unique_ptr BIDFetcher; diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 56527719da51f..6dddc3a709239 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -33,6 +33,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include "llvm/Object/Archive.h" #include #include @@ -286,6 +287,7 @@ LLVMSymbolizer::findSymbol(ArrayRef BuildID, StringRef Symbol, void LLVMSymbolizer::flush() { ObjectForUBPathAndArch.clear(); + ObjectForArchivePathAndArch.clear(); LRUBinaries.clear(); CacheSize = 0; BinaryForPath.clear(); @@ -321,7 +323,7 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) { bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName, uint32_t &CRCHash) { - if (!Obj) + if (!Obj || !isa(Obj)) return false; for (const SectionRef &Section : Obj->sections()) { StringRef Name; @@ -557,19 +559,101 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, if (!DbgObj) DbgObj = Obj; ObjectPair Res = std::make_pair(Obj, DbgObj); - std::string DbgObjPath = DbgObj->getFileName().str(); auto Pair = ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res); - BinaryForPath.find(DbgObjPath)->second.pushEvictor([this, I = Pair.first]() { + std::string DbgObjPath = DbgObj->getFileName().str(); + auto BinIter = BinaryForPath.find(DbgObjPath); + if (BinIter != BinaryForPath.end()) { + BinIter->second.pushEvictor([this, I = Pair.first]() { ObjectPairForPathArch.erase(I); - }); + }); + } return Res; } +Expected LLVMSymbolizer::getOrCreateObjectFromArchive(StringRef ArchivePath, + StringRef MemberName, + const std::string &ArchName) { + Binary *Bin = nullptr; + auto Pair = BinaryForPath.emplace(ArchivePath.str(), OwningBinary()); + if (!Pair.second) { + Bin = Pair.first->second->getBinary(); + recordAccess(Pair.first->second); + } else { + Expected> ArchiveOrErr = createBinary(ArchivePath); + if (!ArchiveOrErr) { + return ArchiveOrErr.takeError(); + } + + CachedBinary &CachedBin = Pair.first->second; + CachedBin = std::move(ArchiveOrErr.get()); + CachedBin.pushEvictor([this, I = Pair.first]() { BinaryForPath.erase(I); }); + LRUBinaries.push_back(CachedBin); + CacheSize += CachedBin.size(); + Bin = CachedBin->getBinary(); + } + + if (!Bin || !isa(Bin)) + return errorCodeToError(object_error::invalid_file_type); + + object::Archive *Archive = cast(Bin); + Error Err = Error::success(); + + // On AIX, archives can contain multiple members with same name but different types + // We need to check all matches and find one that matches both name and architecture + for (auto &Child : Archive->children(Err, /*SkipInternal=*/true)) { + Expected NameOrErr = Child.getName(); + if (!NameOrErr) + continue; + if (*NameOrErr == llvm::sys::path::filename(MemberName)) { + Expected> MemberOrErr = Child.getAsBinary(); + if (!MemberOrErr) + continue; + + std::unique_ptr Binary = std::move(*MemberOrErr); + if (auto *Obj = dyn_cast(Binary.get())) { +#if defined(_AIX) + Triple::ArchType ObjArch = Obj->makeTriple().getArch(); + Triple RequestedTriple; + RequestedTriple.setArch(Triple::getArchTypeForLLVMName(ArchName)); + if (ObjArch != RequestedTriple.getArch()) + continue; +#endif + ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), ArchName}; + auto I = ObjectForArchivePathAndArch.find(CacheKey); + if (I != ObjectForArchivePathAndArch.end()) + return I->second.get(); + + auto CachedObj = std::unique_ptr(Obj); + auto NewEntry = ObjectForArchivePathAndArch.emplace( + CacheKey, std::move(CachedObj)); + Binary.release(); + BinaryForPath.find(ArchivePath.str())->second.pushEvictor( + [this, Iter = NewEntry.first]() { ObjectForArchivePathAndArch.erase(Iter); }); + return NewEntry.first->second.get(); + } + } + } + if (Err) + return std::move(Err); + return errorCodeToError(object_error::arch_not_found); +} + Expected LLVMSymbolizer::getOrCreateObject(const std::string &Path, const std::string &ArchName) { - Binary *Bin; + // First check for archive(member) format - more efficient to check closing paren first + size_t CloseParen = Path.rfind(')'); + if (CloseParen != std::string::npos && CloseParen == Path.length() - 1) { + size_t OpenParen = Path.rfind('(', CloseParen); + if (OpenParen != std::string::npos) { + StringRef ArchivePath = StringRef(Path).substr(0, OpenParen); + StringRef MemberName = StringRef(Path).substr(OpenParen + 1, CloseParen - OpenParen - 1); + return getOrCreateObjectFromArchive(ArchivePath, MemberName, ArchName); + } + } + + Binary *Bin = nullptr; auto Pair = BinaryForPath.emplace(Path, OwningBinary()); if (!Pair.second) { Bin = Pair.first->second->getBinary(); @@ -648,7 +732,9 @@ LLVMSymbolizer::getOrCreateModuleInfo(StringRef ModuleName) { auto I = Modules.find(ModuleName); if (I != Modules.end()) { - recordAccess(BinaryForPath.find(BinaryName)->second); + auto BinIter = BinaryForPath.find(BinaryName); + if (BinIter != BinaryForPath.end()) + recordAccess(BinIter->second); return I->second.get(); } @@ -716,7 +802,9 @@ LLVMSymbolizer::getOrCreateModuleInfo(StringRef ModuleName) { createModuleInfo(Objects.first, std::move(Context), ModuleName); if (ModuleOrErr) { auto I = Modules.find(ModuleName); - BinaryForPath.find(BinaryName)->second.pushEvictor([this, I]() { + auto BinIter = BinaryForPath.find(BinaryName); + if (BinIter != BinaryForPath.end()) + BinIter->second.pushEvictor([this, I]() { Modules.erase(I); }); } diff --git a/llvm/test/DebugInfo/Inputs/big-archive-32.yaml b/llvm/test/DebugInfo/Inputs/big-archive-32.yaml new file mode 100644 index 0000000000000..2080607a1a88c --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/big-archive-32.yaml @@ -0,0 +1,119 @@ +--- !XCOFF +FileHeader: + MagicNumber: 0x1DF + NumberOfSections: 2 + CreationTime: 0 + OffsetToSymbolTable: 0xA0 + EntriesInSymbolTable: 11 + AuxiliaryHeaderSize: 0 + Flags: 0x0 +Sections: + - Name: .text + Address: 0x0 + Size: 0x1C + FileOffsetToData: 0x64 + FileOffsetToRelocations: 0x0 + FileOffsetToLineNumbers: 0x0 + NumberOfRelocations: 0x0 + NumberOfLineNumbers: 0x0 + Flags: [ STYP_TEXT ] + SectionData: 4E800020000000000009204000000001000000040003666F6F000000 + - Name: .data + Address: 0x1C + Size: 0xC + FileOffsetToData: 0x80 + FileOffsetToRelocations: 0x8C + FileOffsetToLineNumbers: 0x0 + NumberOfRelocations: 0x2 + NumberOfLineNumbers: 0x0 + Flags: [ STYP_DATA ] + SectionData: '000000000000002800000000' + Relocations: + - Address: 0x1C + Symbol: 0x5 + Info: 0x1F + Type: 0x0 + - Address: 0x20 + Symbol: 0x9 + Info: 0x1F + Type: 0x0 +Symbols: + - Name: .file + Value: 0x0 + Section: N_DEBUG + Type: 0x18 + StorageClass: C_FILE + NumberOfAuxEntries: 2 + AuxEntries: + - Type: AUX_FILE + FileNameOrString: foo.c + FileStringType: XFT_FN + - Type: AUX_FILE + FileNameOrString: 'IBM Open XL C/C++ for AIX 17.1.3 (5725-C72, 5765-J18), version 17.1.3.0, LLVM version 21.0.0git (145c02cece3630765e6412e6820bc446ddb4e138)' + FileStringType: XFT_CV + - Name: '' + Value: 0x0 + Section: .text + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_SD + SymbolAlignment: 5 + StorageMappingClass: XMC_PR + SectionOrLength: 25 + StabInfoIndex: 0 + StabSectNum: 0 + - Name: .foo + Value: 0x0 + Section: .text + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_LD + SymbolAlignment: 0 + StorageMappingClass: XMC_PR + SectionOrLength: 3 + StabInfoIndex: 0 + StabSectNum: 0 + - Name: foo + Value: 0x1C + Section: .data + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_SD + SymbolAlignment: 2 + StorageMappingClass: XMC_DS + SectionOrLength: 12 + StabInfoIndex: 0 + StabSectNum: 0 + - Name: TOC + Value: 0x28 + Section: .data + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_SD + SymbolAlignment: 2 + StorageMappingClass: XMC_TC0 + SectionOrLength: 0 + StabInfoIndex: 0 + StabSectNum: 0 +StringTable: {} +... diff --git a/llvm/test/DebugInfo/Inputs/big-archive-64.yaml b/llvm/test/DebugInfo/Inputs/big-archive-64.yaml new file mode 100644 index 0000000000000..c1078efe2407e --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/big-archive-64.yaml @@ -0,0 +1,26 @@ +--- !XCOFF +FileHeader: + Magic: 0x01F7 # XCOFF64 magic number + NumberOfSections: 1 + TimeStamp: 0 + SymbolTableOffset: 0 + NumberOfSymTableEntries: 1 +OptionalHeader: + Flags: 0x0 +Sections: + - Name: .text + Address: 0x0` + Size: 1 + FileOffsetToRawData: 0x100 + FileOffsetToRelocations: 0 + FileOffsetToLineNumbers: 0 + NumberOfRelocations: 0 + NumberOfLineNumbers: 0 + Flags: STYP_TEXT + SectionData: '00' +Symbols: + - Name: foo + Value: 0 + SectionNumber: 1 + StorageClass: C_EXT + NumberOfAuxEntries: 0 diff --git a/llvm/test/DebugInfo/Inputs/big-archive-elf-1.yaml b/llvm/test/DebugInfo/Inputs/big-archive-elf-1.yaml new file mode 100644 index 0000000000000..8e5c929e82878 --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/big-archive-elf-1.yaml @@ -0,0 +1,68 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_PPC64 + Flags: [ ] + SectionHeaderStringTable: .strtab +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: '2000804E000000000000000000000000' + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 0049424D204F70656E20584C20432F432B2B20666F72204C696E7578206F6E20506F7765722031372E312E322028353732352D4337322C20353736352D4A3230292C2076657273696F6E2031372E312E322E302C20636C616E672076657273696F6E2032312E302E306769742028676974406769746875622E69626D2E636F6D3A636F6D70696C65722F6C6C766D2D70726F6A6563742E67697420653165653233663838333532623937333563363735386661396335653035313366626234393361322900 + - Name: .note.GNU-stack + Type: SHT_PROGBITS + AddressAlign: 0x1 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + AddressAlign: 0x8 + Content: 1000000000000000017A5200047841011B0C01001000000018000000000000001000000000000000 + - Name: .rela.eh_frame + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .eh_frame + Relocations: + - Offset: 0x1C + Symbol: .text + Type: R_PPC64_REL32 + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Flags: [ SHF_EXCLUDE ] + Link: .symtab + AddressAlign: 0x1 + Offset: 0x1B8 + Symbols: [ ] + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: .text + - Name: .comment + - Name: .note.GNU-stack + - Name: .eh_frame + - Name: .rela.eh_frame + - Name: .llvm_addrsig + - Name: .symtab +Symbols: + - Name: foo1.c + Type: STT_FILE + Index: SHN_ABS + - Name: .text + Type: STT_SECTION + Section: .text + - Name: foo1 + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Size: 0x10 +... diff --git a/llvm/test/DebugInfo/Inputs/big-archive-elf-2.yaml b/llvm/test/DebugInfo/Inputs/big-archive-elf-2.yaml new file mode 100644 index 0000000000000..0052db732500f --- /dev/null +++ b/llvm/test/DebugInfo/Inputs/big-archive-elf-2.yaml @@ -0,0 +1,68 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_PPC64 + Flags: [ ] + SectionHeaderStringTable: .strtab +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: '2000804E000000000000000000000000' + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 0049424D204F70656E20584C20432F432B2B20666F72204C696E7578206F6E20506F7765722031372E312E322028353732352D4337322C20353736352D4A3230292C2076657273696F6E2031372E312E322E302C20636C616E672076657273696F6E2032312E302E306769742028676974406769746875622E69626D2E636F6D3A636F6D70696C65722F6C6C766D2D70726F6A6563742E67697420653165653233663838333532623937333563363735386661396335653035313366626234393361322900 + - Name: .note.GNU-stack + Type: SHT_PROGBITS + AddressAlign: 0x1 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + AddressAlign: 0x8 + Content: 1000000000000000017A5200047841011B0C01001000000018000000000000001000000000000000 + - Name: .rela.eh_frame + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .eh_frame + Relocations: + - Offset: 0x1C + Symbol: .text + Type: R_PPC64_REL32 + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Flags: [ SHF_EXCLUDE ] + Link: .symtab + AddressAlign: 0x1 + Offset: 0x1B8 + Symbols: [ ] + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: .text + - Name: .comment + - Name: .note.GNU-stack + - Name: .eh_frame + - Name: .rela.eh_frame + - Name: .llvm_addrsig + - Name: .symtab +Symbols: + - Name: foo2.c + Type: STT_FILE + Index: SHN_ABS + - Name: .text + Type: STT_SECTION + Section: .text + - Name: foo2 + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Size: 0x10 +... diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test new file mode 100644 index 0000000000000..2cd223333d546 --- /dev/null +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -0,0 +1,24 @@ +// Test archive member recognition by name (ELF format) + +// Generate object files from YAML +// RUN: yaml2obj -o %t-1.o %S/Inputs/big-archive-elf-1.yaml +// RUN: yaml2obj -o %t-2.o %S/Inputs/big-archive-elf-2.yaml + +// Create archive with differently named members +// RUN: rm -f %t.a +// RUN: llvm-ar crv %t.a %t-1.o %t-2.o + +// Verify archive contents +// RUN: llvm-ar tv %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE +// CHECK-ARCHIVE: {{.*}}-1.o +// CHECK-ARCHIVE: {{.*}}-2.o + +// Test symbolization by member name (using just base names) +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t-1.o)" 0x0 | FileCheck %s --check-prefix=CHECK-1 +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 +// CHECK-1: foo1 +// CHECK-2: foo2 + +// Test error cases +// RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR +// CHECK-ERROR: error: {{.*}}No object file for requested architecture diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test new file mode 100644 index 0000000000000..ae39fc929bea6 --- /dev/null +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -0,0 +1,26 @@ +// Test big archive recognition and error handling in llvm-symbolizer + +// Generate object files +// RUN: yaml2obj -o %t-32.o %S/Inputs/big-archive-32.yaml +// RUN: yaml2obj -o %t-64.o %S/Inputs/big-archive-64.yaml + +// Create archive with same-named members using different modes +// RUN: rm -f %t.a +// RUN: cp %t-32.o %t.o && llvm-ar -X32 crv %t.a %t.o +// RUN: cp %t-64.o %t.o && llvm-ar -X64 qv %t.a %t.o + +// Verify archive contains two members with same name +// RUN: llvm-ar tv -X32_64 %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE +// CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} +// CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} + +// Test successful symbolization +// RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-32 +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 +// CHECK-32: foo +// CHECK-64: foo + +// Test error cases +// RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR + +// CHECK-ERROR: error: {{.*}}No object file for requested architecture diff --git a/llvm/tools/llvm-symbolizer/Opts.td b/llvm/tools/llvm-symbolizer/Opts.td index 10f1e6dbbddf7..f616109346c55 100644 --- a/llvm/tools/llvm-symbolizer/Opts.td +++ b/llvm/tools/llvm-symbolizer/Opts.td @@ -15,7 +15,7 @@ class F: Flag<["--"], name>, HelpText; def grp_mach_o : OptionGroup<"kind">, HelpText<"llvm-symbolizer Mach-O Specific Options">; - +def grp_symbolizer : OptionGroup<"Symbolizer Options">; def grp_gsym : OptionGroup<"kind">, HelpText<"llvm-symbolizer GSYM Related Options">; @@ -31,8 +31,8 @@ def color_EQ : Joined<["--"], "color=">, HelpText<"Whether to use color when sym defm debug_file_directory : Eq<"debug-file-directory", "Path to directory where to look for debug files">, MetaVarName<"">; defm debuginfod : B<"debuginfod", "Use debuginfod to find debug binaries", "Don't use debuginfod to find debug binaries">; defm default_arch - : Eq<"default-arch", "Default architecture (for multi-arch objects)">, - Group; + : Eq<"default-arch", "Default architecture for multi-arch containers (Mach-O objects or AIX archives)">, + Group; defm demangle : B<"demangle", "Demangle function names", "Don't demangle function names">; def disable_gsym : F<"disable-gsym", "Don't consider using GSYM files for symbolication">, Group; def filter_markup : Flag<["--"], "filter-markup">, HelpText<"Filter symbolizer markup from stdin.">; From 64639e1512af8f31a9dfd909082f3c2a496bd914 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Tue, 22 Jul 2025 15:25:01 +0530 Subject: [PATCH 02/25] ELF test not supported on AIX --- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 2cd223333d546..87442f633548d 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -1,4 +1,5 @@ // Test archive member recognition by name (ELF format) +// UNSUPPORTED: target={{.*}}-aix{{.*}} // Generate object files from YAML // RUN: yaml2obj -o %t-1.o %S/Inputs/big-archive-elf-1.yaml From f5a357ef3d638cc7d603783755f646d035853bc5 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Thu, 24 Jul 2025 05:07:26 -0400 Subject: [PATCH 03/25] update yaml script --- .../test/DebugInfo/Inputs/big-archive-64.yaml | 133 +++++++++++++++--- 1 file changed, 111 insertions(+), 22 deletions(-) diff --git a/llvm/test/DebugInfo/Inputs/big-archive-64.yaml b/llvm/test/DebugInfo/Inputs/big-archive-64.yaml index c1078efe2407e..9bbb1107555e0 100644 --- a/llvm/test/DebugInfo/Inputs/big-archive-64.yaml +++ b/llvm/test/DebugInfo/Inputs/big-archive-64.yaml @@ -1,26 +1,115 @@ --- !XCOFF FileHeader: - Magic: 0x01F7 # XCOFF64 magic number - NumberOfSections: 1 - TimeStamp: 0 - SymbolTableOffset: 0 - NumberOfSymTableEntries: 1 -OptionalHeader: - Flags: 0x0 + MagicNumber: 0x1F7 + NumberOfSections: 2 + CreationTime: 0 + OffsetToSymbolTable: 0xF8 + EntriesInSymbolTable: 11 + AuxiliaryHeaderSize: 0 + Flags: 0x0 Sections: - - Name: .text - Address: 0x0` - Size: 1 - FileOffsetToRawData: 0x100 - FileOffsetToRelocations: 0 - FileOffsetToLineNumbers: 0 - NumberOfRelocations: 0 - NumberOfLineNumbers: 0 - Flags: STYP_TEXT - SectionData: '00' + - Name: .text + Address: 0x0 + Size: 0x1C + FileOffsetToData: 0xA8 + FileOffsetToRelocations: 0x0 + FileOffsetToLineNumbers: 0x0 + NumberOfRelocations: 0x0 + NumberOfLineNumbers: 0x0 + Flags: [ STYP_TEXT ] + SectionData: 4E800020000000000009204000000001000000040003666F6F000000 + - Name: .data + Address: 0x20 + Size: 0x18 + FileOffsetToData: 0xC4 + FileOffsetToRelocations: 0xDC + FileOffsetToLineNumbers: 0x0 + NumberOfRelocations: 0x2 + NumberOfLineNumbers: 0x0 + Flags: [ STYP_DATA ] + SectionData: '000000000000000000000000000000380000000000000000' + Relocations: + - Address: 0x20 + Symbol: 0x5 + Info: 0x3F + Type: 0x0 + - Address: 0x28 + Symbol: 0x9 + Info: 0x3F + Type: 0x0 Symbols: - - Name: foo - Value: 0 - SectionNumber: 1 - StorageClass: C_EXT - NumberOfAuxEntries: 0 + - Name: .file + Value: 0x0 + Section: N_DEBUG + Type: 0x18 + StorageClass: C_FILE + NumberOfAuxEntries: 2 + AuxEntries: + - Type: AUX_FILE + FileNameOrString: foo.c + FileStringType: XFT_FN + - Type: AUX_FILE + FileNameOrString: 'IBM Open XL C/C++ for AIX 17.1.3 (5725-C72, 5765-J18), version 17.1.3.0, LLVM version 21.0.0git (5ca72bc8d2e87445649eab1825dffd2a047440ba)' + FileStringType: XFT_CV + - Name: '' + Value: 0x0 + Section: .text + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_SD + SymbolAlignment: 5 + StorageMappingClass: XMC_PR + SectionOrLengthLo: 25 + SectionOrLengthHi: 0 + - Name: .foo + Value: 0x0 + Section: .text + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_LD + SymbolAlignment: 0 + StorageMappingClass: XMC_PR + SectionOrLengthLo: 3 + SectionOrLengthHi: 0 + - Name: foo + Value: 0x20 + Section: .data + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_SD + SymbolAlignment: 3 + StorageMappingClass: XMC_DS + SectionOrLengthLo: 24 + SectionOrLengthHi: 0 + - Name: TOC + Value: 0x38 + Section: .data + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolType: XTY_SD + SymbolAlignment: 2 + StorageMappingClass: XMC_TC0 + SectionOrLengthLo: 0 + SectionOrLengthHi: 0 +StringTable: {} +... From 305ef99231413fde40eac648a40217e6e69cf49a Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Thu, 24 Jul 2025 16:00:48 +0530 Subject: [PATCH 04/25] target specific changes --- llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index ae39fc929bea6..f034520638267 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -1,4 +1,5 @@ // Test big archive recognition and error handling in llvm-symbolizer +// REQUIRES: system-aix, target={{.*}}-aix{{.*}} // Generate object files // RUN: yaml2obj -o %t-32.o %S/Inputs/big-archive-32.yaml From 27b4f10441e8ad73ebf79d30245d1f7c8359437e Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Wed, 30 Jul 2025 19:53:32 +0530 Subject: [PATCH 05/25] Review comments addressed --- llvm/docs/CommandGuide/llvm-symbolizer.rst | 6 +- .../llvm/DebugInfo/Symbolize/Symbolize.h | 27 +++++---- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 59 ++++++++++--------- .../DebugInfo/symbolize-big-archive-elf.test | 12 ++-- .../symbolize-big-archive-xcoff.test | 32 +++++++--- 5 files changed, 75 insertions(+), 61 deletions(-) diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst index 8f3a132139fe9..7a33d538269fd 100644 --- a/llvm/docs/CommandGuide/llvm-symbolizer.rst +++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst @@ -547,8 +547,8 @@ MACH-O SPECIFIC OPTIONS $ cat addr.txt /tmp/mach_universal_binary:i386 0x1f84 /tmp/mach_universal_binary:x86_64 0x100000f24 - /tmp/archive.a(member.o):ppc 0x1000 - /tmp/archive.a(member.o):ppc64 0x2000 + /tmp/big-archive.a(member.o):ppc 0x1000 + /tmp/big-archive.a(member.o):ppc64 0x2000 $ llvm-symbolizer < addr.txt _main @@ -559,7 +559,7 @@ MACH-O SPECIFIC OPTIONS _foo /tmp/source_ppc.cc:12 - + _foo /tmp/source_ppc64.cc:12 diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 5144085f3e23c..99297cebd5c89 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -29,10 +29,10 @@ #include #include -#if defined(_AIX) -# define SYMBOLIZE_AIX 1 +#ifdef _AIX +#define SYMBOLIZE_AIX 1 #else -# define SYMBOLIZE_AIX 0 +#define SYMBOLIZE_AIX 0 #endif namespace llvm { @@ -205,14 +205,14 @@ class LLVMSymbolizer { /// Return a pointer to object file at specified path, for a specified /// architecture (e.g. if path refers to a Mach-O universal binary, only one /// object file from it will be returned). - Expected getOrCreateObject(const std::string &Path, - const std::string &ArchName); + Expected getOrCreateObject(const std::string &InputPath, + const std::string &DefaultArchName); /// Return a pointer to object file at specified path, for a specified /// architecture that is present inside an archive file - Expected getOrCreateObjectFromArchive(StringRef ArchivePath, - StringRef MemberName, - const std::string &ArchName); + Expected + getOrCreateObjectFromArchive(StringRef ArchivePath, StringRef MemberName, + StringRef ArchName); /// Update the LRU cache order when a binary is accessed. void recordAccess(CachedBinary &Bin); @@ -239,18 +239,19 @@ class LLVMSymbolizer { ObjectForUBPathAndArch; struct ArchiveCacheKey { - std::string ArchivePath; // Storage for StringRef - std::string MemberName; // Storage for StringRef - std::string ArchName; // Storage for StringRef + std::string ArchivePath; // Storage for StringRef + std::string MemberName; // Storage for StringRef + std::string ArchName; // Storage for StringRef // Required for map comparison bool operator<(const ArchiveCacheKey &Other) const { - return std::tie(ArchivePath, MemberName, ArchName) < + return std::tie(ArchivePath, MemberName, ArchName) < std::tie(Other.ArchivePath, Other.MemberName, Other.ArchName); } }; - std::map> ObjectForArchivePathAndArch; + std::map> + ObjectForArchivePathAndArch; Options Opts; diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 6dddc3a709239..74990347d4b5d 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -21,6 +21,7 @@ #include "llvm/DebugInfo/PDB/PDBContext.h" #include "llvm/DebugInfo/Symbolize/SymbolizableObjectFile.h" #include "llvm/Demangle/Demangle.h" +#include "llvm/Object/Archive.h" #include "llvm/Object/BuildID.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" @@ -33,7 +34,6 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" -#include "llvm/Object/Archive.h" #include #include @@ -323,7 +323,7 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) { bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName, uint32_t &CRCHash) { - if (!Obj || !isa(Obj)) + if (!Obj) return false; for (const SectionRef &Section : Obj->sections()) { StringRef Name; @@ -564,16 +564,14 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, std::string DbgObjPath = DbgObj->getFileName().str(); auto BinIter = BinaryForPath.find(DbgObjPath); if (BinIter != BinaryForPath.end()) { - BinIter->second.pushEvictor([this, I = Pair.first]() { - ObjectPairForPathArch.erase(I); - }); + BinIter->second.pushEvictor( + [this, I = Pair.first]() { ObjectPairForPathArch.erase(I); }); } return Res; } -Expected LLVMSymbolizer::getOrCreateObjectFromArchive(StringRef ArchivePath, - StringRef MemberName, - const std::string &ArchName) { +Expected LLVMSymbolizer::getOrCreateObjectFromArchive( + StringRef ArchivePath, StringRef MemberName, StringRef ArchName) { Binary *Bin = nullptr; auto Pair = BinaryForPath.emplace(ArchivePath.str(), OwningBinary()); if (!Pair.second) { @@ -581,9 +579,8 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive(StringRef Ar recordAccess(Pair.first->second); } else { Expected> ArchiveOrErr = createBinary(ArchivePath); - if (!ArchiveOrErr) { + if (!ArchiveOrErr) return ArchiveOrErr.takeError(); - } CachedBinary &CachedBin = Pair.first->second; CachedBin = std::move(ArchiveOrErr.get()); @@ -593,26 +590,28 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive(StringRef Ar Bin = CachedBin->getBinary(); } - if (!Bin || !isa(Bin)) + object::Archive *Archive = dyn_cast_if_present(Bin); + if (!Archive) return errorCodeToError(object_error::invalid_file_type); - object::Archive *Archive = cast(Bin); Error Err = Error::success(); - // On AIX, archives can contain multiple members with same name but different types - // We need to check all matches and find one that matches both name and architecture + // On AIX, archives can contain multiple members with same name but different + // types. We need to check all matches and find one that matches both name and + // architecture. for (auto &Child : Archive->children(Err, /*SkipInternal=*/true)) { Expected NameOrErr = Child.getName(); if (!NameOrErr) - continue; - if (*NameOrErr == llvm::sys::path::filename(MemberName)) { - Expected> MemberOrErr = Child.getAsBinary(); + continue; + if (*NameOrErr == sys::path::filename(MemberName)) { + Expected> MemberOrErr = + Child.getAsBinary(); if (!MemberOrErr) - continue; + continue; std::unique_ptr Binary = std::move(*MemberOrErr); if (auto *Obj = dyn_cast(Binary.get())) { -#if defined(_AIX) +#ifdef _AIX Triple::ArchType ObjArch = Obj->makeTriple().getArch(); Triple RequestedTriple; RequestedTriple.setArch(Triple::getArchTypeForLLVMName(ArchName)); @@ -625,11 +624,13 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive(StringRef Ar return I->second.get(); auto CachedObj = std::unique_ptr(Obj); - auto NewEntry = ObjectForArchivePathAndArch.emplace( - CacheKey, std::move(CachedObj)); + auto NewEntry = + ObjectForArchivePathAndArch.emplace(CacheKey, std::move(CachedObj)); Binary.release(); - BinaryForPath.find(ArchivePath.str())->second.pushEvictor( - [this, Iter = NewEntry.first]() { ObjectForArchivePathAndArch.erase(Iter); }); + BinaryForPath.find(ArchivePath.str()) + ->second.pushEvictor([this, Iter = NewEntry.first]() { + ObjectForArchivePathAndArch.erase(Iter); + }); return NewEntry.first->second.get(); } } @@ -642,13 +643,15 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive(StringRef Ar Expected LLVMSymbolizer::getOrCreateObject(const std::string &Path, const std::string &ArchName) { - // First check for archive(member) format - more efficient to check closing paren first + // First check for archive(member) format - more efficient to check closing + // paren first. size_t CloseParen = Path.rfind(')'); if (CloseParen != std::string::npos && CloseParen == Path.length() - 1) { size_t OpenParen = Path.rfind('(', CloseParen); if (OpenParen != std::string::npos) { StringRef ArchivePath = StringRef(Path).substr(0, OpenParen); - StringRef MemberName = StringRef(Path).substr(OpenParen + 1, CloseParen - OpenParen - 1); + StringRef MemberName = + StringRef(Path).substr(OpenParen + 1, CloseParen - OpenParen - 1); return getOrCreateObjectFromArchive(ArchivePath, MemberName, ArchName); } } @@ -803,10 +806,8 @@ LLVMSymbolizer::getOrCreateModuleInfo(StringRef ModuleName) { if (ModuleOrErr) { auto I = Modules.find(ModuleName); auto BinIter = BinaryForPath.find(BinaryName); - if (BinIter != BinaryForPath.end()) - BinIter->second.pushEvictor([this, I]() { - Modules.erase(I); - }); + if (BinIter != BinaryForPath.end()) + BinIter->second.pushEvictor([this, I]() { Modules.erase(I); }); } return ModuleOrErr; } diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 87442f633548d..f92e3140c5e70 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -1,5 +1,4 @@ // Test archive member recognition by name (ELF format) -// UNSUPPORTED: target={{.*}}-aix{{.*}} // Generate object files from YAML // RUN: yaml2obj -o %t-1.o %S/Inputs/big-archive-elf-1.yaml @@ -9,14 +8,11 @@ // RUN: rm -f %t.a // RUN: llvm-ar crv %t.a %t-1.o %t-2.o -// Verify archive contents -// RUN: llvm-ar tv %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE -// CHECK-ARCHIVE: {{.*}}-1.o -// CHECK-ARCHIVE: {{.*}}-2.o - // Test symbolization by member name (using just base names) -// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t-1.o)" 0x0 | FileCheck %s --check-prefix=CHECK-1 -// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 +// RUN: MEMBER1=$(basename %t-1.o) +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a($MEMBER1)" 0x0 | FileCheck %s --check-prefix=CHECK-1 +// RUN: MEMBER2=$(basename %t-2.o) +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a($MEMBER2)" 0x0 | FileCheck %s --check-prefix=CHECK-2 // CHECK-1: foo1 // CHECK-2: foo2 diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index f034520638267..fdace7510d4e1 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -1,5 +1,4 @@ // Test big archive recognition and error handling in llvm-symbolizer -// REQUIRES: system-aix, target={{.*}}-aix{{.*}} // Generate object files // RUN: yaml2obj -o %t-32.o %S/Inputs/big-archive-32.yaml @@ -7,21 +6,38 @@ // Create archive with same-named members using different modes // RUN: rm -f %t.a -// RUN: cp %t-32.o %t.o && llvm-ar -X32 crv %t.a %t.o -// RUN: cp %t-64.o %t.o && llvm-ar -X64 qv %t.a %t.o - +// RUN: cp %t-32.o %t.o +// RUN: if [ "$(uname)" = "AIX" ]; then \ + llvm-ar -X32 crv %t.a %t.o; \ + else \ + llvm-ar crv %t.a %t.o; \ + fi +// RUN: cp %t-64.o %t.o +// RUN: if [ "$(uname)" = "AIX" ]; then \ + llvm-ar -X64 rv %t.a %t.o; \ + else \ + llvm-ar qv %t.a %t.o; \ + fi + + // Verify archive contains two members with same name -// RUN: llvm-ar tv -X32_64 %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE +// RUN: if [ "$(uname)" = "AIX" ]; then \ + llvm-ar tv -X32_64 %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE; \ + else \ + llvm-ar tv %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE; \ + fi // CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} // CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} // Test successful symbolization -// RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-32 -// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 +// RUN: MEMBER=$(basename %t.o) +// RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a($MEMBER)" 0x0 | FileCheck %s --check-prefix=CHECK-32 +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a($MEMBER)" 0x0 | FileCheck %s --check-prefix=CHECK-64 +// RUN: llvm-symbolizer --obj="%t.a($MEMBER):ppc" 0x0 | FileCheck %s --check-prefix=CHECK-32 +// RUN: llvm-symbolizer --obj="%t.a($MEMBER):ppc64" 0x0 | FileCheck %s --check-prefix=CHECK-64 // CHECK-32: foo // CHECK-64: foo // Test error cases // RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR - // CHECK-ERROR: error: {{.*}}No object file for requested architecture From 647f98ebe074e45ca0c93b486d08c212bc7b549a Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Fri, 1 Aug 2025 12:28:52 +0530 Subject: [PATCH 06/25] review comments addressed --- .../llvm/DebugInfo/Symbolize/Symbolize.h | 14 ++++---------- .../DebugInfo/symbolize-big-archive-elf.test | 6 ++++-- .../symbolize-big-archive-xcoff.test | 19 +++---------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 99297cebd5c89..6cebd91ecbbd5 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -29,12 +29,6 @@ #include #include -#ifdef _AIX -#define SYMBOLIZE_AIX 1 -#else -#define SYMBOLIZE_AIX 0 -#endif - namespace llvm { namespace object { class ELFObjectFileBase; @@ -210,9 +204,9 @@ class LLVMSymbolizer { /// Return a pointer to object file at specified path, for a specified /// architecture that is present inside an archive file - Expected - getOrCreateObjectFromArchive(StringRef ArchivePath, StringRef MemberName, - StringRef ArchName); + Expected getOrCreateObjectFromArchive(StringRef ArchivePath, + StringRef MemberName, + StringRef ArchName); /// Update the LRU cache order when a binary is accessed. void recordAccess(CachedBinary &Bin); @@ -252,7 +246,7 @@ class LLVMSymbolizer { std::map> ObjectForArchivePathAndArch; - + Options Opts; std::unique_ptr BIDFetcher; diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index f92e3140c5e70..3290a0684c568 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -10,9 +10,11 @@ // Test symbolization by member name (using just base names) // RUN: MEMBER1=$(basename %t-1.o) -// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a($MEMBER1)" 0x0 | FileCheck %s --check-prefix=CHECK-1 +// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a($MEMBER1)" 0x0 | FileCheck %s --check-prefix=CHECK-1 +// RUN: llvm-symbolizer --obj="%t.a($MEMBER1):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-1 // RUN: MEMBER2=$(basename %t-2.o) -// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a($MEMBER2)" 0x0 | FileCheck %s --check-prefix=CHECK-2 +// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a($MEMBER2)" 0x0 | FileCheck %s --check-prefix=CHECK-2 +// RUN: llvm-symbolizer --obj="%t.a($MEMBER2):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-2 // CHECK-1: foo1 // CHECK-2: foo2 diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index fdace7510d4e1..522a20f531774 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -7,25 +7,12 @@ // Create archive with same-named members using different modes // RUN: rm -f %t.a // RUN: cp %t-32.o %t.o -// RUN: if [ "$(uname)" = "AIX" ]; then \ - llvm-ar -X32 crv %t.a %t.o; \ - else \ - llvm-ar crv %t.a %t.o; \ - fi +// RUN: llvm-ar %if system-aix %{-X32%} crv %t.a %t.o // RUN: cp %t-64.o %t.o -// RUN: if [ "$(uname)" = "AIX" ]; then \ - llvm-ar -X64 rv %t.a %t.o; \ - else \ - llvm-ar qv %t.a %t.o; \ - fi - +// RUN: llvm-ar %if system-aix %{-X64 rv%} %else %{qv%} %t.a %t.o // Verify archive contains two members with same name -// RUN: if [ "$(uname)" = "AIX" ]; then \ - llvm-ar tv -X32_64 %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE; \ - else \ - llvm-ar tv %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE; \ - fi +// RUN: llvm-ar tv %if system-aix %{-X32_64%} %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE // CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} // CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} From 629e7a503fca06551e64357dda7b2f12de15e219 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Fri, 1 Aug 2025 12:29:39 +0530 Subject: [PATCH 07/25] review comments addressed --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 74990347d4b5d..94d76ace9434f 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -595,9 +595,9 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( return errorCodeToError(object_error::invalid_file_type); Error Err = Error::success(); - + // On AIX, archives can contain multiple members with same name but different - // types. We need to check all matches and find one that matches both name and + // types. We need to check all matches and find one that matches both name and // architecture. for (auto &Child : Archive->children(Err, /*SkipInternal=*/true)) { Expected NameOrErr = Child.getName(); @@ -608,17 +608,15 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( Child.getAsBinary(); if (!MemberOrErr) continue; - + std::unique_ptr Binary = std::move(*MemberOrErr); if (auto *Obj = dyn_cast(Binary.get())) { -#ifdef _AIX Triple::ArchType ObjArch = Obj->makeTriple().getArch(); Triple RequestedTriple; RequestedTriple.setArch(Triple::getArchTypeForLLVMName(ArchName)); if (ObjArch != RequestedTriple.getArch()) continue; -#endif - ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), ArchName}; + ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), ArchName.str()}; auto I = ObjectForArchivePathAndArch.find(CacheKey); if (I != ObjectForArchivePathAndArch.end()) return I->second.get(); From 9c14b3875132941c8d73c54f0fee1e1619144406 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Fri, 1 Aug 2025 12:47:45 +0530 Subject: [PATCH 08/25] format correction --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 94d76ace9434f..a356edaa722ae 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -616,7 +616,8 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( RequestedTriple.setArch(Triple::getArchTypeForLLVMName(ArchName)); if (ObjArch != RequestedTriple.getArch()) continue; - ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), ArchName.str()}; + ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), + ArchName.str()}; auto I = ObjectForArchivePathAndArch.find(CacheKey); if (I != ObjectForArchivePathAndArch.end()) return I->second.get(); From f8aeb3e78a52c2b4c8f4c5face7df5173321c9c3 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Fri, 1 Aug 2025 16:31:36 +0530 Subject: [PATCH 09/25] added test support --- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 1 + llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 1 + 2 files changed, 2 insertions(+) diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 3290a0684c568..66c59b45c8a76 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -1,4 +1,5 @@ // Test archive member recognition by name (ELF format) +// REQUIRES: system-linux || system-aix // Generate object files from YAML // RUN: yaml2obj -o %t-1.o %S/Inputs/big-archive-elf-1.yaml diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index 522a20f531774..e8f6a5f790ffc 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -1,4 +1,5 @@ // Test big archive recognition and error handling in llvm-symbolizer +// REQUIRES: system-linux || system-aix // Generate object files // RUN: yaml2obj -o %t-32.o %S/Inputs/big-archive-32.yaml From 0952fcf2d8a6ca133fcf6594f7bb935e824fccc3 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Tue, 12 Aug 2025 15:47:42 +0530 Subject: [PATCH 10/25] refactor of code to remove duplicates --- llvm/docs/CommandGuide/llvm-symbolizer.rst | 2 +- .../llvm/DebugInfo/Symbolize/Symbolize.h | 32 ++-- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 175 ++++++++++-------- .../DebugInfo/symbolize-big-archive-elf.test | 2 +- .../symbolize-big-archive-xcoff.test | 2 +- 5 files changed, 118 insertions(+), 95 deletions(-) diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst index 7a33d538269fd..a38f6415272d9 100644 --- a/llvm/docs/CommandGuide/llvm-symbolizer.rst +++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst @@ -539,7 +539,7 @@ MACH-O SPECIFIC OPTIONS symbolize the object file for a given architecture. You can also specify the architecture by writing ``binary_name:arch_name`` in the input (see example below). For AIX archives, the format ``archive.a(member.o):arch`` - is also supported. If the architecture is not specified in either way, + is also supported. If the architecture is not specified, the address will not be symbolized. Defaults to empty string. .. code-block:: console diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 6cebd91ecbbd5..64164d4189a21 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -196,14 +196,14 @@ class LLVMSymbolizer { Expected getOrCreateObjectPair(const std::string &Path, const std::string &ArchName); - /// Return a pointer to object file at specified path, for a specified + /// Return a pointer to the object file at specified path, for a specified /// architecture (e.g. if path refers to a Mach-O universal binary, only one /// object file from it will be returned). Expected getOrCreateObject(const std::string &InputPath, const std::string &DefaultArchName); - /// Return a pointer to object file at specified path, for a specified - /// architecture that is present inside an archive file + /// Return a pointer to the object file at specified path, for a specified + /// architecture that is present inside an archive file. Expected getOrCreateObjectFromArchive(StringRef ArchivePath, StringRef MemberName, StringRef ArchName); @@ -227,25 +227,31 @@ class LLVMSymbolizer { /// Sum of the sizes of the cached binaries. size_t CacheSize = 0; - /// Parsed object file for path/architecture pair, where "path" refers - /// to Mach-O universal binary. - std::map, std::unique_ptr> - ObjectForUBPathAndArch; - struct ArchiveCacheKey { - std::string ArchivePath; // Storage for StringRef - std::string MemberName; // Storage for StringRef - std::string ArchName; // Storage for StringRef + std::string ArchivePath; + std::string MemberName; + std::string ArchName; - // Required for map comparison + // Required for map comparison. bool operator<(const ArchiveCacheKey &Other) const { return std::tie(ArchivePath, MemberName, ArchName) < std::tie(Other.ArchivePath, Other.MemberName, Other.ArchName); } }; + /// Parsed object file for path/architecture pair, where "path" refers + /// to Mach-O universal binary. std::map> - ObjectForArchivePathAndArch; + ObjectFileCache; + + /// Helper function to load binary. + object::Binary *loadOrGetBinary(const std::string &Path); + + /// Helper function to find and get object + Expected findOrCacheObject( + const ArchiveCacheKey &Key, + llvm::function_ref>()> Loader, + const std::string &PathForBinaryCache); Options Opts; diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index a356edaa722ae..663709ac11ae6 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -286,8 +286,7 @@ LLVMSymbolizer::findSymbol(ArrayRef BuildID, StringRef Symbol, } void LLVMSymbolizer::flush() { - ObjectForUBPathAndArch.clear(); - ObjectForArchivePathAndArch.clear(); + ObjectFileCache.clear(); LRUBinaries.clear(); CacheSize = 0; BinaryForPath.clear(); @@ -438,13 +437,13 @@ bool LLVMSymbolizer::findDebugBinary(const std::string &OrigPath, SmallString<16> OrigDir(OrigPath); llvm::sys::path::remove_filename(OrigDir); SmallString<16> DebugPath = OrigDir; - // Try relative/path/to/original_binary/debuglink_name + // Try relative/path/to/original_binary/debuglink_name. llvm::sys::path::append(DebugPath, DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { Result = std::string(DebugPath); return true; } - // Try relative/path/to/original_binary/.debug/debuglink_name + // Try relative/path/to/original_binary/.debug/debuglink_name. DebugPath = OrigDir; llvm::sys::path::append(DebugPath, ".debug", DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { @@ -453,17 +452,17 @@ bool LLVMSymbolizer::findDebugBinary(const std::string &OrigPath, } // Make the path absolute so that lookups will go to // "/usr/lib/debug/full/path/to/debug", not - // "/usr/lib/debug/to/debug" + // "/usr/lib/debug/to/debug". llvm::sys::fs::make_absolute(OrigDir); if (!Opts.FallbackDebugPath.empty()) { - // Try /absolute/path/to/original_binary/debuglink_name + // Try /absolute/path/to/original_binary/debuglink_name. DebugPath = Opts.FallbackDebugPath; } else { #if defined(__NetBSD__) - // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name + // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name. DebugPath = "/usr/libdata/debug"; #else - // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name + // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name. DebugPath = "/usr/lib/debug"; #endif } @@ -512,11 +511,11 @@ std::string LLVMSymbolizer::lookUpGsymFile(const std::string &Path) { return !EC && !llvm::sys::fs::is_directory(Status); }; - // First, look beside the binary file + // First, look beside the binary file. if (const auto GsymPath = Path + ".gsym"; CheckGsymFile(GsymPath)) return GsymPath; - // Then, look in the directories specified by GsymFileDirectory + // Then, look in the directories specified by GsymFileDirectory. for (const auto &Directory : Opts.GsymFileDirectory) { SmallString<16> GsymPath = llvm::StringRef{Directory}; @@ -555,7 +554,15 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, else if (auto ELFObj = dyn_cast(Obj)) DbgObj = lookUpBuildIDObject(Path, ELFObj, ArchName); if (!DbgObj) + { + llvm::outs() << "Path: " << Path << "\n"; + if (Obj) + llvm::outs() << "Obj pointer: " << Obj << "\n"; + else + llvm::outs() << "Obj is null!\n"; + llvm::outs() << "ArchName: " << ArchName << "\n"; DbgObj = lookUpDebuglinkObject(Path, Obj, ArchName); + } if (!DbgObj) DbgObj = Obj; ObjectPair Res = std::make_pair(Obj, DbgObj); @@ -570,33 +577,69 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, return Res; } -Expected LLVMSymbolizer::getOrCreateObjectFromArchive( - StringRef ArchivePath, StringRef MemberName, StringRef ArchName) { - Binary *Bin = nullptr; - auto Pair = BinaryForPath.emplace(ArchivePath.str(), OwningBinary()); +object::Binary *LLVMSymbolizer::loadOrGetBinary(const std::string &Path) { + auto Pair = BinaryForPath.emplace(Path, OwningBinary()); if (!Pair.second) { - Bin = Pair.first->second->getBinary(); recordAccess(Pair.first->second); - } else { - Expected> ArchiveOrErr = createBinary(ArchivePath); - if (!ArchiveOrErr) - return ArchiveOrErr.takeError(); + return Pair.first->second->getBinary(); + } + + Expected> BinOrErr = createBinary(Path); + if (!BinOrErr) { + BinaryForPath.erase(Pair.first); + consumeError(BinOrErr.takeError()); + return nullptr; + } + + CachedBinary &CachedBin = Pair.first->second; + CachedBin = std::move(*BinOrErr); + CachedBin.pushEvictor([this, I = Pair.first]() { BinaryForPath.erase(I); }); + LRUBinaries.push_back(CachedBin); + CacheSize += CachedBin.size(); + return CachedBin->getBinary(); +} + +Expected LLVMSymbolizer::findOrCacheObject( + const ArchiveCacheKey &Key, + llvm::function_ref>()> Loader, + const std::string &PathForBinaryCache) { + + auto It = ObjectFileCache.find(Key); + if (It != ObjectFileCache.end()) + return It->second.get(); - CachedBinary &CachedBin = Pair.first->second; - CachedBin = std::move(ArchiveOrErr.get()); - CachedBin.pushEvictor([this, I = Pair.first]() { BinaryForPath.erase(I); }); - LRUBinaries.push_back(CachedBin); - CacheSize += CachedBin.size(); - Bin = CachedBin->getBinary(); + Expected> ObjOrErr = Loader(); + if (!ObjOrErr) { + ObjectFileCache.emplace(Key, std::unique_ptr()); + return ObjOrErr.takeError(); } + ObjectFile *Res = ObjOrErr->get(); + auto NewEntry = ObjectFileCache.emplace(Key, std::move(*ObjOrErr)); + auto CacheIter = BinaryForPath.find(PathForBinaryCache); + if (CacheIter != BinaryForPath.end()) + CacheIter->second.pushEvictor([this, Iter = NewEntry.first]() { + ObjectFileCache.erase(Iter); + }); + return Res; +} + +Expected LLVMSymbolizer::getOrCreateObjectFromArchive( + StringRef ArchivePath, StringRef MemberName, StringRef ArchName) { + Binary *Bin = loadOrGetBinary(ArchivePath.str()); + if (!Bin) + return createStringError(std::errc::invalid_argument, + "Failed to load archive '%s'", + ArchivePath.str().c_str()); + object::Archive *Archive = dyn_cast_if_present(Bin); if (!Archive) - return errorCodeToError(object_error::invalid_file_type); + return createStringError(std::errc::invalid_argument, + "'%s' is not a valid archive", + ArchivePath.str().c_str()); Error Err = Error::success(); - - // On AIX, archives can contain multiple members with same name but different + // On AIX, archives can contain multiple members with the same name but different // types. We need to check all matches and find one that matches both name and // architecture. for (auto &Child : Archive->children(Err, /*SkipInternal=*/true)) { @@ -616,27 +659,27 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( RequestedTriple.setArch(Triple::getArchTypeForLLVMName(ArchName)); if (ObjArch != RequestedTriple.getArch()) continue; + ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), ArchName.str()}; - auto I = ObjectForArchivePathAndArch.find(CacheKey); - if (I != ObjectForArchivePathAndArch.end()) - return I->second.get(); - - auto CachedObj = std::unique_ptr(Obj); - auto NewEntry = - ObjectForArchivePathAndArch.emplace(CacheKey, std::move(CachedObj)); + Expected Res = findOrCacheObject( + CacheKey, + [O = std::unique_ptr(Obj)]() + mutable -> Expected> { + return std::move(O); + }, + ArchivePath.str()); Binary.release(); - BinaryForPath.find(ArchivePath.str()) - ->second.pushEvictor([this, Iter = NewEntry.first]() { - ObjectForArchivePathAndArch.erase(Iter); - }); - return NewEntry.first->second.get(); + return Res; } } } if (Err) return std::move(Err); - return errorCodeToError(object_error::arch_not_found); + return createStringError(std::errc::invalid_argument, + "No matching member '%s' with arch '%s' in '%s'", + MemberName.str().c_str(), ArchName.str().c_str(), + ArchivePath.str().c_str()); } Expected @@ -655,45 +698,19 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, } } - Binary *Bin = nullptr; - auto Pair = BinaryForPath.emplace(Path, OwningBinary()); - if (!Pair.second) { - Bin = Pair.first->second->getBinary(); - recordAccess(Pair.first->second); - } else { - Expected> BinOrErr = createBinary(Path); - if (!BinOrErr) - return BinOrErr.takeError(); - - CachedBinary &CachedBin = Pair.first->second; - CachedBin = std::move(BinOrErr.get()); - CachedBin.pushEvictor([this, I = Pair.first]() { BinaryForPath.erase(I); }); - LRUBinaries.push_back(CachedBin); - CacheSize += CachedBin.size(); - Bin = CachedBin->getBinary(); - } - + Binary *Bin = loadOrGetBinary(Path); if (!Bin) - return static_cast(nullptr); + return createStringError(std::errc::invalid_argument, + "Failed to load object '%s'", Path.c_str()); if (MachOUniversalBinary *UB = dyn_cast_or_null(Bin)) { - auto I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName)); - if (I != ObjectForUBPathAndArch.end()) - return I->second.get(); - - Expected> ObjOrErr = - UB->getMachOObjectForArch(ArchName); - if (!ObjOrErr) { - ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName), - std::unique_ptr()); - return ObjOrErr.takeError(); - } - ObjectFile *Res = ObjOrErr->get(); - auto Pair = ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName), - std::move(ObjOrErr.get())); - BinaryForPath.find(Path)->second.pushEvictor( - [this, Iter = Pair.first]() { ObjectForUBPathAndArch.erase(Iter); }); - return Res; + ArchiveCacheKey CacheKey{Path, "", ArchName}; + return findOrCacheObject( + CacheKey, + [UB, ArchName]() -> Expected> { + return UB->getMachOObjectForArch(ArchName); + }, + Path); } if (Bin->isObject()) { return cast(Bin); @@ -789,7 +806,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(StringRef ModuleName) { if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(), Session)) { Modules.emplace(ModuleName, std::unique_ptr()); - // Return along the PDB filename to provide more context + // Return along the PDB filename to provide more context. return createFileError(PDBFileName, std::move(Err)); } Context.reset(new PDBContext(*CoffObject, std::move(Session))); @@ -830,7 +847,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const ObjectFile &Obj) { Context = BTFContext::create(Obj); else Context = DWARFContext::create(Obj); - // FIXME: handle COFF object with PDB info to use PDBContext + // FIXME: handle COFF object with PDB info to use PDBContext. return createModuleInfo(&Obj, std::move(Context), ObjName); } diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 66c59b45c8a76..2306a27e61f0c 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -21,4 +21,4 @@ // Test error cases // RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -// CHECK-ERROR: error: {{.*}}No object file for requested architecture +// CHECK-ERROR: error: {{.*}}No matching member{{.*}} diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index e8f6a5f790ffc..51b9381ff0318 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -28,4 +28,4 @@ // Test error cases // RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -// CHECK-ERROR: error: {{.*}}No object file for requested architecture +// CHECK-ERROR: error: {{.*}}No matching member{{.*}} From 12dd6e55b7ecf50bcdedfbe5776589ad7e35c38f Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Tue, 12 Aug 2025 16:03:16 +0530 Subject: [PATCH 11/25] code formatting --- .../llvm/DebugInfo/Symbolize/Symbolize.h | 13 ++++---- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 31 +++++++------------ 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 64164d4189a21..5bc139543a427 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -239,19 +239,18 @@ class LLVMSymbolizer { } }; - /// Parsed object file for path/architecture pair, where "path" refers - /// to Mach-O universal binary. - std::map> - ObjectFileCache; + /// Parsed object file for path/object/architecture pair, where + /// "path" refers to Mach-O universal binary. + std::map> ObjectFileCache; /// Helper function to load binary. object::Binary *loadOrGetBinary(const std::string &Path); /// Helper function to find and get object Expected findOrCacheObject( - const ArchiveCacheKey &Key, - llvm::function_ref>()> Loader, - const std::string &PathForBinaryCache); + const ArchiveCacheKey &Key, + llvm::function_ref>()> Loader, + const std::string &PathForBinaryCache); Options Opts; diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 663709ac11ae6..8b3dd84076d1c 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -554,15 +554,7 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, else if (auto ELFObj = dyn_cast(Obj)) DbgObj = lookUpBuildIDObject(Path, ELFObj, ArchName); if (!DbgObj) - { - llvm::outs() << "Path: " << Path << "\n"; - if (Obj) - llvm::outs() << "Obj pointer: " << Obj << "\n"; - else - llvm::outs() << "Obj is null!\n"; - llvm::outs() << "ArchName: " << ArchName << "\n"; DbgObj = lookUpDebuglinkObject(Path, Obj, ArchName); - } if (!DbgObj) DbgObj = Obj; ObjectPair Res = std::make_pair(Obj, DbgObj); @@ -618,9 +610,8 @@ Expected LLVMSymbolizer::findOrCacheObject( auto NewEntry = ObjectFileCache.emplace(Key, std::move(*ObjOrErr)); auto CacheIter = BinaryForPath.find(PathForBinaryCache); if (CacheIter != BinaryForPath.end()) - CacheIter->second.pushEvictor([this, Iter = NewEntry.first]() { - ObjectFileCache.erase(Iter); - }); + CacheIter->second.pushEvictor( + [this, Iter = NewEntry.first]() { ObjectFileCache.erase(Iter); }); return Res; } @@ -639,9 +630,9 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( ArchivePath.str().c_str()); Error Err = Error::success(); - // On AIX, archives can contain multiple members with the same name but different - // types. We need to check all matches and find one that matches both name and - // architecture. + // On AIX, archives can contain multiple members with the same name but + // different types. We need to check all matches and find one that matches + // both name and architecture. for (auto &Child : Archive->children(Err, /*SkipInternal=*/true)) { Expected NameOrErr = Child.getName(); if (!NameOrErr) @@ -663,12 +654,12 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( ArchiveCacheKey CacheKey{ArchivePath.str(), MemberName.str(), ArchName.str()}; Expected Res = findOrCacheObject( - CacheKey, - [O = std::unique_ptr(Obj)]() - mutable -> Expected> { - return std::move(O); - }, - ArchivePath.str()); + CacheKey, + [O = std::unique_ptr(Obj)]() + mutable -> Expected> { + return std::move(O); + }, + ArchivePath.str()); Binary.release(); return Res; } From 68b886f33a9b96b5f51e769eb00f23b3398f5c61 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Tue, 12 Aug 2025 16:09:27 +0530 Subject: [PATCH 12/25] code formatting --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 8b3dd84076d1c..4e09aa10f0152 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -655,9 +655,9 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( ArchName.str()}; Expected Res = findOrCacheObject( CacheKey, - [O = std::unique_ptr(Obj)]() - mutable -> Expected> { - return std::move(O); + [O = std::unique_ptr( + Obj)]() mutable -> Expected> { + return std::move(O); }, ArchivePath.str()); Binary.release(); From d0f0a1d03b2913914c6b6a06fbf8fe185fc3c7db Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Wed, 13 Aug 2025 02:15:35 +0530 Subject: [PATCH 13/25] test fail fix --- .../llvm/DebugInfo/Symbolize/Symbolize.h | 2 +- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 5bc139543a427..18b48c5d3383e 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -244,7 +244,7 @@ class LLVMSymbolizer { std::map> ObjectFileCache; /// Helper function to load binary. - object::Binary *loadOrGetBinary(const std::string &Path); + Expected loadOrGetBinary(const std::string &Path); /// Helper function to find and get object Expected findOrCacheObject( diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 4e09aa10f0152..1da4c37fc37b2 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -569,7 +569,7 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, return Res; } -object::Binary *LLVMSymbolizer::loadOrGetBinary(const std::string &Path) { +Expected LLVMSymbolizer::loadOrGetBinary(const std::string &Path) { auto Pair = BinaryForPath.emplace(Path, OwningBinary()); if (!Pair.second) { recordAccess(Pair.first->second); @@ -579,8 +579,7 @@ object::Binary *LLVMSymbolizer::loadOrGetBinary(const std::string &Path) { Expected> BinOrErr = createBinary(Path); if (!BinOrErr) { BinaryForPath.erase(Pair.first); - consumeError(BinOrErr.takeError()); - return nullptr; + return BinOrErr.takeError(); } CachedBinary &CachedBin = Pair.first->second; @@ -617,11 +616,10 @@ Expected LLVMSymbolizer::findOrCacheObject( Expected LLVMSymbolizer::getOrCreateObjectFromArchive( StringRef ArchivePath, StringRef MemberName, StringRef ArchName) { - Binary *Bin = loadOrGetBinary(ArchivePath.str()); - if (!Bin) - return createStringError(std::errc::invalid_argument, - "Failed to load archive '%s'", - ArchivePath.str().c_str()); + Expected BinOrErr = loadOrGetBinary(ArchivePath.str()); + if (!BinOrErr) + return BinOrErr.takeError(); + object::Binary *Bin = *BinOrErr; object::Archive *Archive = dyn_cast_if_present(Bin); if (!Archive) @@ -689,10 +687,10 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, } } - Binary *Bin = loadOrGetBinary(Path); - if (!Bin) - return createStringError(std::errc::invalid_argument, - "Failed to load object '%s'", Path.c_str()); + Expected BinOrErr = loadOrGetBinary(Path); + if (!BinOrErr) + return BinOrErr.takeError(); + object::Binary *Bin = *BinOrErr; if (MachOUniversalBinary *UB = dyn_cast_or_null(Bin)) { ArchiveCacheKey CacheKey{Path, "", ArchName}; From fe5a9c23aba4ea15d04d48c399c601ebd3b20a9b Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Wed, 13 Aug 2025 02:39:06 +0530 Subject: [PATCH 14/25] code formatting --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h | 2 +- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 18b48c5d3383e..5845f4dd438eb 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -244,7 +244,7 @@ class LLVMSymbolizer { std::map> ObjectFileCache; /// Helper function to load binary. - Expected loadOrGetBinary(const std::string &Path); + Expected loadOrGetBinary(const std::string &Path); /// Helper function to find and get object Expected findOrCacheObject( diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 1da4c37fc37b2..d915ea76a6a99 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -569,7 +569,8 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, return Res; } -Expected LLVMSymbolizer::loadOrGetBinary(const std::string &Path) { +Expected +LLVMSymbolizer::loadOrGetBinary(const std::string &Path) { auto Pair = BinaryForPath.emplace(Path, OwningBinary()); if (!Pair.second) { recordAccess(Pair.first->second); @@ -616,7 +617,7 @@ Expected LLVMSymbolizer::findOrCacheObject( Expected LLVMSymbolizer::getOrCreateObjectFromArchive( StringRef ArchivePath, StringRef MemberName, StringRef ArchName) { - Expected BinOrErr = loadOrGetBinary(ArchivePath.str()); + Expected BinOrErr = loadOrGetBinary(ArchivePath.str()); if (!BinOrErr) return BinOrErr.takeError(); object::Binary *Bin = *BinOrErr; @@ -687,7 +688,7 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, } } - Expected BinOrErr = loadOrGetBinary(Path); + Expected BinOrErr = loadOrGetBinary(Path); if (!BinOrErr) return BinOrErr.takeError(); object::Binary *Bin = *BinOrErr; From e2083eb2b5cbc297d8a07560c6370fb49ccd587a Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Thu, 14 Aug 2025 12:05:22 +0530 Subject: [PATCH 15/25] make tests available on other platforms --- llvm/docs/CommandGuide/llvm-symbolizer.rst | 4 ++-- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 1 - llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst index a9c2494cb1009..b665a28d266ec 100644 --- a/llvm/docs/CommandGuide/llvm-symbolizer.rst +++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst @@ -547,8 +547,8 @@ MACH-O SPECIFIC OPTIONS $ cat addr.txt /tmp/mach_universal_binary:i386 0x1f84 /tmp/mach_universal_binary:x86_64 0x100000f24 - /tmp/big-archive.a(member.o):ppc 0x1000 - /tmp/big-archive.a(member.o):ppc64 0x2000 + /tmp/archive.a(member.o):ppc 0x1000 + /tmp/archive.a(member.o):ppc64 0x2000 $ llvm-symbolizer < addr.txt _main diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 2306a27e61f0c..a7e7683d62c2c 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -1,5 +1,4 @@ // Test archive member recognition by name (ELF format) -// REQUIRES: system-linux || system-aix // Generate object files from YAML // RUN: yaml2obj -o %t-1.o %S/Inputs/big-archive-elf-1.yaml diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index 51b9381ff0318..e3cd1215ec078 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -1,5 +1,4 @@ // Test big archive recognition and error handling in llvm-symbolizer -// REQUIRES: system-linux || system-aix // Generate object files // RUN: yaml2obj -o %t-32.o %S/Inputs/big-archive-32.yaml From 0595460d94041871ec410eab1edc77dac6bc5ed6 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Mon, 18 Aug 2025 12:24:13 +0530 Subject: [PATCH 16/25] test changes for windows --- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 10 ++++------ llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 9 ++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index a7e7683d62c2c..2c772f3e3a4fb 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -9,12 +9,10 @@ // RUN: llvm-ar crv %t.a %t-1.o %t-2.o // Test symbolization by member name (using just base names) -// RUN: MEMBER1=$(basename %t-1.o) -// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a($MEMBER1)" 0x0 | FileCheck %s --check-prefix=CHECK-1 -// RUN: llvm-symbolizer --obj="%t.a($MEMBER1):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-1 -// RUN: MEMBER2=$(basename %t-2.o) -// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a($MEMBER2)" 0x0 | FileCheck %s --check-prefix=CHECK-2 -// RUN: llvm-symbolizer --obj="%t.a($MEMBER2):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-2 +// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%{t:stem}.tmp-1.o)" 0x0 | FileCheck %s --check-prefix=CHECK-1 +// RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp-1.o):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-1 +// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%{t:stem}.tmp-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 +// RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp-2.o):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-2 // CHECK-1: foo1 // CHECK-2: foo2 diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index e3cd1215ec078..258dfe51bf3c1 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -17,11 +17,10 @@ // CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} // Test successful symbolization -// RUN: MEMBER=$(basename %t.o) -// RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a($MEMBER)" 0x0 | FileCheck %s --check-prefix=CHECK-32 -// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a($MEMBER)" 0x0 | FileCheck %s --check-prefix=CHECK-64 -// RUN: llvm-symbolizer --obj="%t.a($MEMBER):ppc" 0x0 | FileCheck %s --check-prefix=CHECK-32 -// RUN: llvm-symbolizer --obj="%t.a($MEMBER):ppc64" 0x0 | FileCheck %s --check-prefix=CHECK-64 +// RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a(%{t:stem}.tmp.o)" 0x0 | FileCheck %s --check-prefix=CHECK-32 +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%{t:stem}.tmp.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 +// RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp.o):ppc" 0x0 | FileCheck %s --check-prefix=CHECK-32 +// RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp.o):ppc64" 0x0 | FileCheck %s --check-prefix=CHECK-64 // CHECK-32: foo // CHECK-64: foo From b37409ba00c682c88e5b988de5bda6af761c1bf5 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Thu, 21 Aug 2025 11:36:02 +0530 Subject: [PATCH 17/25] fix review comments --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h | 2 +- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 2 +- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 4 +++- llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 4 +++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 5845f4dd438eb..63da5d9d57423 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -246,7 +246,7 @@ class LLVMSymbolizer { /// Helper function to load binary. Expected loadOrGetBinary(const std::string &Path); - /// Helper function to find and get object + /// Helper function to find and get object. Expected findOrCacheObject( const ArchiveCacheKey &Key, llvm::function_ref>()> Loader, diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index d915ea76a6a99..570262816e27f 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -667,7 +667,7 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( if (Err) return std::move(Err); return createStringError(std::errc::invalid_argument, - "No matching member '%s' with arch '%s' in '%s'", + "no matching member '%s' with arch '%s' in '%s'", MemberName.str().c_str(), ArchName.str().c_str(), ArchivePath.str().c_str()); } diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 2c772f3e3a4fb..242a0e89bfd8c 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -18,4 +18,6 @@ // Test error cases // RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -// CHECK-ERROR: error: {{.*}}No matching member{{.*}} +// CHECK-ERROR: error: {{.*}}no matching member{{.*}} +// RUN: not llvm-symbolizer --obj="%t-1.o(%{t:stem}.tmp-1.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-NOTARCHIVE +// CHECK-NOTARCHIVE: error: '{{.*}}' is not a valid archive diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index 258dfe51bf3c1..610f86e77224e 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -26,4 +26,6 @@ // Test error cases // RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR -// CHECK-ERROR: error: {{.*}}No matching member{{.*}} +// CHECK-ERROR: error: {{.*}}no matching member{{.*}} +// RUN: not llvm-symbolizer --obj="%t.o(%{t:stem}.tmp.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-NOTARCHIVE +// CHECK-NOTARCHIVE: error: '{{.*}}' is not a valid archive From ca85990e0a6a137cf9bdaed02e12dcafeee13be7 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Fri, 29 Aug 2025 13:44:39 +0530 Subject: [PATCH 18/25] review comments addressed --- .../llvm/DebugInfo/Symbolize/Symbolize.h | 10 +++++----- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 19 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 63da5d9d57423..4e44a54ebb091 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -196,14 +196,14 @@ class LLVMSymbolizer { Expected getOrCreateObjectPair(const std::string &Path, const std::string &ArchName); - /// Return a pointer to the object file at specified path, for a specified - /// architecture (e.g. if path refers to a Mach-O universal binary, only one - /// object file from it will be returned). + /// Return a pointer to the object file with the specified name, for a + /// specified architecture (e.g. if path refers to a Mach-O universal + /// binary, only one object file from it will be returned). Expected getOrCreateObject(const std::string &InputPath, const std::string &DefaultArchName); - /// Return a pointer to the object file at specified path, for a specified - /// architecture that is present inside an archive file. + /// Return a pointer to the object file with the specified name, for a + /// specified architecture that is present inside an archive file. Expected getOrCreateObjectFromArchive(StringRef ArchivePath, StringRef MemberName, StringRef ArchName); diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 570262816e27f..bb8b23f36cef2 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -437,13 +437,13 @@ bool LLVMSymbolizer::findDebugBinary(const std::string &OrigPath, SmallString<16> OrigDir(OrigPath); llvm::sys::path::remove_filename(OrigDir); SmallString<16> DebugPath = OrigDir; - // Try relative/path/to/original_binary/debuglink_name. + // Try relative/path/to/original_binary/debuglink_name llvm::sys::path::append(DebugPath, DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { Result = std::string(DebugPath); return true; } - // Try relative/path/to/original_binary/.debug/debuglink_name. + // Try relative/path/to/original_binary/.debug/debuglink_name DebugPath = OrigDir; llvm::sys::path::append(DebugPath, ".debug", DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { @@ -452,17 +452,17 @@ bool LLVMSymbolizer::findDebugBinary(const std::string &OrigPath, } // Make the path absolute so that lookups will go to // "/usr/lib/debug/full/path/to/debug", not - // "/usr/lib/debug/to/debug". + // "/usr/lib/debug/to/debug" llvm::sys::fs::make_absolute(OrigDir); if (!Opts.FallbackDebugPath.empty()) { - // Try /absolute/path/to/original_binary/debuglink_name. + // Try /absolute/path/to/original_binary/debuglink_name DebugPath = Opts.FallbackDebugPath; } else { #if defined(__NetBSD__) - // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name. + // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name DebugPath = "/usr/libdata/debug"; #else - // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name. + // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name DebugPath = "/usr/lib/debug"; #endif } @@ -511,11 +511,11 @@ std::string LLVMSymbolizer::lookUpGsymFile(const std::string &Path) { return !EC && !llvm::sys::fs::is_directory(Status); }; - // First, look beside the binary file. + // First, look beside the binary file if (const auto GsymPath = Path + ".gsym"; CheckGsymFile(GsymPath)) return GsymPath; - // Then, look in the directories specified by GsymFileDirectory. + // Then, look in the directories specified by GsymFileDirectory for (const auto &Directory : Opts.GsymFileDirectory) { SmallString<16> GsymPath = llvm::StringRef{Directory}; @@ -595,7 +595,6 @@ Expected LLVMSymbolizer::findOrCacheObject( const ArchiveCacheKey &Key, llvm::function_ref>()> Loader, const std::string &PathForBinaryCache) { - auto It = ObjectFileCache.find(Key); if (It != ObjectFileCache.end()) return It->second.get(); @@ -837,7 +836,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const ObjectFile &Obj) { Context = BTFContext::create(Obj); else Context = DWARFContext::create(Obj); - // FIXME: handle COFF object with PDB info to use PDBContext. + // FIXME: handle COFF object with PDB info to use PDBContext return createModuleInfo(&Obj, std::move(Context), ObjName); } From 74d4e235e3170dc05892a2e5c2a6b7af67f4dcc6 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Sat, 6 Sep 2025 20:08:45 +0530 Subject: [PATCH 19/25] code format --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 4e44a54ebb091..757fb85f22933 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -196,13 +196,13 @@ class LLVMSymbolizer { Expected getOrCreateObjectPair(const std::string &Path, const std::string &ArchName); - /// Return a pointer to the object file with the specified name, for a + /// Return a pointer to the object file with the specified name, for a /// specified architecture (e.g. if path refers to a Mach-O universal /// binary, only one object file from it will be returned). Expected getOrCreateObject(const std::string &InputPath, const std::string &DefaultArchName); - /// Return a pointer to the object file with the specified name, for a + /// Return a pointer to the object file with the specified name, for a /// specified architecture that is present inside an archive file. Expected getOrCreateObjectFromArchive(StringRef ArchivePath, StringRef MemberName, From 183197af64e1f0c2c191a8f8f5e10e5fbbbe1475 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Mon, 8 Sep 2025 09:43:17 +0530 Subject: [PATCH 20/25] code format --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index 757fb85f22933..d9764d20cd638 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -197,7 +197,7 @@ class LLVMSymbolizer { const std::string &ArchName); /// Return a pointer to the object file with the specified name, for a - /// specified architecture (e.g. if path refers to a Mach-O universal + /// specified architecture (e.g. if path refers to a Mach-O universal /// binary, only one object file from it will be returned). Expected getOrCreateObject(const std::string &InputPath, const std::string &DefaultArchName); From 740776967df0223fd2f7846018480136757648df Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Mon, 8 Sep 2025 14:22:02 +0530 Subject: [PATCH 21/25] review comments fix --- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 10 +++++----- llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 242a0e89bfd8c..01881b3f38502 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -1,14 +1,14 @@ -// Test archive member recognition by name (ELF format) +// Test archive member recognition by name (ELF format). -// Generate object files from YAML +// Generate object files from YAML. // RUN: yaml2obj -o %t-1.o %S/Inputs/big-archive-elf-1.yaml // RUN: yaml2obj -o %t-2.o %S/Inputs/big-archive-elf-2.yaml -// Create archive with differently named members +// Create archive with differently named members. // RUN: rm -f %t.a // RUN: llvm-ar crv %t.a %t-1.o %t-2.o -// Test symbolization by member name (using just base names) +// Test symbolization by member name (using just base names). // RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%{t:stem}.tmp-1.o)" 0x0 | FileCheck %s --check-prefix=CHECK-1 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp-1.o):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-1 // RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%{t:stem}.tmp-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 @@ -16,7 +16,7 @@ // CHECK-1: foo1 // CHECK-2: foo2 -// Test error cases +// Test error cases. // RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR // CHECK-ERROR: error: {{.*}}no matching member{{.*}} // RUN: not llvm-symbolizer --obj="%t-1.o(%{t:stem}.tmp-1.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-NOTARCHIVE diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index 610f86e77224e..f88be1879755e 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -1,22 +1,22 @@ -// Test big archive recognition and error handling in llvm-symbolizer +// Test big archive recognition and error handling in llvm-symbolizer. -// Generate object files +// Generate object files. // RUN: yaml2obj -o %t-32.o %S/Inputs/big-archive-32.yaml // RUN: yaml2obj -o %t-64.o %S/Inputs/big-archive-64.yaml -// Create archive with same-named members using different modes +// Create archive with same-named members using different modes. // RUN: rm -f %t.a // RUN: cp %t-32.o %t.o // RUN: llvm-ar %if system-aix %{-X32%} crv %t.a %t.o // RUN: cp %t-64.o %t.o // RUN: llvm-ar %if system-aix %{-X64 rv%} %else %{qv%} %t.a %t.o -// Verify archive contains two members with same name +// Verify archive contains two members with same name. // RUN: llvm-ar tv %if system-aix %{-X32_64%} %t.a | FileCheck %s --check-prefix=CHECK-ARCHIVE // CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} // CHECK-ARCHIVE: {{.*}}symbolize-big-archive-xcoff.test.tmp.o{{$}} -// Test successful symbolization +// Test successful symbolization. // RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a(%{t:stem}.tmp.o)" 0x0 | FileCheck %s --check-prefix=CHECK-32 // RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%{t:stem}.tmp.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp.o):ppc" 0x0 | FileCheck %s --check-prefix=CHECK-32 @@ -24,7 +24,7 @@ // CHECK-32: foo // CHECK-64: foo -// Test error cases +// Test error cases. // RUN: not llvm-symbolizer --obj="%t.a(nonexistent.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR // CHECK-ERROR: error: {{.*}}no matching member{{.*}} // RUN: not llvm-symbolizer --obj="%t.o(%{t:stem}.tmp.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-NOTARCHIVE From b0f070540f7559202232601af4e6ad7786cf3d7d Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Mon, 15 Sep 2025 14:20:23 +0530 Subject: [PATCH 22/25] added tests --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 7 +++---- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 8 ++++++++ llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 9 +++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index bb8b23f36cef2..63e455dcbfbe6 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -676,13 +676,12 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, const std::string &ArchName) { // First check for archive(member) format - more efficient to check closing // paren first. - size_t CloseParen = Path.rfind(')'); - if (CloseParen != std::string::npos && CloseParen == Path.length() - 1) { - size_t OpenParen = Path.rfind('(', CloseParen); + if (!Path.empty() && Path.back() == ')') { + size_t OpenParen = Path.rfind('(', Path.size() - 1); if (OpenParen != std::string::npos) { StringRef ArchivePath = StringRef(Path).substr(0, OpenParen); StringRef MemberName = - StringRef(Path).substr(OpenParen + 1, CloseParen - OpenParen - 1); + StringRef(Path).substr(OpenParen + 1, Path.size() - OpenParen - 2); return getOrCreateObjectFromArchive(ArchivePath, MemberName, ArchName); } } diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 01881b3f38502..afa32733643f5 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -13,6 +13,8 @@ // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp-1.o):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-1 // RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%{t:stem}.tmp-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp-2.o):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-2 +// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%t-1.o)" 0x0 | FileCheck %s --check-prefix=CHECK-1 +// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%t-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 // CHECK-1: foo1 // CHECK-2: foo2 @@ -21,3 +23,9 @@ // CHECK-ERROR: error: {{.*}}no matching member{{.*}} // RUN: not llvm-symbolizer --obj="%t-1.o(%{t:stem}.tmp-1.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-NOTARCHIVE // CHECK-NOTARCHIVE: error: '{{.*}}' is not a valid archive +// RUN: not llvm-symbolizer --obj="%t.a()" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-EMPTY +// CHECK-EMPTY: {{.*}}no matching member{{.*}} +// RUN: not llvm-symbolizer --obj="%t.a(%t.o" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-1 +// CHECK-INCORRECT-FORMAT-1: {{.*}}No such file or directory{{.*}} +// RUN: not llvm-symbolizer --obj="%t.a%t.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-2 +// CHECK-INCORRECT-FORMAT-2: {{.*}}Not a directory{{.*}} diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index f88be1879755e..d1b88a44b9b55 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -21,6 +21,8 @@ // RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%{t:stem}.tmp.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp.o):ppc" 0x0 | FileCheck %s --check-prefix=CHECK-32 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp.o):ppc64" 0x0 | FileCheck %s --check-prefix=CHECK-64 +// RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-32 +// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 // CHECK-32: foo // CHECK-64: foo @@ -29,3 +31,10 @@ // CHECK-ERROR: error: {{.*}}no matching member{{.*}} // RUN: not llvm-symbolizer --obj="%t.o(%{t:stem}.tmp.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-NOTARCHIVE // CHECK-NOTARCHIVE: error: '{{.*}}' is not a valid archive +// RUN: not llvm-symbolizer --obj="%t.a()" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-EMPTY +// CHECK-EMPTY: {{.*}}no matching member{{.*}} +// RUN: not llvm-symbolizer --obj="%t.a(%t.o" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-1 +// CHECK-INCORRECT-FORMAT-1: {{.*}}No such file or directory{{.*}} +// RUN: not llvm-symbolizer --obj="%t.a%t.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-2 +// CHECK-INCORRECT-FORMAT-2: {{.*}}Not a directory{{.*}} + From f034d9024c95f8dbabe2bbc2a0a52c938f0f4eac Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Mon, 15 Sep 2025 15:34:21 +0530 Subject: [PATCH 23/25] review comments fix --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 1 - llvm/test/DebugInfo/symbolize-big-archive-elf.test | 4 ---- llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 5 ----- 3 files changed, 10 deletions(-) diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 63e455dcbfbe6..2d5b68cbca4a3 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -579,7 +579,6 @@ LLVMSymbolizer::loadOrGetBinary(const std::string &Path) { Expected> BinOrErr = createBinary(Path); if (!BinOrErr) { - BinaryForPath.erase(Pair.first); return BinOrErr.takeError(); } diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index afa32733643f5..084c4c7e022f3 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -25,7 +25,3 @@ // CHECK-NOTARCHIVE: error: '{{.*}}' is not a valid archive // RUN: not llvm-symbolizer --obj="%t.a()" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-EMPTY // CHECK-EMPTY: {{.*}}no matching member{{.*}} -// RUN: not llvm-symbolizer --obj="%t.a(%t.o" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-1 -// CHECK-INCORRECT-FORMAT-1: {{.*}}No such file or directory{{.*}} -// RUN: not llvm-symbolizer --obj="%t.a%t.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-2 -// CHECK-INCORRECT-FORMAT-2: {{.*}}Not a directory{{.*}} diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index d1b88a44b9b55..3eab2b32c315c 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -33,8 +33,3 @@ // CHECK-NOTARCHIVE: error: '{{.*}}' is not a valid archive // RUN: not llvm-symbolizer --obj="%t.a()" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-EMPTY // CHECK-EMPTY: {{.*}}no matching member{{.*}} -// RUN: not llvm-symbolizer --obj="%t.a(%t.o" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-1 -// CHECK-INCORRECT-FORMAT-1: {{.*}}No such file or directory{{.*}} -// RUN: not llvm-symbolizer --obj="%t.a%t.o)" 0x1000 2>&1 | FileCheck %s --check-prefix=CHECK-INCORRECT-FORMAT-2 -// CHECK-INCORRECT-FORMAT-2: {{.*}}Not a directory{{.*}} - From e4d6fed61abddf4b904c284e9710bcc71413f275 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Fri, 19 Sep 2025 20:15:28 +0530 Subject: [PATCH 24/25] remove sys call for path --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 2 +- llvm/test/DebugInfo/symbolize-big-archive-elf.test | 2 -- llvm/test/DebugInfo/symbolize-big-archive-xcoff.test | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 2d5b68cbca4a3..0bc61f957f0f4 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -634,7 +634,7 @@ Expected LLVMSymbolizer::getOrCreateObjectFromArchive( Expected NameOrErr = Child.getName(); if (!NameOrErr) continue; - if (*NameOrErr == sys::path::filename(MemberName)) { + if (*NameOrErr == MemberName) { Expected> MemberOrErr = Child.getAsBinary(); if (!MemberOrErr) diff --git a/llvm/test/DebugInfo/symbolize-big-archive-elf.test b/llvm/test/DebugInfo/symbolize-big-archive-elf.test index 084c4c7e022f3..20d007a8bdd82 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-elf.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-elf.test @@ -13,8 +13,6 @@ // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp-1.o):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-1 // RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%{t:stem}.tmp-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp-2.o):ppc64le" 0x0 | FileCheck %s --check-prefix=CHECK-2 -// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%t-1.o)" 0x0 | FileCheck %s --check-prefix=CHECK-1 -// RUN: llvm-symbolizer --default-arch=ppc64le --obj="%t.a(%t-2.o)" 0x0 | FileCheck %s --check-prefix=CHECK-2 // CHECK-1: foo1 // CHECK-2: foo2 diff --git a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test index 3eab2b32c315c..2811038eca65f 100644 --- a/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test +++ b/llvm/test/DebugInfo/symbolize-big-archive-xcoff.test @@ -21,8 +21,6 @@ // RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%{t:stem}.tmp.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp.o):ppc" 0x0 | FileCheck %s --check-prefix=CHECK-32 // RUN: llvm-symbolizer --obj="%t.a(%{t:stem}.tmp.o):ppc64" 0x0 | FileCheck %s --check-prefix=CHECK-64 -// RUN: llvm-symbolizer --default-arch=ppc --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-32 -// RUN: llvm-symbolizer --default-arch=ppc64 --obj="%t.a(%t.o)" 0x0 | FileCheck %s --check-prefix=CHECK-64 // CHECK-32: foo // CHECK-64: foo From c3acb241d1fba6be94a82c85a7ec7f0451b7a8f0 Mon Sep 17 00:00:00 2001 From: Midhunesh Date: Mon, 29 Sep 2025 18:13:03 +0530 Subject: [PATCH 25/25] review comment fix --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 0bc61f957f0f4..983f82f95fcd3 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -793,7 +793,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(StringRef ModuleName) { if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(), Session)) { Modules.emplace(ModuleName, std::unique_ptr()); - // Return along the PDB filename to provide more context. + // Return along the PDB filename to provide more context return createFileError(PDBFileName, std::move(Err)); } Context.reset(new PDBContext(*CoffObject, std::move(Session)));