diff options
-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: } |