diff options
author | jasonliu <jasonliu.development@gmail.com> | 2019-11-25 15:02:01 +0000 |
---|---|---|
committer | jasonliu <jasonliu.development@gmail.com> | 2019-11-25 15:02:01 +0000 |
commit | 906ecae2ed8b14924236a02ffa7fc7142c5b9753 (patch) | |
tree | a4e3414d20fa6794841d4c1a33a5f0bfbcf4ffbc | |
parent | d1782133d96d316c3bc98e33a191994794a26851 (diff) | |
download | bcm5719-llvm-906ecae2ed8b14924236a02ffa7fc7142c5b9753.tar.gz bcm5719-llvm-906ecae2ed8b14924236a02ffa7fc7142c5b9753.zip |
[AIX][XCOFF] Generate undefined symbol in symbol table for external function call
Summary:
This patch sets up the infrastructure for
1. Associate MCSymbolXCOFF with an MCSectionXCOFF when it could not
get implicitly associated.
2. Generate undefined symbols. The patch itself generates undefined symbol
for external function call only. Generate undefined symbol for external
global variable and external function descriptors will be handled in
separate patch(s) after this is land.
Differential Revision: https://reviews.llvm.org/D70443
-rw-r--r-- | llvm/include/llvm/MC/MCSectionXCOFF.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolXCOFF.h | 2 | ||||
-rw-r--r-- | llvm/lib/MC/XCOFFObjectWriter.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 16 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/aix-undef-func-call.ll | 29 |
5 files changed, 79 insertions, 10 deletions
diff --git a/llvm/include/llvm/MC/MCSectionXCOFF.h b/llvm/include/llvm/MC/MCSectionXCOFF.h index 604f17d9b13..611eb69c149 100644 --- a/llvm/include/llvm/MC/MCSectionXCOFF.h +++ b/llvm/include/llvm/MC/MCSectionXCOFF.h @@ -44,7 +44,7 @@ class MCSectionXCOFF final : public MCSection { MCSymbolXCOFF *QualName, MCSymbol *Begin) : MCSection(SV_XCOFF, K, Begin), Name(Section), MappingClass(SMC), Type(ST), StorageClass(SC), QualName(QualName) { - assert((ST == XCOFF::XTY_SD || ST == XCOFF::XTY_CM) && + assert((ST == XCOFF::XTY_SD || ST == XCOFF::XTY_CM || ST == XCOFF::XTY_ER) && "Invalid or unhandled type for csect."); assert(QualName != nullptr && "QualName is needed."); QualName->setStorageClass(SC); diff --git a/llvm/include/llvm/MC/MCSymbolXCOFF.h b/llvm/include/llvm/MC/MCSymbolXCOFF.h index 98ecd246692..8bc78174043 100644 --- a/llvm/include/llvm/MC/MCSymbolXCOFF.h +++ b/llvm/include/llvm/MC/MCSymbolXCOFF.h @@ -48,6 +48,8 @@ public: return ContainingCsect; } + bool hasContainingCsect() const { return ContainingCsect != nullptr; } + private: Optional<XCOFF::StorageClass> StorageClass; MCSectionXCOFF *ContainingCsect = nullptr; diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp index 95f950465c0..ca96a0ecf9f 100644 --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -149,6 +149,7 @@ class XCOFFObjectWriter : public MCObjectWriter { // CsectGroups. These store the csects which make up different parts of // the sections. Should have one for each set of csects that get mapped into // the same section and get handled in a 'similar' way. + CsectGroup UndefinedCsects; CsectGroup ProgramCodeCsects; CsectGroup ReadOnlyCsects; CsectGroup DataCsects; @@ -227,6 +228,8 @@ XCOFFObjectWriter::XCOFFObjectWriter( CsectGroups{&BSSCsects}) {} void XCOFFObjectWriter::reset() { + UndefinedCsects.clear(); + // Reset any sections we have written to, and empty the section header table. for (auto *Sec : Sections) Sec->reset(); @@ -291,6 +294,8 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const auto *MCSec = cast<const MCSectionXCOFF>(&S); assert(WrapperMap.find(MCSec) == WrapperMap.end() && "Cannot add a csect twice."); + assert(XCOFF::XTY_ER != MCSec->getCSectType() && + "An undefined csect should not get registered."); // If the name does not fit in the storage provided in the symbol table // entry, add it to the string table. @@ -310,14 +315,20 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, // Map the symbol into its containing csect. const MCSectionXCOFF *ContainingCsect = XSym->getContainingCsect(); - assert(WrapperMap.find(ContainingCsect) != WrapperMap.end() && - "Expected containing csect to exist in map"); - // If the symbol is the Csect itself, we don't need to put the symbol - // into Csect's Syms. + // If the symbol is the csect itself, we don't need to put the symbol + // into csect's Syms. if (XSym == ContainingCsect->getQualNameSymbol()) continue; + if (XSym->isUndefined(false)) { + UndefinedCsects.emplace_back(ContainingCsect); + continue; + } + + assert(WrapperMap.find(ContainingCsect) != WrapperMap.end() && + "Expected containing csect to exist in map"); + // Lookup the containing csect and add the symbol to it. WrapperMap[ContainingCsect]->Syms.emplace_back(XSym); @@ -530,6 +541,11 @@ void XCOFFObjectWriter::writeSectionHeaderTable() { } void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) { + for (const auto &Csect : UndefinedCsects) { + writeSymbolTableEntryForControlSection( + Csect, XCOFF::ReservedSectionNum::N_UNDEF, Csect.MCCsect->getStorageClass()); + } + for (const auto *Section : Sections) { // Nothing to write for this Section. if (Section->Index == Section::UninitializedIndex) @@ -554,15 +570,25 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) { } void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) { + // The first symbol table entry is for the file name. We are not emitting it + // yet, so start at index 0. + uint32_t SymbolTableIndex = 0; + + // Calculate undefined symbol's indices. + for (auto &Csect : UndefinedCsects) { + Csect.Size = 0; + Csect.Address = 0; + Csect.SymbolTableIndex = SymbolTableIndex; + // 1 main and 1 auxiliary symbol table entry for each contained symbol. + SymbolTableIndex += 2; + } + // The address corrresponds to the address of sections and symbols in the // object file. We place the shared address 0 immediately after the // section header table. uint32_t Address = 0; // Section indices are 1-based in XCOFF. int32_t SectionIndex = 1; - // The first symbol table entry is for the file name. We are not emitting it - // yet, so start at index 0. - uint32_t SymbolTableIndex = 0; for (auto *Section : Sections) { const bool IsEmpty = diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 4d9288ce798..ff704b7299a 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -5325,8 +5325,20 @@ SDValue PPCTargetLowering::FinishCall( // C-linkage name. GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Callee); auto &Context = DAG.getMachineFunction().getMMI().getContext(); - MCSymbol *S = Context.getOrCreateSymbol(Twine(".") + - Twine(G->getGlobal()->getName())); + + MCSymbolXCOFF *S = cast<MCSymbolXCOFF>(Context.getOrCreateSymbol( + Twine(".") + Twine(G->getGlobal()->getName()))); + + const GlobalValue *GV = G->getGlobal(); + if (GV && GV->isDeclaration() && !S->hasContainingCsect()) { + // On AIX, undefined symbol need to associate with a MCSectionXCOFF to + // get the correct storage mapping class. In this case, XCOFF::XMC_PR. + MCSectionXCOFF *Sec = + Context.getXCOFFSection(S->getName(), XCOFF::XMC_PR, XCOFF::XTY_ER, + XCOFF::C_EXT, SectionKind::getMetadata()); + S->setContainingCsect(Sec); + } + Callee = DAG.getMCSymbol(S, PtrVT); // Replace the GlobalAddressSDNode Callee with the MCSymbolSDNode. Ops[1] = Callee; diff --git a/llvm/test/CodeGen/PowerPC/aix-undef-func-call.ll b/llvm/test/CodeGen/PowerPC/aix-undef-func-call.ll new file mode 100644 index 00000000000..31d707c2ae9 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-undef-func-call.ll @@ -0,0 +1,29 @@ +; RUN: llc -mtriple powerpc-ibm-aix-xcoff -filetype=obj -o %t.o < %s +; RUN: llvm-readobj --symbols %t.o | FileCheck %s + +define void @bar() { +entry: + call void bitcast (void (...)* @foo to void ()*)() + ret void +} + +declare void @foo(...) + +;CHECK: Symbol { +;CHECK: Name: .foo +;CHECK-NEXT: Value (RelocatableAddress): 0x0 +;CHECK-NEXT: Section: N_UNDEF +;CHECK-NEXT: Type: 0x0 +;CHECK-NEXT: StorageClass: C_EXT (0x2) +;CHECK-NEXT: NumberOfAuxEntries: 1 +;CHECK-NEXT: CSECT Auxiliary Entry { +;CHECK: SectionLen: 0 +;CHECK-NEXT: ParameterHashIndex: 0x0 +;CHECK-NEXT: TypeChkSectNum: 0x0 +;CHECK-NEXT: SymbolAlignmentLog2: 0 +;CHECK-NEXT: SymbolType: XTY_ER (0x0) +;CHECK-NEXT: StorageMappingClass: XMC_PR (0x0) +;CHECK-NEXT: StabInfoIndex: 0x0 +;CHECK-NEXT: StabSectNum: 0x0 +;CHECK-NEXT: } +;CHECK-NEXT: } |