From 6e2d6b9ab4db2c6ea61697b494fcf8f1dd510aa2 Mon Sep 17 00:00:00 2001 From: Chen Zheng Date: Mon, 25 Sep 2023 05:24:25 -0400 Subject: [PATCH 1/5] get symbol size by calling xcoff interfaces. --- llvm/include/llvm/Object/XCOFFObjectFile.h | 29 ++++++++++++++++++- llvm/lib/Object/SymbolSize.cpp | 7 +++++ llvm/lib/Object/XCOFFObjectFile.cpp | 4 +++ .../Symbolize/XCOFF/xcoff-symbolize-data.ll | 9 ++---- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h index 5f51aacfabc08..7f975e568b552 100644 --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -15,6 +15,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/BinaryFormat/XCOFF.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Endian.h" @@ -23,6 +24,8 @@ namespace llvm { namespace object { +class xcoff_symbol_iterator; + struct XCOFFFileHeader32 { support::ubig16_t Magic; support::ubig16_t NumberOfSections; @@ -576,6 +579,10 @@ class XCOFFObjectFile : public ObjectFile { Expected getSymbolFlags(DataRefImpl Symb) const override; basic_symbol_iterator symbol_begin() const override; basic_symbol_iterator symbol_end() const override; + + using xcoff_symbol_iterator_range = iterator_range; + xcoff_symbol_iterator_range symbols() const; + bool is64Bit() const override; Expected getSymbolName(DataRefImpl Symb) const override; Expected getSymbolAddress(DataRefImpl Symb) const override; @@ -761,7 +768,7 @@ struct XCOFFSymbolEntry64 { uint8_t NumberOfAuxEntries; }; -class XCOFFSymbolRef { +class XCOFFSymbolRef : public SymbolRef { public: enum { NAME_IN_STR_TBL_MAGIC = 0x0 }; @@ -787,6 +794,11 @@ class XCOFFSymbolRef { uint64_t getValue64() const { return Entry64->Value; } + uint64_t getSize() const { + return cast(BasicSymbolRef::getObject()) + ->getSymbolSize(getRawDataRefImpl()); + } + #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X int16_t getSectionNumber() const { return GETVALUE(SectionNumber); } @@ -827,6 +839,21 @@ class XCOFFSymbolRef { const XCOFFSymbolEntry64 *Entry64 = nullptr; }; +class xcoff_symbol_iterator : public symbol_iterator { +public: + xcoff_symbol_iterator(const basic_symbol_iterator &B) + : symbol_iterator(SymbolRef(B->getRawDataRefImpl(), + cast(B->getObject()))) {} + + const XCOFFSymbolRef *operator->() const { + return static_cast(symbol_iterator::operator->()); + } + + const XCOFFSymbolRef &operator*() const { + return static_cast(symbol_iterator::operator*()); + } +}; + class TBVectorExt { uint16_t Data; SmallString<32> VecParmsInfo; diff --git a/llvm/lib/Object/SymbolSize.cpp b/llvm/lib/Object/SymbolSize.cpp index f93a5f7d9bd54..c4f30b1072d52 100644 --- a/llvm/lib/Object/SymbolSize.cpp +++ b/llvm/lib/Object/SymbolSize.cpp @@ -59,6 +59,13 @@ llvm::object::computeSymbolSizes(const ObjectFile &O) { return Ret; } + if (const auto *E = dyn_cast(&O)) { + auto Syms = E->symbols(); + for (XCOFFSymbolRef Sym : Syms) + Ret.push_back({Sym, Sym.getSize()}); + return Ret; + } + // Collect sorted symbol addresses. Include dummy addresses for the end // of each section. std::vector Addresses; diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp index fa4917e354e92..7dcf344282e14 100644 --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -689,6 +689,10 @@ basic_symbol_iterator XCOFFObjectFile::symbol_end() const { return basic_symbol_iterator(SymbolRef(SymDRI, this)); } +XCOFFObjectFile::xcoff_symbol_iterator_range XCOFFObjectFile::symbols() const { + return xcoff_symbol_iterator_range(symbol_begin(), symbol_end()); +} + section_iterator XCOFFObjectFile::section_begin() const { DataRefImpl DRI; DRI.p = getSectionHeaderTableAddress(); diff --git a/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll b/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll index 968c175ffdc6c..5432b59d583ba 100644 --- a/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll +++ b/llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll @@ -35,23 +35,20 @@ ; CHECK-EMPTY: ;; Test a function scope static variable. -;; FIXME: fix the wrong size 152 ; CHECK: f()::function_global -; CHECK-NEXT: 144 152 +; CHECK-NEXT: 144 4 ; CHECK-NEXT: /t.cpp:8 ; CHECK-EMPTY: ;; Test a global scope static variable that is used in current compilation unit. -;; FIXME: fix the wrong size 152 ; CHECK: beta -; CHECK-NEXT: 148 152 +; CHECK-NEXT: 148 4 ; CHECK-NEXT: /t.cpp:13 ; CHECK-EMPTY: ;; Test another global scope static variable that is used in current compilation unit. -;; FIXME: fix the wrong size 152 ; CHECK: alpha -; CHECK-NEXT: 152 152 +; CHECK-NEXT: 152 4 ; CHECK-NEXT: /t.cpp:12 ; CHECK-EMPTY: From c383e9cf4c2ecf5e5bb09875bf777887f32bad92 Mon Sep 17 00:00:00 2001 From: Chen Zheng Date: Wed, 27 Sep 2023 02:18:10 -0400 Subject: [PATCH 2/5] address comments --- llvm/include/llvm/Object/XCOFFObjectFile.h | 10 ++++++---- llvm/lib/Object/XCOFFObjectFile.cpp | 16 ++++++++-------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h index 7f975e568b552..c1072d20eaa63 100644 --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -774,7 +774,7 @@ class XCOFFSymbolRef : public SymbolRef { XCOFFSymbolRef(DataRefImpl SymEntDataRef, const XCOFFObjectFile *OwningObjectPtr) - : OwningObjectPtr(OwningObjectPtr) { + : SymbolRef(SymEntDataRef, OwningObjectPtr) { assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!"); assert(SymEntDataRef.p != 0 && "Symbol table entry pointer cannot be nullptr!"); @@ -795,8 +795,7 @@ class XCOFFSymbolRef : public SymbolRef { uint64_t getValue64() const { return Entry64->Value; } uint64_t getSize() const { - return cast(BasicSymbolRef::getObject()) - ->getSymbolSize(getRawDataRefImpl()); + return getObject()->getSymbolSize(getRawDataRefImpl()); } #define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X @@ -834,7 +833,10 @@ class XCOFFSymbolRef : public SymbolRef { Expected getXCOFFCsectAuxRef() const; private: - const XCOFFObjectFile *OwningObjectPtr; + const XCOFFObjectFile *getObject() const { + return cast(BasicSymbolRef::getObject()); + } + const XCOFFSymbolEntry32 *Entry32 = nullptr; const XCOFFSymbolEntry64 *Entry64 = nullptr; }; diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp index 7dcf344282e14..4fee4b0893751 100644 --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -1252,7 +1252,7 @@ bool XCOFFSymbolRef::isFunction() const { return false; const int16_t SectNum = getSectionNumber(); - Expected SI = OwningObjectPtr->getSectionByNum(SectNum); + Expected SI = getObject()->getSectionByNum(SectNum); if (!SI) { // If we could not get the section, then this symbol should not be // a function. So consume the error and return `false` to move on. @@ -1260,7 +1260,7 @@ bool XCOFFSymbolRef::isFunction() const { return false; } - return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT); + return (getObject()->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT); } bool XCOFFSymbolRef::isCsectSymbol() const { @@ -1279,13 +1279,13 @@ Expected XCOFFSymbolRef::getXCOFFCsectAuxRef() const { if (auto Err = NameOrErr.takeError()) return std::move(Err); - uint32_t SymbolIdx = OwningObjectPtr->getSymbolIndex(getEntryAddress()); + uint32_t SymbolIdx = getObject()->getSymbolIndex(getEntryAddress()); if (!NumberOfAuxEntries) { return createError("csect symbol \"" + *NameOrErr + "\" with index " + Twine(SymbolIdx) + " contains no auxiliary entry"); } - if (!OwningObjectPtr->is64Bit()) { + if (!getObject()->is64Bit()) { // In XCOFF32, the csect auxilliary entry is always the last auxiliary // entry for the symbol. uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress( @@ -1298,10 +1298,10 @@ Expected XCOFFSymbolRef::getXCOFFCsectAuxRef() const { for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) { uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress( getEntryAddress(), Index); - if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) == + if (*getObject()->getSymbolAuxType(AuxAddr) == XCOFF::SymbolAuxType::AUX_CSECT) { #ifndef NDEBUG - OwningObjectPtr->checkSymbolEntryPointer(AuxAddr); + getObject()->checkSymbolEntryPointer(AuxAddr); #endif return XCOFFCsectAuxRef(viewAs(AuxAddr)); } @@ -1322,10 +1322,10 @@ Expected XCOFFSymbolRef::getName() const { if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC) return generateXCOFFFixedNameStringRef(Entry32->SymbolName); - return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset); + return getObject()->getStringTableEntry(Entry32->NameInStrTbl.Offset); } - return OwningObjectPtr->getStringTableEntry(Entry64->Offset); + return getObject()->getStringTableEntry(Entry64->Offset); } // Explictly instantiate template classes. From 5b7e39d71b933a5983aa5b944cb26fef01df7c65 Mon Sep 17 00:00:00 2001 From: Chen Zheng Date: Thu, 28 Sep 2023 04:47:40 -0400 Subject: [PATCH 3/5] address comments --- llvm/include/llvm/Object/XCOFFObjectFile.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h index c1072d20eaa63..a92a81d3535dc 100644 --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -844,8 +844,7 @@ class XCOFFSymbolRef : public SymbolRef { class xcoff_symbol_iterator : public symbol_iterator { public: xcoff_symbol_iterator(const basic_symbol_iterator &B) - : symbol_iterator(SymbolRef(B->getRawDataRefImpl(), - cast(B->getObject()))) {} + : symbol_iterator(B) {} const XCOFFSymbolRef *operator->() const { return static_cast(symbol_iterator::operator->()); From be84368dc45d2f7043d15bde5f0299ec7b8f47bb Mon Sep 17 00:00:00 2001 From: Chen Zheng Date: Wed, 11 Oct 2023 03:19:56 -0400 Subject: [PATCH 4/5] address comment --- llvm/include/llvm/Object/XCOFFObjectFile.h | 29 +++++++++++----------- llvm/lib/Object/XCOFFObjectFile.cpp | 11 ++++---- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h index a92a81d3535dc..b986423236a06 100644 --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -778,17 +778,19 @@ class XCOFFSymbolRef : public SymbolRef { assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!"); assert(SymEntDataRef.p != 0 && "Symbol table entry pointer cannot be nullptr!"); - - if (OwningObjectPtr->is64Bit()) - Entry64 = reinterpret_cast(SymEntDataRef.p); - else - Entry32 = reinterpret_cast(SymEntDataRef.p); } - const XCOFFSymbolEntry32 *getSymbol32() { return Entry32; } - const XCOFFSymbolEntry64 *getSymbol64() { return Entry64; } +#define Entry32 \ + reinterpret_cast(getRawDataRefImpl().p) +#define Entry64 \ + reinterpret_cast(getRawDataRefImpl().p) + + const XCOFFSymbolEntry32 *getSymbol32() const { return Entry32; } + const XCOFFSymbolEntry64 *getSymbol64() const { return Entry64; } - uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); } + uint64_t getValue() const { + return getObject()->is64Bit() ? getValue64() : getValue32(); + } uint32_t getValue32() const { return Entry32->Value; } @@ -798,7 +800,7 @@ class XCOFFSymbolRef : public SymbolRef { return getObject()->getSymbolSize(getRawDataRefImpl()); } -#define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X +#define GETVALUE(X) getObject()->is64Bit() ? Entry64->X : Entry32->X int16_t getSectionNumber() const { return GETVALUE(SectionNumber); } @@ -823,9 +825,11 @@ class XCOFFSymbolRef : public SymbolRef { #undef GETVALUE uintptr_t getEntryAddress() const { - return Entry32 ? reinterpret_cast(Entry32) - : reinterpret_cast(Entry64); + return getObject()->is64Bit() ? reinterpret_cast(Entry64) + : reinterpret_cast(Entry32); } +#undef Entry32 +#undef Entry64 Expected getName() const; bool isFunction() const; @@ -836,9 +840,6 @@ class XCOFFSymbolRef : public SymbolRef { const XCOFFObjectFile *getObject() const { return cast(BasicSymbolRef::getObject()); } - - const XCOFFSymbolEntry32 *Entry32 = nullptr; - const XCOFFSymbolEntry64 *Entry64 = nullptr; }; class xcoff_symbol_iterator : public symbol_iterator { diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp index 4fee4b0893751..4c192aa37a7ec 100644 --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -1318,14 +1318,15 @@ Expected XCOFFSymbolRef::getName() const { if (getStorageClass() & 0x80) return StringRef("Unimplemented Debug Name"); - if (Entry32) { - if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC) - return generateXCOFFFixedNameStringRef(Entry32->SymbolName); + if (!getObject()->is64Bit()) { + if (getSymbol32()->NameInStrTbl.Magic != + XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC) + return generateXCOFFFixedNameStringRef(getSymbol32()->SymbolName); - return getObject()->getStringTableEntry(Entry32->NameInStrTbl.Offset); + return getObject()->getStringTableEntry(getSymbol32()->NameInStrTbl.Offset); } - return getObject()->getStringTableEntry(Entry64->Offset); + return getObject()->getStringTableEntry(getSymbol64()->Offset); } // Explictly instantiate template classes. From 382ee766d2a6a8a948843632f3612379980e3539 Mon Sep 17 00:00:00 2001 From: Chen Zheng Date: Wed, 11 Oct 2023 10:42:03 -0400 Subject: [PATCH 5/5] don't use macro --- llvm/include/llvm/Object/XCOFFObjectFile.h | 33 +++++++++++++--------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h index b986423236a06..be468e888aa5c 100644 --- a/llvm/include/llvm/Object/XCOFFObjectFile.h +++ b/llvm/include/llvm/Object/XCOFFObjectFile.h @@ -780,27 +780,35 @@ class XCOFFSymbolRef : public SymbolRef { "Symbol table entry pointer cannot be nullptr!"); } -#define Entry32 \ - reinterpret_cast(getRawDataRefImpl().p) -#define Entry64 \ - reinterpret_cast(getRawDataRefImpl().p) - - const XCOFFSymbolEntry32 *getSymbol32() const { return Entry32; } - const XCOFFSymbolEntry64 *getSymbol64() const { return Entry64; } + const XCOFFSymbolEntry32 *getSymbol32() const { + return reinterpret_cast(getRawDataRefImpl().p); + } + const XCOFFSymbolEntry64 *getSymbol64() const { + return reinterpret_cast(getRawDataRefImpl().p); + } uint64_t getValue() const { return getObject()->is64Bit() ? getValue64() : getValue32(); } - uint32_t getValue32() const { return Entry32->Value; } + uint32_t getValue32() const { + return reinterpret_cast(getRawDataRefImpl().p) + ->Value; + } - uint64_t getValue64() const { return Entry64->Value; } + uint64_t getValue64() const { + return reinterpret_cast(getRawDataRefImpl().p) + ->Value; + } uint64_t getSize() const { return getObject()->getSymbolSize(getRawDataRefImpl()); } -#define GETVALUE(X) getObject()->is64Bit() ? Entry64->X : Entry32->X +#define GETVALUE(X) \ + getObject()->is64Bit() \ + ? reinterpret_cast(getRawDataRefImpl().p)->X \ + : reinterpret_cast(getRawDataRefImpl().p)->X int16_t getSectionNumber() const { return GETVALUE(SectionNumber); } @@ -825,11 +833,8 @@ class XCOFFSymbolRef : public SymbolRef { #undef GETVALUE uintptr_t getEntryAddress() const { - return getObject()->is64Bit() ? reinterpret_cast(Entry64) - : reinterpret_cast(Entry32); + return getRawDataRefImpl().p; } -#undef Entry32 -#undef Entry64 Expected getName() const; bool isFunction() const;