summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/MC/MCSectionXCOFF.h2
-rw-r--r--llvm/include/llvm/MC/MCSymbolXCOFF.h2
-rw-r--r--llvm/lib/MC/XCOFFObjectWriter.cpp40
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp16
-rw-r--r--llvm/test/CodeGen/PowerPC/aix-undef-func-call.ll29
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: }
OpenPOWER on IntegriCloud