https://github.com/DhruvSrivastavaX updated https://github.com/llvm/llvm-project/pull/141577
>From a62cd7b510f3cf74ee356a95a26e0f9922f4b39c Mon Sep 17 00:00:00 2001 From: DhruvSrivastavaX <dhruv.srivast...@ibm.com> Date: Tue, 27 May 2025 05:44:55 -0500 Subject: [PATCH 1/4] Added XCOFF ParseSymtab handling --- .../ObjectFile/XCOFF/ObjectFileXCOFF.cpp | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp index e629355cd40b9..7dfe6c362add4 100644 --- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp @@ -188,7 +188,71 @@ AddressClass ObjectFileXCOFF::GetAddressClass(addr_t file_addr) { return AddressClass::eUnknown; } -void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) {} +lldb::SymbolType MapSymbolType(llvm::object::SymbolRef::Type sym_type) { + if (sym_type == llvm::object::SymbolRef::ST_Function) + return lldb::eSymbolTypeCode; + else if (sym_type == llvm::object::SymbolRef::ST_Data) + return lldb::eSymbolTypeData; + else if (sym_type == llvm::object::SymbolRef::ST_File) + return lldb::eSymbolTypeSourceFile; + return lldb::eSymbolTypeInvalid; +} + +void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) { + SectionList *sectionList = GetSectionList(); + + for (const auto &symbol_ref : m_binary->symbols()) { + llvm::object::XCOFFSymbolRef xcoff_sym_ref(symbol_ref); + llvm::Expected<llvm::StringRef> name_or_err = xcoff_sym_ref.getName(); + if (!name_or_err) { + consumeError(name_or_err.takeError()); + continue; + } + llvm::StringRef symbolName = name_or_err.get(); + // Remove the dot prefix for demangle + llvm::StringRef symbol_name = + symbolName.starts_with(".") ? symbolName.drop_front() : symbolName; + auto storageClass = xcoff_sym_ref.getStorageClass(); + if (storageClass == XCOFF::C_HIDEXT && symbolName != "TOC") { + if (xcoff_sym_ref.getNumberOfAuxEntries() != 1) + continue; + auto aux_csect_or_err = xcoff_sym_ref.getXCOFFCsectAuxRef(); + if (!aux_csect_or_err) { + consumeError(aux_csect_or_err.takeError()); + continue; + } + const llvm::object::XCOFFCsectAuxRef csect_aux = aux_csect_or_err.get(); + if (csect_aux.getStorageMappingClass() != XCOFF::XMC_PR || + (m_binary->is64Bit() ? (csect_aux.getAuxType64() != XCOFF::AUX_CSECT) + : false)) + continue; + } + + Symbol symbol; + symbol.GetMangled().SetValue(ConstString(symbol_name)); + + int16_t sectionNumber = xcoff_sym_ref.getSectionNumber(); + size_t sectionIndex = static_cast<size_t>(sectionNumber - 1); + if (sectionNumber > 0 && sectionIndex < sectionList->GetSize()) { + lldb::SectionSP section_sp = + sectionList->GetSectionAtIndex(sectionNumber - 1); + if (!section_sp || section_sp->GetFileAddress() == LLDB_INVALID_ADDRESS) + continue; + lldb::addr_t file_addr = section_sp->GetFileAddress(); + lldb::addr_t symbolValue = xcoff_sym_ref.getValue(); + if (symbolValue < file_addr) + continue; + symbol.GetAddressRef() = Address(section_sp, symbolValue - file_addr); + } + + Expected<llvm::object::SymbolRef::Type> sym_type_or_err = + symbol_ref.getType(); + symbol.SetType(MapSymbolType(sym_type_or_err.get())); + printf("%s %d\n", symbol.GetName(), *sym_type_or_err); + + lldb_symtab.AddSymbol(symbol); + } +} bool ObjectFileXCOFF::IsStripped() { return false; } >From 21f5a39976457589e2ab9666820c08331aaf4542 Mon Sep 17 00:00:00 2001 From: Dhruv Srivastava <dhruv.srivast...@ibm.com> Date: Tue, 27 May 2025 16:33:08 +0530 Subject: [PATCH 2/4] cleanup --- lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp index 7dfe6c362add4..1e84b86cd6f0a 100644 --- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp @@ -247,8 +247,11 @@ void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) { Expected<llvm::object::SymbolRef::Type> sym_type_or_err = symbol_ref.getType(); + if (!sym_type_or_err) { + consumeError(sym_type_or_err.takeError()); + continue; + } symbol.SetType(MapSymbolType(sym_type_or_err.get())); - printf("%s %d\n", symbol.GetName(), *sym_type_or_err); lldb_symtab.AddSymbol(symbol); } >From 4d631899cd3ab96ea3819e1ece3ce2851d1f9f6c Mon Sep 17 00:00:00 2001 From: DhruvSrivastavaX <dhruv.srivast...@ibm.com> Date: Thu, 29 May 2025 07:37:23 -0500 Subject: [PATCH 3/4] Addressed comments --- .../ObjectFile/XCOFF/ObjectFileXCOFF.cpp | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp index 1e84b86cd6f0a..953d72293c81d 100644 --- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp @@ -205,31 +205,39 @@ void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) { llvm::object::XCOFFSymbolRef xcoff_sym_ref(symbol_ref); llvm::Expected<llvm::StringRef> name_or_err = xcoff_sym_ref.getName(); if (!name_or_err) { - consumeError(name_or_err.takeError()); + LLDB_LOG_ERROR(log, name_or_err.takeError(), + "Unable to extract name from the xcoff symbol ref object"); continue; } llvm::StringRef symbolName = name_or_err.get(); - // Remove the dot prefix for demangle - llvm::StringRef symbol_name = + // Remove the dot prefix from symbol names. + llvm::StringRef name_no_dot = symbolName.starts_with(".") ? symbolName.drop_front() : symbolName; auto storageClass = xcoff_sym_ref.getStorageClass(); + // If its the hidden ext TOC symbol, add it directly, + // for all other C_HIDEXT symbols, proceed to other checks. if (storageClass == XCOFF::C_HIDEXT && symbolName != "TOC") { + // We do not need to add entries with 0 or >1 auxiliary data if (xcoff_sym_ref.getNumberOfAuxEntries() != 1) continue; auto aux_csect_or_err = xcoff_sym_ref.getXCOFFCsectAuxRef(); if (!aux_csect_or_err) { - consumeError(aux_csect_or_err.takeError()); + LLDB_LOG_ERROR(log, aux_csect_or_err.takeError(), + "Unable to access xcoff csect aux ref object"); continue; } const llvm::object::XCOFFCsectAuxRef csect_aux = aux_csect_or_err.get(); - if (csect_aux.getStorageMappingClass() != XCOFF::XMC_PR || - (m_binary->is64Bit() ? (csect_aux.getAuxType64() != XCOFF::AUX_CSECT) - : false)) + // Only add hidden ext entries which come under Program Code, skip others + if (csect_aux.getStorageMappingClass() != XCOFF::XMC_PR) + continue; + // This does not apply to 32-bit, + // Only add csect symbols identified by the aux entry, skip others + if (m_binary->is64Bit() ? (csect_aux.getAuxType64() != XCOFF::AUX_CSECT)) continue; } Symbol symbol; - symbol.GetMangled().SetValue(ConstString(symbol_name)); + symbol.GetMangled().SetValue(ConstString(name_no_dot)); int16_t sectionNumber = xcoff_sym_ref.getSectionNumber(); size_t sectionIndex = static_cast<size_t>(sectionNumber - 1); @@ -248,7 +256,8 @@ void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) { Expected<llvm::object::SymbolRef::Type> sym_type_or_err = symbol_ref.getType(); if (!sym_type_or_err) { - consumeError(sym_type_or_err.takeError()); + LLDB_LOG_ERROR(log, aux_csect_or_err.takeError(), + "Unable to access xcoff symbol type"); continue; } symbol.SetType(MapSymbolType(sym_type_or_err.get())); >From e324a3ba39c5623f4ac2585d614cef208b685057 Mon Sep 17 00:00:00 2001 From: DhruvSrivastavaX <dhruv.srivast...@ibm.com> Date: Thu, 12 Jun 2025 06:01:29 -0500 Subject: [PATCH 4/4] Added comments and tests --- .../ObjectFile/XCOFF/ObjectFileXCOFF.cpp | 71 +++++++++----- .../Shell/ObjectFile/XCOFF/basic-info.yaml | 94 +++++++++++++++++++ 2 files changed, 141 insertions(+), 24 deletions(-) diff --git a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp index dcc4f3e1046c2..641bb30021603 100644 --- a/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/XCOFF/ObjectFileXCOFF.cpp @@ -188,78 +188,102 @@ AddressClass ObjectFileXCOFF::GetAddressClass(addr_t file_addr) { return AddressClass::eUnknown; } -lldb::SymbolType MapSymbolType(llvm::object::SymbolRef::Type sym_type) { - if (sym_type == llvm::object::SymbolRef::ST_Function) +static lldb::SymbolType MapSymbolType(llvm::object::SymbolRef::Type sym_type) { + switch (sym_type) { + case llvm::object::SymbolRef::ST_Function: return lldb::eSymbolTypeCode; - else if (sym_type == llvm::object::SymbolRef::ST_Data) + case llvm::object::SymbolRef::ST_Data: return lldb::eSymbolTypeData; - else if (sym_type == llvm::object::SymbolRef::ST_File) + case llvm::object::SymbolRef::ST_File: return lldb::eSymbolTypeSourceFile; - return lldb::eSymbolTypeInvalid; + default: + return lldb::eSymbolTypeInvalid; + } } void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) { + Log *log = GetLog(LLDBLog::Object); SectionList *sectionList = GetSectionList(); for (const auto &symbol_ref : m_binary->symbols()) { llvm::object::XCOFFSymbolRef xcoff_sym_ref(symbol_ref); + llvm::Expected<llvm::StringRef> name_or_err = xcoff_sym_ref.getName(); if (!name_or_err) { LLDB_LOG_ERROR(log, name_or_err.takeError(), "Unable to extract name from the xcoff symbol ref object"); continue; } + llvm::StringRef symbolName = name_or_err.get(); - // Remove the dot prefix from symbol names. + // Remove the . prefix added during compilation. This prefix is usually + // added to differentiate between reference to the code and function + // descriptor. For instance, Adding .func will only allow user to put bp on + // .func, which is not known to the user, instead of func. llvm::StringRef name_no_dot = symbolName.starts_with(".") ? symbolName.drop_front() : symbolName; auto storageClass = xcoff_sym_ref.getStorageClass(); - // If its the hidden ext TOC symbol, add it directly, - // for all other C_HIDEXT symbols, proceed to other checks. + // C_HIDEXT symbols are not needed to be exposed, with the exception of TOC + // which is responsible for storing references to global data if (storageClass == XCOFF::C_HIDEXT && symbolName != "TOC") { - // We do not need to add entries with 0 or >1 auxiliary data + + // Zero or muliple aux entries may suggest ambiguous data if (xcoff_sym_ref.getNumberOfAuxEntries() != 1) continue; + auto aux_csect_or_err = xcoff_sym_ref.getXCOFFCsectAuxRef(); if (!aux_csect_or_err) { LLDB_LOG_ERROR(log, aux_csect_or_err.takeError(), "Unable to access xcoff csect aux ref object"); continue; } + const llvm::object::XCOFFCsectAuxRef csect_aux = aux_csect_or_err.get(); + // Only add hidden ext entries which come under Program Code, skip others + // as they are not useful as debugging data. if (csect_aux.getStorageMappingClass() != XCOFF::XMC_PR) continue; + // This does not apply to 32-bit, - // Only add csect symbols identified by the aux entry, skip others - if (m_binary->is64Bit() ? (csect_aux.getAuxType64() != XCOFF::AUX_CSECT)) - continue; + // Only add csect symbols identified by the aux entry, as they are + // needed to reference section information. Skip others + if (m_binary->is64Bit()) + if (csect_aux.getAuxType64() != XCOFF::AUX_CSECT) + continue; } Symbol symbol; symbol.GetMangled().SetValue(ConstString(name_no_dot)); int16_t sectionNumber = xcoff_sym_ref.getSectionNumber(); + // Note that XCOFF section headers are numbered from 1 and not 0. size_t sectionIndex = static_cast<size_t>(sectionNumber - 1); - if (sectionNumber > 0 && sectionIndex < sectionList->GetSize()) { - lldb::SectionSP section_sp = - sectionList->GetSectionAtIndex(sectionNumber - 1); - if (!section_sp || section_sp->GetFileAddress() == LLDB_INVALID_ADDRESS) - continue; - lldb::addr_t file_addr = section_sp->GetFileAddress(); - lldb::addr_t symbolValue = xcoff_sym_ref.getValue(); - if (symbolValue < file_addr) - continue; - symbol.GetAddressRef() = Address(section_sp, symbolValue - file_addr); + if (sectionNumber > 0) { + if (sectionIndex < sectionList->GetSize()) { + + lldb::SectionSP section_sp = + sectionList->GetSectionAtIndex(sectionIndex); + if (!section_sp || section_sp->GetFileAddress() == LLDB_INVALID_ADDRESS) + continue; + + lldb::addr_t file_addr = section_sp->GetFileAddress(); + lldb::addr_t symbolValue = xcoff_sym_ref.getValue(); + if (symbolValue < file_addr) + continue; + + symbol.GetAddressRef() = Address(section_sp, symbolValue - file_addr); + } } Expected<llvm::object::SymbolRef::Type> sym_type_or_err = symbol_ref.getType(); if (!sym_type_or_err) { - LLDB_LOG_ERROR(log, aux_csect_or_err.takeError(), + LLDB_LOG_ERROR(log, sym_type_or_err.takeError(), "Unable to access xcoff symbol type"); continue; } + symbol.SetType(MapSymbolType(sym_type_or_err.get())); lldb_symtab.AddSymbol(symbol); @@ -315,7 +339,6 @@ void ObjectFileXCOFF::CreateSectionsWithBitness( .Case(".dwinfo", eSectionTypeDWARFDebugInfo) .Case(".dwline", eSectionTypeDWARFDebugLine) .Case(".dwabrev", eSectionTypeDWARFDebugAbbrev) - .Case(".dwrnges", eSectionTypeDWARFDebugRanges) .Default(eSectionTypeInvalid); } diff --git a/lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml b/lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml index 17ff2f31c2fff..bc391aac33d6d 100644 --- a/lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml +++ b/lldb/test/Shell/ObjectFile/XCOFF/basic-info.yaml @@ -29,6 +29,15 @@ # CHECK-NEXT: Type: dwarf-abbrev # CHECK-NEXT: Permissions: r-- +# RUN: %lldb %t -o "image dump symtab" -o exit | FileCheck %s --check-prefix=CHECK-SYMBOL +# CHECK-SYMBOL:Index UserID DSX Type File Address/Value Load Address Size Flags Name +# CHECK-SYMBOL:[ 0] 4294967295 Invalid 0xffffffffffffffff 0x0000000000000000 0x00000000 errno +# CHECK-SYMBOL:[ 1] 4294967295 Code 0x0000000100000500 0x0000000000000398 0x00000000 __threads_init +# CHECK-SYMBOL:[ 2] 4294967295 Data 0x0000000110000a70 0x0000000000000060 0x00000000 __threads_init +# CHECK-SYMBOL:[ 3] 4294967295 Invalid 0x0000000110000ad0 0x00000000000000b0 0x00000000 TOC +# CHECK-SYMBOL:[ 4] 4294967295 Invalid 0x0000000100000898 0x00000000100001d8 0x00000000 text +# CHECK-SYMBOL:[ 5] 4294967295 Code 0x0000000100000898 0x00000000100001d8 0x00000000 main + --- !XCOFF FileHeader: MagicNumber: 0x1F7 @@ -104,5 +113,90 @@ Sections: NumberOfLineNumbers: 0x0 Flags: [ STYP_DWARF ] SectionData: 01110125 +Symbols: + - Name: errno + Value: 0x0 + Section: N_UNDEF + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolAlignmentAndType: 0 + StorageMappingClass: XMC_RW + SectionOrLengthLo: 0 + SectionOrLengthHi: 0 + - Name: .__threads_init + Value: 0x100000500 + Section: .text + Type: 0x20 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolAlignmentAndType: 2 + StorageMappingClass: XMC_PR + SectionOrLengthLo: 80 + SectionOrLengthHi: 0 + - Name: __threads_init + Value: 0x110000A70 + Section: .data + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolAlignmentAndType: 25 + StorageMappingClass: XMC_DS + SectionOrLengthLo: 24 + SectionOrLengthHi: 0 + - Name: TOC + Value: 0x110000AD0 + Section: .data + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolAlignmentAndType: 25 + StorageMappingClass: XMC_TC0 + SectionOrLengthLo: 0 + SectionOrLengthHi: 0 + - Name: .text + Value: 0x100000898 + Section: .text + Type: 0x0 + StorageClass: C_HIDEXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolAlignmentAndType: 17 + StorageMappingClass: XMC_PR + SectionOrLengthLo: 58 + SectionOrLengthHi: 0 + - Name: .main + Value: 0x100000898 + Section: .text + Type: 0x0 + StorageClass: C_EXT + NumberOfAuxEntries: 1 + AuxEntries: + - Type: AUX_CSECT + ParameterHashIndex: 0 + TypeChkSectNum: 0 + SymbolAlignmentAndType: 2 + StorageMappingClass: XMC_PR + SectionOrLengthLo: 135 + SectionOrLengthHi: 0 StringTable: {} ... _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits