forked from OSchip/llvm-project
[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:
parent
d1782133d9
commit
906ecae2ed
|
@ -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);
|
||||
|
|
|
@ -48,6 +48,8 @@ public:
|
|||
return ContainingCsect;
|
||||
}
|
||||
|
||||
bool hasContainingCsect() const { return ContainingCsect != nullptr; }
|
||||
|
||||
private:
|
||||
Optional<XCOFF::StorageClass> StorageClass;
|
||||
MCSectionXCOFF *ContainingCsect = nullptr;
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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: }
|
Loading…
Reference in New Issue