aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp97
1 files changed, 67 insertions, 30 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
index fa4917e354e9..3fbd51887831 100644
--- a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -299,7 +299,11 @@ Expected<SymbolRef::Type>
XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
XCOFFSymbolRef XCOFFSym = toSymbolRef(Symb);
- if (XCOFFSym.isFunction())
+ Expected<bool> IsFunction = XCOFFSym.isFunction();
+ if (!IsFunction)
+ return IsFunction.takeError();
+
+ if (*IsFunction)
return SymbolRef::ST_Function;
if (XCOFF::C_FILE == XCOFFSym.getStorageClass())
@@ -689,6 +693,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();
@@ -1221,7 +1229,7 @@ std::optional<StringRef> XCOFFObjectFile::tryGetCPUName() const {
return StringRef("future");
}
-bool XCOFFSymbolRef::isFunction() const {
+Expected<bool> XCOFFSymbolRef::isFunction() const {
if (!isCsectSymbol())
return false;
@@ -1229,34 +1237,62 @@ bool XCOFFSymbolRef::isFunction() const {
return true;
Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
- if (!ExpCsectAuxEnt) {
- // If we could not get the CSECT auxiliary entry, then treat this symbol as
- // if it isn't a function. Consume the error and return `false` to move on.
- consumeError(ExpCsectAuxEnt.takeError());
- return false;
- }
+ if (!ExpCsectAuxEnt)
+ return ExpCsectAuxEnt.takeError();
const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
- // A function definition should be a label definition.
- // FIXME: This is not necessarily the case when -ffunction-sections is
- // enabled.
- if (!CsectAuxRef.isLabel())
+ if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR &&
+ CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_GL)
return false;
- if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
+ // A function definition should not be a common type symbol or an external
+ // symbol.
+ if (CsectAuxRef.getSymbolType() == XCOFF::XTY_CM ||
+ CsectAuxRef.getSymbolType() == XCOFF::XTY_ER)
return false;
- const int16_t SectNum = getSectionNumber();
- Expected<DataRefImpl> SI = OwningObjectPtr->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.
- consumeError(SI.takeError());
- return false;
+ // If the next symbol is an XTY_LD type symbol with the same address, this
+ // XTY_SD symbol is not a function. Otherwise this is a function symbol for
+ // -ffunction-sections.
+ if (CsectAuxRef.getSymbolType() == XCOFF::XTY_SD) {
+ // If this is a csect with size 0, it won't be a function definition.
+ // This is used to work around the fact that LLVM always generates below
+ // symbol for -ffunction-sections:
+ // m 0x00000000 .text 1 unamex **No Symbol**
+ // a4 0x00000000 0 0 SD PR 0 0
+ // FIXME: remove or replace this meaningless symbol.
+ if (getSize() == 0)
+ return false;
+
+ xcoff_symbol_iterator NextIt(this);
+ // If this is the last main symbol table entry, there won't be an XTY_LD
+ // type symbol below.
+ if (++NextIt == getObject()->symbol_end())
+ return true;
+
+ if (cantFail(getAddress()) != cantFail(NextIt->getAddress()))
+ return true;
+
+ // Check next symbol is XTY_LD. If so, this symbol is not a function.
+ Expected<XCOFFCsectAuxRef> NextCsectAuxEnt = NextIt->getXCOFFCsectAuxRef();
+ if (!NextCsectAuxEnt)
+ return NextCsectAuxEnt.takeError();
+
+ if (NextCsectAuxEnt.get().getSymbolType() == XCOFF::XTY_LD)
+ return false;
+
+ return true;
}
- return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
+ if (CsectAuxRef.getSymbolType() == XCOFF::XTY_LD)
+ return true;
+
+ return createError(
+ "symbol csect aux entry with index " +
+ Twine(getObject()->getSymbolIndex(CsectAuxRef.getEntryAddress())) +
+ " has invalid symbol type " +
+ Twine::utohexstr(CsectAuxRef.getSymbolType()));
}
bool XCOFFSymbolRef::isCsectSymbol() const {
@@ -1275,13 +1311,13 @@ Expected<XCOFFCsectAuxRef> 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(
@@ -1294,10 +1330,10 @@ Expected<XCOFFCsectAuxRef> 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<XCOFFCsectAuxEnt64>(AuxAddr));
}
@@ -1314,14 +1350,15 @@ Expected<StringRef> 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 OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
+ return getObject()->getStringTableEntry(getSymbol32()->NameInStrTbl.Offset);
}
- return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
+ return getObject()->getStringTableEntry(getSymbol64()->Offset);
}
// Explictly instantiate template classes.