Skip to content

Commit 1379a72

Browse files
author
Chen Zheng
authored
[XCOFF][OBJECT] get symbol size by calling XCOFF interfaces (#67304)
Computing the symbol size as the gap between sorted symbols are not right for XCOFF. For XCOFF, the size info is stored in aux symbol and can be got from existing XCOFF interface `getSymbolSize()`. This patch changes XCOFFObjectFile to call this API to get sizes for symbols.
1 parent c661c4f commit 1379a72

File tree

4 files changed

+77
-34
lines changed

4 files changed

+77
-34
lines changed

llvm/include/llvm/Object/XCOFFObjectFile.h

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "llvm/ADT/SmallString.h"
1717
#include "llvm/ADT/SmallVector.h"
18+
#include "llvm/ADT/iterator_range.h"
1819
#include "llvm/BinaryFormat/XCOFF.h"
1920
#include "llvm/Object/ObjectFile.h"
2021
#include "llvm/Support/Endian.h"
@@ -23,6 +24,8 @@
2324
namespace llvm {
2425
namespace object {
2526

27+
class xcoff_symbol_iterator;
28+
2629
struct XCOFFFileHeader32 {
2730
support::ubig16_t Magic;
2831
support::ubig16_t NumberOfSections;
@@ -576,6 +579,10 @@ class XCOFFObjectFile : public ObjectFile {
576579
Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
577580
basic_symbol_iterator symbol_begin() const override;
578581
basic_symbol_iterator symbol_end() const override;
582+
583+
using xcoff_symbol_iterator_range = iterator_range<xcoff_symbol_iterator>;
584+
xcoff_symbol_iterator_range symbols() const;
585+
579586
bool is64Bit() const override;
580587
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
581588
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
@@ -761,33 +768,47 @@ struct XCOFFSymbolEntry64 {
761768
uint8_t NumberOfAuxEntries;
762769
};
763770

764-
class XCOFFSymbolRef {
771+
class XCOFFSymbolRef : public SymbolRef {
765772
public:
766773
enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
767774

768775
XCOFFSymbolRef(DataRefImpl SymEntDataRef,
769776
const XCOFFObjectFile *OwningObjectPtr)
770-
: OwningObjectPtr(OwningObjectPtr) {
777+
: SymbolRef(SymEntDataRef, OwningObjectPtr) {
771778
assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!");
772779
assert(SymEntDataRef.p != 0 &&
773780
"Symbol table entry pointer cannot be nullptr!");
781+
}
774782

775-
if (OwningObjectPtr->is64Bit())
776-
Entry64 = reinterpret_cast<const XCOFFSymbolEntry64 *>(SymEntDataRef.p);
777-
else
778-
Entry32 = reinterpret_cast<const XCOFFSymbolEntry32 *>(SymEntDataRef.p);
783+
const XCOFFSymbolEntry32 *getSymbol32() const {
784+
return reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p);
785+
}
786+
const XCOFFSymbolEntry64 *getSymbol64() const {
787+
return reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p);
779788
}
780789

781-
const XCOFFSymbolEntry32 *getSymbol32() { return Entry32; }
782-
const XCOFFSymbolEntry64 *getSymbol64() { return Entry64; }
790+
uint64_t getValue() const {
791+
return getObject()->is64Bit() ? getValue64() : getValue32();
792+
}
783793

784-
uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); }
794+
uint32_t getValue32() const {
795+
return reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p)
796+
->Value;
797+
}
785798

786-
uint32_t getValue32() const { return Entry32->Value; }
799+
uint64_t getValue64() const {
800+
return reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p)
801+
->Value;
802+
}
787803

788-
uint64_t getValue64() const { return Entry64->Value; }
804+
uint64_t getSize() const {
805+
return getObject()->getSymbolSize(getRawDataRefImpl());
806+
}
789807

790-
#define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
808+
#define GETVALUE(X) \
809+
getObject()->is64Bit() \
810+
? reinterpret_cast<const XCOFFSymbolEntry64 *>(getRawDataRefImpl().p)->X \
811+
: reinterpret_cast<const XCOFFSymbolEntry32 *>(getRawDataRefImpl().p)->X
791812

792813
int16_t getSectionNumber() const { return GETVALUE(SectionNumber); }
793814

@@ -812,8 +833,7 @@ class XCOFFSymbolRef {
812833
#undef GETVALUE
813834

814835
uintptr_t getEntryAddress() const {
815-
return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
816-
: reinterpret_cast<uintptr_t>(Entry64);
836+
return getRawDataRefImpl().p;
817837
}
818838

819839
Expected<StringRef> getName() const;
@@ -822,9 +842,23 @@ class XCOFFSymbolRef {
822842
Expected<XCOFFCsectAuxRef> getXCOFFCsectAuxRef() const;
823843

824844
private:
825-
const XCOFFObjectFile *OwningObjectPtr;
826-
const XCOFFSymbolEntry32 *Entry32 = nullptr;
827-
const XCOFFSymbolEntry64 *Entry64 = nullptr;
845+
const XCOFFObjectFile *getObject() const {
846+
return cast<XCOFFObjectFile>(BasicSymbolRef::getObject());
847+
}
848+
};
849+
850+
class xcoff_symbol_iterator : public symbol_iterator {
851+
public:
852+
xcoff_symbol_iterator(const basic_symbol_iterator &B)
853+
: symbol_iterator(B) {}
854+
855+
const XCOFFSymbolRef *operator->() const {
856+
return static_cast<const XCOFFSymbolRef *>(symbol_iterator::operator->());
857+
}
858+
859+
const XCOFFSymbolRef &operator*() const {
860+
return static_cast<const XCOFFSymbolRef &>(symbol_iterator::operator*());
861+
}
828862
};
829863

830864
class TBVectorExt {

llvm/lib/Object/SymbolSize.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ llvm::object::computeSymbolSizes(const ObjectFile &O) {
5959
return Ret;
6060
}
6161

62+
if (const auto *E = dyn_cast<XCOFFObjectFile>(&O)) {
63+
auto Syms = E->symbols();
64+
for (XCOFFSymbolRef Sym : Syms)
65+
Ret.push_back({Sym, Sym.getSize()});
66+
return Ret;
67+
}
68+
6269
// Collect sorted symbol addresses. Include dummy addresses for the end
6370
// of each section.
6471
std::vector<SymEntry> Addresses;

llvm/lib/Object/XCOFFObjectFile.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,10 @@ basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
689689
return basic_symbol_iterator(SymbolRef(SymDRI, this));
690690
}
691691

692+
XCOFFObjectFile::xcoff_symbol_iterator_range XCOFFObjectFile::symbols() const {
693+
return xcoff_symbol_iterator_range(symbol_begin(), symbol_end());
694+
}
695+
692696
section_iterator XCOFFObjectFile::section_begin() const {
693697
DataRefImpl DRI;
694698
DRI.p = getSectionHeaderTableAddress();
@@ -1248,15 +1252,15 @@ bool XCOFFSymbolRef::isFunction() const {
12481252
return false;
12491253

12501254
const int16_t SectNum = getSectionNumber();
1251-
Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
1255+
Expected<DataRefImpl> SI = getObject()->getSectionByNum(SectNum);
12521256
if (!SI) {
12531257
// If we could not get the section, then this symbol should not be
12541258
// a function. So consume the error and return `false` to move on.
12551259
consumeError(SI.takeError());
12561260
return false;
12571261
}
12581262

1259-
return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
1263+
return (getObject()->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
12601264
}
12611265

12621266
bool XCOFFSymbolRef::isCsectSymbol() const {
@@ -1275,13 +1279,13 @@ Expected<XCOFFCsectAuxRef> XCOFFSymbolRef::getXCOFFCsectAuxRef() const {
12751279
if (auto Err = NameOrErr.takeError())
12761280
return std::move(Err);
12771281

1278-
uint32_t SymbolIdx = OwningObjectPtr->getSymbolIndex(getEntryAddress());
1282+
uint32_t SymbolIdx = getObject()->getSymbolIndex(getEntryAddress());
12791283
if (!NumberOfAuxEntries) {
12801284
return createError("csect symbol \"" + *NameOrErr + "\" with index " +
12811285
Twine(SymbolIdx) + " contains no auxiliary entry");
12821286
}
12831287

1284-
if (!OwningObjectPtr->is64Bit()) {
1288+
if (!getObject()->is64Bit()) {
12851289
// In XCOFF32, the csect auxilliary entry is always the last auxiliary
12861290
// entry for the symbol.
12871291
uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
@@ -1294,10 +1298,10 @@ Expected<XCOFFCsectAuxRef> XCOFFSymbolRef::getXCOFFCsectAuxRef() const {
12941298
for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
12951299
uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
12961300
getEntryAddress(), Index);
1297-
if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
1301+
if (*getObject()->getSymbolAuxType(AuxAddr) ==
12981302
XCOFF::SymbolAuxType::AUX_CSECT) {
12991303
#ifndef NDEBUG
1300-
OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
1304+
getObject()->checkSymbolEntryPointer(AuxAddr);
13011305
#endif
13021306
return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
13031307
}
@@ -1314,14 +1318,15 @@ Expected<StringRef> XCOFFSymbolRef::getName() const {
13141318
if (getStorageClass() & 0x80)
13151319
return StringRef("Unimplemented Debug Name");
13161320

1317-
if (Entry32) {
1318-
if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
1319-
return generateXCOFFFixedNameStringRef(Entry32->SymbolName);
1321+
if (!getObject()->is64Bit()) {
1322+
if (getSymbol32()->NameInStrTbl.Magic !=
1323+
XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
1324+
return generateXCOFFFixedNameStringRef(getSymbol32()->SymbolName);
13201325

1321-
return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
1326+
return getObject()->getStringTableEntry(getSymbol32()->NameInStrTbl.Offset);
13221327
}
13231328

1324-
return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
1329+
return getObject()->getStringTableEntry(getSymbol64()->Offset);
13251330
}
13261331

13271332
// Explictly instantiate template classes.

llvm/test/DebugInfo/Symbolize/XCOFF/xcoff-symbolize-data.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,20 @@
3535
; CHECK-EMPTY:
3636

3737
;; Test a function scope static variable.
38-
;; FIXME: fix the wrong size 152
3938
; CHECK: f()::function_global
40-
; CHECK-NEXT: 144 152
39+
; CHECK-NEXT: 144 4
4140
; CHECK-NEXT: /t.cpp:8
4241
; CHECK-EMPTY:
4342

4443
;; Test a global scope static variable that is used in current compilation unit.
45-
;; FIXME: fix the wrong size 152
4644
; CHECK: beta
47-
; CHECK-NEXT: 148 152
45+
; CHECK-NEXT: 148 4
4846
; CHECK-NEXT: /t.cpp:13
4947
; CHECK-EMPTY:
5048

5149
;; Test another global scope static variable that is used in current compilation unit.
52-
;; FIXME: fix the wrong size 152
5350
; CHECK: alpha
54-
; CHECK-NEXT: 152 152
51+
; CHECK-NEXT: 152 4
5552
; CHECK-NEXT: /t.cpp:12
5653
; CHECK-EMPTY:
5754

0 commit comments

Comments
 (0)