[llvm] 906ecae - [AIX][XCOFF] Generate undefined symbol in symbol table for external function call

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 25 07:18:10 PST 2019


Author: jasonliu
Date: 2019-11-25T15:02:01Z
New Revision: 906ecae2ed8b14924236a02ffa7fc7142c5b9753

URL: https://github.com/llvm/llvm-project/commit/906ecae2ed8b14924236a02ffa7fc7142c5b9753
DIFF: https://github.com/llvm/llvm-project/commit/906ecae2ed8b14924236a02ffa7fc7142c5b9753.diff

LOG: [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

Added: 
    llvm/test/CodeGen/PowerPC/aix-undef-func-call.ll

Modified: 
    llvm/include/llvm/MC/MCSectionXCOFF.h
    llvm/include/llvm/MC/MCSymbolXCOFF.h
    llvm/lib/MC/XCOFFObjectWriter.cpp
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCSectionXCOFF.h b/llvm/include/llvm/MC/MCSectionXCOFF.h
index 604f17d9b136..611eb69c1493 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 98ecd2466926..8bc781740439 100644
--- a/llvm/include/llvm/MC/MCSymbolXCOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolXCOFF.h
@@ -48,6 +48,8 @@ class MCSymbolXCOFF : public MCSymbol {
     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 95f950465c0b..ca96a0ecf9ff 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 
diff erent 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 4d9288ce7982..ff704b7299a3 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 000000000000..31d707c2ae9f
--- /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: }


        


More information about the llvm-commits mailing list