diff options
author | Chen Zheng <czhengsz@cn.ibm.com> | 2023-11-26 11:59:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-26 11:59:09 +0800 |
commit | abc405858d6d6212d1eb40298865771e8a3b759a (patch) | |
tree | 3b1da1717a62f54cc8f1a2083341707eea4add1b /llvm/lib/Object/XCOFFObjectFile.cpp | |
parent | 3bbed4ee26817e50ec699fe66017638ee080fc20 (diff) | |
download | llvm-abc405858d6d6212d1eb40298865771e8a3b759a.zip llvm-abc405858d6d6212d1eb40298865771e8a3b759a.tar.gz llvm-abc405858d6d6212d1eb40298865771e8a3b759a.tar.bz2 |
[XCOFF] make related SD symbols as isFunction (#69553)
This will help tools like llvm-symbolizer recognizes more functions.
Diffstat (limited to 'llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/XCOFFObjectFile.cpp | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp index 07e1054f..3fbd518 100644 --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -1242,21 +1242,57 @@ Expected<bool> XCOFFSymbolRef::isFunction() const { 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 = getObject()->getSectionByNum(SectNum); - if (!SI) - return SI.takeError(); + // 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 (getObject()->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT); + return true; + } + + 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 { |