Skip to content

Commit a2c8cd1

Browse files
author
diggerlin
committed
[AIX] emit .extern and .weak directive linkage
SUMMARY: emit .extern and .weak directive linkage Reviewers: hubert.reinterpretcast, Jason Liu Subscribers: wuzish, nemanjai, hiraditya Differential Revision: https://reviews.llvm.org/D76932
1 parent f6cdcb0 commit a2c8cd1

17 files changed

+1209
-58
lines changed

llvm/include/llvm/MC/MCAsmInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ class MCAsmInfo {
307307
/// false.
308308
bool HasAltEntry = false;
309309

310+
/// True if this target supports the XCOFF .extern directive. Defaults to
311+
/// false.
312+
bool HasDotExternDirective = false;
313+
310314
/// Used to declare a global as being a weak symbol. Defaults to ".weak".
311315
const char *WeakDirective;
312316

@@ -583,6 +587,7 @@ class MCAsmInfo {
583587
bool hasIdentDirective() const { return HasIdentDirective; }
584588
bool hasNoDeadStrip() const { return HasNoDeadStrip; }
585589
bool hasAltEntry() const { return HasAltEntry; }
590+
bool hasDotExternDirective() const { return HasDotExternDirective; }
586591
const char *getWeakDirective() const { return WeakDirective; }
587592
const char *getWeakRefDirective() const { return WeakRefDirective; }
588593
bool hasWeakDefDirective() const { return HasWeakDefDirective; }

llvm/include/llvm/MC/MCDirectives.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum MCSymbolAttr {
2929
MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object
3030
MCSA_Global, ///< .globl
3131
MCSA_LGlobal, ///< .lglobl (XCOFF)
32+
MCSA_Extern, ///< .extern (XCOFF)
3233
MCSA_Hidden, ///< .hidden (ELF)
3334
MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
3435
MCSA_Internal, ///< .internal (ELF)

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,8 @@ void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
395395
GlobalValue::LinkageTypes Linkage = GV->getLinkage();
396396
switch (Linkage) {
397397
case GlobalValue::CommonLinkage:
398+
assert(!TM.getTargetTriple().isOSBinFormatXCOFF() &&
399+
"CommonLinkage of XCOFF should not come to this path.");
398400
case GlobalValue::LinkOnceAnyLinkage:
399401
case GlobalValue::LinkOnceODRLinkage:
400402
case GlobalValue::WeakAnyLinkage:
@@ -418,18 +420,25 @@ void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
418420
}
419421
return;
420422
case GlobalValue::ExternalLinkage:
421-
// If external, declare as a global symbol: .globl _foo
422-
OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);
423+
if (MAI->hasDotExternDirective() && GV->isDeclaration())
424+
OutStreamer->emitSymbolAttribute(GVSym, MCSA_Extern);
425+
else
426+
OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);
423427
return;
424428
case GlobalValue::PrivateLinkage:
425429
return;
426430
case GlobalValue::InternalLinkage:
427431
if (MAI->hasDotLGloblDirective())
428432
OutStreamer->emitSymbolAttribute(GVSym, MCSA_LGlobal);
429433
return;
434+
case GlobalValue::ExternalWeakLinkage:
435+
if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
436+
OutStreamer->emitSymbolAttribute(GVSym, MCSA_Weak);
437+
return;
438+
}
439+
LLVM_FALLTHROUGH;
430440
case GlobalValue::AppendingLinkage:
431441
case GlobalValue::AvailableExternallyLinkage:
432-
case GlobalValue::ExternalWeakLinkage:
433442
llvm_unreachable("Should never emit this");
434443
}
435444
llvm_unreachable("Unknown linkage type!");
@@ -1489,15 +1498,30 @@ bool AsmPrinter::doFinalization(Module &M) {
14891498
// Emit remaining GOT equivalent globals.
14901499
emitGlobalGOTEquivs();
14911500

1492-
// Emit visibility info for declarations
1501+
// Emit linkage(XCOFF) and visibility info for declarations
14931502
for (const Function &F : M) {
14941503
if (!F.isDeclarationForLinker())
14951504
continue;
1505+
1506+
MCSymbol *Name = getSymbol(&F);
1507+
// Function getSymbol gives us the function descriptor symbol for XCOFF.
1508+
if (TM.getTargetTriple().isOSBinFormatXCOFF() && !F.isIntrinsic()) {
1509+
1510+
// Get the function entry point symbol.
1511+
MCSymbol *FnEntryPointSym = OutContext.getOrCreateSymbol(
1512+
"." + cast<MCSymbolXCOFF>(Name)->getUnqualifiedName());
1513+
if (cast<MCSymbolXCOFF>(FnEntryPointSym)->hasRepresentedCsectSet())
1514+
// Emit linkage for the function entry point.
1515+
emitLinkage(&F, FnEntryPointSym);
1516+
1517+
// Emit linkage for the function descriptor.
1518+
emitLinkage(&F, Name);
1519+
}
1520+
14961521
GlobalValue::VisibilityTypes V = F.getVisibility();
14971522
if (V == GlobalValue::DefaultVisibility)
14981523
continue;
14991524

1500-
MCSymbol *Name = getSymbol(&F);
15011525
emitVisibility(Name, V, false);
15021526
}
15031527

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,15 +2131,19 @@ XCOFF::StorageClass TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(
21312131
case GlobalValue::CommonLinkage:
21322132
return XCOFF::C_EXT;
21332133
case GlobalValue::ExternalWeakLinkage:
2134+
case GlobalValue::LinkOnceAnyLinkage:
21342135
case GlobalValue::LinkOnceODRLinkage:
2136+
case GlobalValue::WeakAnyLinkage:
2137+
case GlobalValue::WeakODRLinkage:
21352138
return XCOFF::C_WEAKEXT;
21362139
case GlobalValue::AppendingLinkage:
21372140
report_fatal_error(
21382141
"There is no mapping that implements AppendingLinkage for XCOFF.");
2139-
default:
2140-
report_fatal_error(
2141-
"Unhandled linkage when mapping linkage to StorageClass.");
2142+
case GlobalValue::AvailableExternallyLinkage:
2143+
report_fatal_error("unhandled AvailableExternallyLinkage when mapping "
2144+
"linkage to StorageClass");
21422145
}
2146+
llvm_unreachable("Unknown linkage type!");
21432147
}
21442148

