[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
This commit is contained in:
jasonliu 2019-11-25 15:02:01 +00:00
parent d1782133d9
commit 906ecae2ed
5 changed files with 79 additions and 10 deletions

View File

@ -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);

View File

@ -48,6 +48,8 @@ public:
return ContainingCsect;
}
bool hasContainingCsect() const { return ContainingCsect != nullptr; }
private:
Optional<XCOFF::StorageClass> StorageClass;
MCSectionXCOFF *ContainingCsect = nullptr;

View File

@ -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 =

View File

@ -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;

View File

@ -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: }