mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-28 13:51:09 +00:00
[AIX] supporting the visibility attribute for aix assembly
SUMMARY: in the aix assembly , it do not have .hidden and .protected directive. in current llvm. if a function or a variable which has visibility attribute, it will generate something like the .hidden or .protected , it can not recognize by aix as. in aix assembly, the visibility attribute are support in the pseudo-op like .extern Name [ , Visibility ] .globl Name [, Visibility ] .weak Name [, Visibility ] in this patch, we implement the visibility attribute for the global variable, function or extern function . for example. extern __attribute__ ((visibility ("hidden"))) int bar(int* ip); __attribute__ ((visibility ("hidden"))) int b = 0; __attribute__ ((visibility ("hidden"))) int foo(int* ip){ return (*ip)++; } the visibility of .comm linkage do not support , we will have a separate patch for it. we have the unsupported cases ("default" and "internal") , we will implement them in a a separate patch for it. Reviewers: Jason Liu ,hubert.reinterpretcast,James Henderson Differential Revision: https://reviews.llvm.org/D75866
This commit is contained in:
parent
bdf48658a5
commit
d98ed2e336
@ -178,6 +178,17 @@ enum SymbolType : uint8_t {
|
||||
XTY_CM = 3 ///< Common csect definition. For uninitialized storage.
|
||||
};
|
||||
|
||||
/// Values for visibility as they would appear when encoded in the high 4 bits
|
||||
/// of the 16-bit unsigned n_type field of symbol table entries. Valid for
|
||||
/// 32-bit XCOFF only when the vstamp in the auxiliary header is greater than 1.
|
||||
enum VisibilityType : uint16_t {
|
||||
SYM_V_UNSPECIFIED = 0x0000,
|
||||
SYM_V_INTERNAL = 0x1000,
|
||||
SYM_V_HIDDEN = 0x2000,
|
||||
SYM_V_PROTECTED = 0x3000,
|
||||
SYM_V_EXPORTED = 0x4000
|
||||
};
|
||||
|
||||
// Relocation types, defined in `/usr/include/reloc.h`.
|
||||
enum RelocationType : uint8_t {
|
||||
R_POS = 0x00, ///< Positive relocation. Provides the address of the referenced
|
||||
|
@ -659,7 +659,7 @@ public:
|
||||
|
||||
/// This emits linkage information about \p GVSym based on \p GV, if this is
|
||||
/// supported by the target.
|
||||
void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
|
||||
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
|
||||
|
||||
/// Return the alignment for the specified \p GV.
|
||||
static Align getGVAlignment(const GlobalValue *GV, const DataLayout &DL,
|
||||
|
@ -93,6 +93,10 @@ protected:
|
||||
/// constants into comdat sections.
|
||||
bool HasCOFFComdatConstants = false;
|
||||
|
||||
/// True if this is an XCOFF target that supports visibility attributes as
|
||||
/// part of .global, .weak, .extern, and .comm. Default is false.
|
||||
bool HasVisibilityOnlyWithLinkage = false;
|
||||
|
||||
/// This is the maximum possible length of an instruction, which is needed to
|
||||
/// compute the size of an inline asm. Defaults to 4.
|
||||
unsigned MaxInstLength = 4;
|
||||
@ -506,6 +510,9 @@ public:
|
||||
bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
|
||||
bool hasCOFFAssociativeComdats() const { return HasCOFFAssociativeComdats; }
|
||||
bool hasCOFFComdatConstants() const { return HasCOFFComdatConstants; }
|
||||
bool hasVisibilityOnlyWithLinkage() const {
|
||||
return HasVisibilityOnlyWithLinkage;
|
||||
}
|
||||
|
||||
/// Returns the maximum possible encoded instruction size in bytes. If \p STI
|
||||
/// is null, this should be the maximum size for any subtarget.
|
||||
|
@ -565,6 +565,15 @@ public:
|
||||
MCSymbol *CsectSym,
|
||||
unsigned ByteAlignment);
|
||||
|
||||
/// Emit a symbol's linkage and visibilty with a linkage directive for XCOFF.
|
||||
///
|
||||
/// \param Symbol - The symbol to emit.
|
||||
/// \param Linkage - The linkage of the symbol to emit.
|
||||
/// \param Visibility - The visibility of the symbol to emit or MCSA_Invalid
|
||||
/// if the symbol does not have an explicit visibility.
|
||||
virtual void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
|
||||
MCSymbolAttr Linkage,
|
||||
MCSymbolAttr Visibility);
|
||||
/// Emit an ELF .size directive.
|
||||
///
|
||||
/// This corresponds to an assembler statement such as:
|
||||
|
@ -53,9 +53,14 @@ public:
|
||||
|
||||
void setRepresentedCsect(MCSectionXCOFF *C);
|
||||
|
||||
void setVisibilityType(XCOFF::VisibilityType SVT) { VisibilityType = SVT; };
|
||||
|
||||
XCOFF::VisibilityType getVisibilityType() const { return VisibilityType; }
|
||||
|
||||
private:
|
||||
Optional<XCOFF::StorageClass> StorageClass;
|
||||
MCSectionXCOFF *RepresentedCsect = nullptr;
|
||||
XCOFF::VisibilityType VisibilityType = XCOFF::SYM_V_UNSPECIFIED;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -29,6 +29,9 @@ public:
|
||||
void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
|
||||
MCSymbol *CsectSym,
|
||||
unsigned ByteAlign) override;
|
||||
void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
|
||||
MCSymbolAttr Linkage,
|
||||
MCSymbolAttr Visibility) override;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -700,7 +700,8 @@ void AsmPrinter::emitFunctionHeader() {
|
||||
MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM));
|
||||
OutStreamer->SwitchSection(MF->getSection());
|
||||
|
||||
emitVisibility(CurrentFnSym, F.getVisibility());
|
||||
if (!MAI->hasVisibilityOnlyWithLinkage())
|
||||
emitVisibility(CurrentFnSym, F.getVisibility());
|
||||
|
||||
if (MAI->needsFunctionDescriptors() &&
|
||||
F.getLinkage() != GlobalValue::InternalLinkage)
|
||||
@ -1517,23 +1518,29 @@ bool AsmPrinter::doFinalization(Module &M) {
|
||||
|
||||
MCSymbol *Name = getSymbol(&F);
|
||||
// Function getSymbol gives us the function descriptor symbol for XCOFF.
|
||||
if (TM.getTargetTriple().isOSBinFormatXCOFF() && !F.isIntrinsic()) {
|
||||
|
||||
// Get the function entry point symbol.
|
||||
MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(&F, TM);
|
||||
if (cast<MCSymbolXCOFF>(FnEntryPointSym)->hasRepresentedCsectSet())
|
||||
// Emit linkage for the function entry point.
|
||||
emitLinkage(&F, FnEntryPointSym);
|
||||
if (!TM.getTargetTriple().isOSBinFormatXCOFF()) {
|
||||
GlobalValue::VisibilityTypes V = F.getVisibility();
|
||||
if (V == GlobalValue::DefaultVisibility)
|
||||
continue;
|
||||
|
||||
// Emit linkage for the function descriptor.
|
||||
emitLinkage(&F, Name);
|
||||
emitVisibility(Name, V, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
GlobalValue::VisibilityTypes V = F.getVisibility();
|
||||
if (V == GlobalValue::DefaultVisibility)
|
||||
if (F.isIntrinsic())
|
||||
continue;
|
||||
|
||||
emitVisibility(Name, V, false);
|
||||
// Handle the XCOFF case.
|
||||
// Variable `Name` is the function descriptor symbol (see above). Get the
|
||||
// function entry point symbol.
|
||||
MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(&F, TM);
|
||||
if (cast<MCSymbolXCOFF>(FnEntryPointSym)->hasRepresentedCsectSet())
|
||||
// Emit linkage for the function entry point.
|
||||
emitLinkage(&F, FnEntryPointSym);
|
||||
|
||||
// Emit linkage for the function descriptor.
|
||||
emitLinkage(&F, Name);
|
||||
}
|
||||
|
||||
// Emit the remarks section contents.
|
||||
|
@ -14,6 +14,7 @@ void MCAsmInfoXCOFF::anchor() {}
|
||||
|
||||
MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
|
||||
IsLittleEndian = false;
|
||||
HasVisibilityOnlyWithLinkage = true;
|
||||
PrivateGlobalPrefix = "L..";
|
||||
PrivateLabelPrefix = "L..";
|
||||
SupportsQuotedNames = false;
|
||||
|
@ -171,6 +171,10 @@ public:
|
||||
void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
|
||||
MCSymbol *CsectSym,
|
||||
unsigned ByteAlign) override;
|
||||
void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
|
||||
MCSymbolAttr Linakge,
|
||||
MCSymbolAttr Visibility) override;
|
||||
|
||||
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
|
||||
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlignment) override;
|
||||
@ -791,6 +795,41 @@ void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
|
||||
MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {
|
||||
|
||||
switch (Linkage) {
|
||||
case MCSA_Global:
|
||||
OS << MAI->getGlobalDirective();
|
||||
break;
|
||||
case MCSA_Weak:
|
||||
OS << MAI->getWeakDirective();
|
||||
break;
|
||||
case MCSA_Extern:
|
||||
OS << "\t.extern\t";
|
||||
break;
|
||||
default:
|
||||
report_fatal_error("unhandled linkage type");
|
||||
}
|
||||
|
||||
Symbol->print(OS, MAI);
|
||||
|
||||
switch (Visibility) {
|
||||
case MCSA_Invalid:
|
||||
// Nothing to do.
|
||||
break;
|
||||
case MCSA_Hidden:
|
||||
OS << ",hidden";
|
||||
break;
|
||||
case MCSA_Protected:
|
||||
OS << ",protected";
|
||||
break;
|
||||
default:
|
||||
report_fatal_error("unexpected value for Visibility type");
|
||||
}
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
|
||||
assert(MAI->hasDotTypeDotSizeDirective());
|
||||
OS << "\t.size\t";
|
||||
|
@ -1063,6 +1063,14 @@ void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
|
||||
unsigned ByteAlign) {
|
||||
llvm_unreachable("this directive only supported on XCOFF targets");
|
||||
}
|
||||
|
||||
void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
|
||||
MCSymbolAttr Linkage,
|
||||
MCSymbolAttr Visibility) {
|
||||
llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
|
||||
"XCOFF targets");
|
||||
}
|
||||
|
||||
void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
|
||||
void MCStreamer::emitELFSymverDirective(StringRef AliasName,
|
||||
const MCSymbol *Aliasee) {}
|
||||
|
@ -48,12 +48,30 @@ bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
|
||||
Symbol->setStorageClass(XCOFF::C_WEAKEXT);
|
||||
Symbol->setExternal(true);
|
||||
break;
|
||||
case llvm::MCSA_Hidden:
|
||||
Symbol->setVisibilityType(XCOFF::SYM_V_HIDDEN);
|
||||
break;
|
||||
case llvm::MCSA_Protected:
|
||||
Symbol->setVisibilityType(XCOFF::SYM_V_PROTECTED);
|
||||
break;
|
||||
default:
|
||||
report_fatal_error("Not implemented yet.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MCXCOFFStreamer::emitXCOFFSymbolLinkageWithVisibility(
|
||||
MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {
|
||||
|
||||
emitSymbolAttribute(Symbol, Linkage);
|
||||
|
||||
// When the caller passes `MCSA_Invalid` for the visibility, do not emit one.
|
||||
if (Visibility == MCSA_Invalid)
|
||||
return;
|
||||
|
||||
emitSymbolAttribute(Symbol, Visibility);
|
||||
}
|
||||
|
||||
void MCXCOFFStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlignment) {
|
||||
getAssembler().registerSymbol(*Symbol);
|
||||
|
@ -168,6 +168,8 @@ public:
|
||||
void emitFunctionDescriptor() override;
|
||||
|
||||
void emitEndOfAsmFile(Module &) override;
|
||||
|
||||
void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const override;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@ -1577,6 +1579,61 @@ void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
|
||||
}
|
||||
}
|
||||
|
||||
void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV,
|
||||
MCSymbol *GVSym) const {
|
||||
|
||||
assert(MAI->hasVisibilityOnlyWithLinkage() &&
|
||||
"AIX's linkage directives take a visibility setting.");
|
||||
|
||||
MCSymbolAttr LinkageAttr = MCSA_Invalid;
|
||||
switch (GV->getLinkage()) {
|
||||
case GlobalValue::ExternalLinkage:
|
||||
LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
|
||||
break;
|
||||
case GlobalValue::LinkOnceAnyLinkage:
|
||||
case GlobalValue::LinkOnceODRLinkage:
|
||||
case GlobalValue::WeakAnyLinkage:
|
||||
case GlobalValue::WeakODRLinkage:
|
||||
case GlobalValue::ExternalWeakLinkage:
|
||||
LinkageAttr = MCSA_Weak;
|
||||
break;
|
||||
case GlobalValue::AvailableExternallyLinkage:
|
||||
LinkageAttr = MCSA_Extern;
|
||||
break;
|
||||
case GlobalValue::PrivateLinkage:
|
||||
return;
|
||||
case GlobalValue::InternalLinkage:
|
||||
assert(MAI->hasDotLGloblDirective() &&
|
||||
"Expecting .lglobl to be supported for AIX.");
|
||||
OutStreamer->emitSymbolAttribute(GVSym, MCSA_LGlobal);
|
||||
return;
|
||||
case GlobalValue::AppendingLinkage:
|
||||
llvm_unreachable("Should never emit this");
|
||||
case GlobalValue::CommonLinkage:
|
||||
llvm_unreachable("CommonLinkage of XCOFF should not come to this path");
|
||||
}
|
||||
|
||||
assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid.");
|
||||
|
||||
MCSymbolAttr VisibilityAttr = MCSA_Invalid;
|
||||
switch (GV->getVisibility()) {
|
||||
|
||||
// TODO: "exported" and "internal" Visibility needs to go here.
|
||||
|
||||
case GlobalValue::DefaultVisibility:
|
||||
break;
|
||||
case GlobalValue::HiddenVisibility:
|
||||
VisibilityAttr = MAI->getHiddenVisibilityAttr();
|
||||
break;
|
||||
case GlobalValue::ProtectedVisibility:
|
||||
VisibilityAttr = MAI->getProtectedVisibilityAttr();
|
||||
break;
|
||||
}
|
||||
|
||||
OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
|
||||
VisibilityAttr);
|
||||
}
|
||||
|
||||
void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
|
||||
// Setup CurrentFnDescSym and its containing csect.
|
||||
MCSectionXCOFF *FnDescSec =
|
||||
|
Loading…
Reference in New Issue
Block a user