21452149
MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor(

llvm/lib/MC/MCAsmInfoXCOFF.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void MCAsmInfoXCOFF::anchor() {}
1515
MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
1616
IsLittleEndian = false;
1717
HasDotTypeDotSizeDirective = false;
18+
HasDotExternDirective = true;
1819
COMMDirectiveAlignmentIsInBytes = false;
1920
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
2021
UseDotAlignForAlignment = true;

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,9 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
675675
break;
676676
case MCSA_Protected: OS << "\t.protected\t"; break;
677677
case MCSA_Reference: OS << "\t.reference\t"; break;
678+
case MCSA_Extern:
679+
OS << "\t.extern\t";
680+
break;
678681
case MCSA_Weak: OS << MAI->getWeakDirective(); break;
679682
case MCSA_WeakDefinition:
680683
OS << "\t.weak_definition\t";

llvm/lib/MC/MCXCOFFStreamer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,18 @@ bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
3535

3636
switch (Attribute) {
3737
case MCSA_Global:
38+
case MCSA_Extern:
3839
Symbol->setStorageClass(XCOFF::C_EXT);
3940
Symbol->setExternal(true);
4041
break;
4142
case MCSA_LGlobal:
4243
Symbol->setStorageClass(XCOFF::C_HIDEXT);
4344
Symbol->setExternal(true);
4445
break;
46+
case llvm::MCSA_Weak:
47+
Symbol->setStorageClass(XCOFF::C_WEAKEXT);
48+
Symbol->setExternal(true);
49+
break;
4550
default:
4651
report_fatal_error("Not implemented yet.");
4752
}

llvm/lib/MC/XCOFFObjectWriter.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -354,21 +354,24 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
354354
// Handle undefined symbol.
355355
UndefinedCsects.emplace_back(ContainingCsect);
356356
SectionMap[ContainingCsect] = &UndefinedCsects.back();
357-
} else {
358-
// If the symbol is the csect itself, we don't need to put the symbol
359-
// into csect's Syms.
360-
if (XSym == ContainingCsect->getQualNameSymbol())
361-
continue;
357+
if (nameShouldBeInStringTable(ContainingCsect->getName()))
358+
Strings.add(ContainingCsect->getName());
359+
continue;
360+
}
362361

363-
// Only put a label into the symbol table when it is an external label.
364-
if (!XSym->isExternal())
365-
continue;
362+
// If the symbol is the csect itself, we don't need to put the symbol
363+
// into csect's Syms.
364+
if (XSym == ContainingCsect->getQualNameSymbol())
365+
continue;
366366

367-
assert(SectionMap.find(ContainingCsect) != SectionMap.end() &&
368-
"Expected containing csect to exist in map");
369-
// Lookup the containing csect and add the symbol to it.
370-
SectionMap[ContainingCsect]->Syms.emplace_back(XSym);
371-
}
367+
// Only put a label into the symbol table when it is an external label.
368+
if (!XSym->isExternal())
369+
continue;
370+
371+
assert(SectionMap.find(ContainingCsect) != SectionMap.end() &&
372+
"Expected containing csect to exist in map");
373+
// Lookup the containing csect and add the symbol to it.
374+
SectionMap[ContainingCsect]->Syms.emplace_back(XSym);
372375

373376
// If the name does not fit in the storage provided in the symbol table
374377
// entry, add it to the string table.

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,9 +1616,10 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
16161616
GVSym->setStorageClass(
16171617
TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
16181618

1619-
// External global variables are already handled.
1620-
if (GV->isDeclaration())
1619+
if (GV->isDeclarationForLinker()) {
1620+
emitLinkage(GV, GVSym);
16211621
return;
1622+
}
16221623

16231624
SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
16241625
if (!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly())
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
2+
; RUN: FileCheck %s
3+
4+
; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
5+
; RUN: FileCheck %s
6+
7+
define linkonce void @_Z3fooIiEvT_() {
8+
entry:
9+
ret void
10+
}
11+
12+
; CHECK: .weak _Z3fooIiEvT_[DS]
13+
; CHECK: .weak ._Z3fooIiEvT_

llvm/test/CodeGen/PowerPC/aix-LinkOnceODRLinkage.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ entry:
99
ret void
1010
}
1111

12-
; CHECK: .weak _Z3fooIiEvT_
12+
; CHECK: .weak _Z3fooIiEvT_[DS]
1313
; CHECK: .weak ._Z3fooIiEvT_
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | \
2+
; RUN: FileCheck %s
3+
4+
; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | \
5+
; RUN: FileCheck %s
6+
7+
define weak_odr void @_Z3fooIiEvT_() {
8+
entry:
9+
ret void
10+
}
11+
12+
; CHECK: .weak _Z3fooIiEvT_[DS]
13+
; CHECK: .weak ._Z3fooIiEvT_

0 commit comments

Comments
 (0)