diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp | 97 |
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. |