/// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation
/// for MachO targets.
class MachineModuleInfoMachO : public MachineModuleInfoImpl {
- /// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub",
- /// the value is something like "_foo".
- DenseMap<MCSymbol *, StubValueTy> FnStubs;
-
/// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like
/// "Lfoo$non_lazy_ptr", the value is something like "_foo". The extra bit
/// is true if this GV is external.
public:
MachineModuleInfoMachO(const MachineModuleInfo &) {}
- StubValueTy &getFnStubEntry(MCSymbol *Sym) {
- assert(Sym && "Key cannot be null");
- return FnStubs[Sym];
- }
-
StubValueTy &getGVStubEntry(MCSymbol *Sym) {
assert(Sym && "Key cannot be null");
return GVStubs[Sym];
}
/// Accessor methods to return the set of stubs in sorted order.
- SymbolListTy GetFnStubList() { return getSortedStubs(FnStubs); }
SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); }
SymbolListTy GetThreadLocalGVStubList() {
return getSortedStubs(ThreadLocalGVStubs);
//===------------------------------------------------------------------===//
// PPC Specific MachineOperand flags.
MO_NO_FLAG,
-
- /// MO_PLT_OR_STUB - On a symbol operand "FOO", this indicates that the
- /// reference is actually to the "FOO$stub" or "FOO@plt" symbol. This is
- /// used for calls and jumps to external functions on Tiger and earlier, and
+
+ /// On a symbol operand "FOO", this indicates that the reference is actually
+ /// to "FOO@plt". This is used for calls and jumps to external functions on
/// for PIC calls on Linux and ELF systems.
- MO_PLT_OR_STUB = 1,
-
+ MO_PLT = 1,
+
/// MO_PIC_FLAG - If this bit is set, the symbol reference is relative to
/// the function's picbase, e.g. lo16(symbol-picbase).
MO_PIC_FLAG = 2,
/// MO_NLP_FLAG - If this bit is set, the symbol reference is actually to
/// the non_lazy_ptr for the global, e.g. lo16(symbol$non_lazy_ptr-picbase).
MO_NLP_FLAG = 4,
-
+
/// MO_NLP_HIDDEN_FLAG - If this bit is set, the symbol reference is to a
/// symbol with hidden visibility. This causes a different kind of
/// non-lazy-pointer to be generated.
/// These values identify relocations on immediates folded
/// into memory operations.
MO_DTPREL_LO = 5 << 4,
- MO_TLSLD_LO = 6 << 4,
- MO_TOC_LO = 7 << 4,
+ MO_TLSLD_LO = 6 << 4,
+ MO_TOC_LO = 7 << 4,
// Symbol for VK_PPC_TLS fixup attached to an ADD instruction
- MO_TLS = 8 << 4
+ MO_TLS = 8 << 4
};
} // end namespace PPCII
bool doFinalization(Module &M) override;
void EmitStartOfAsmFile(Module &M) override;
-
- void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
};
} // end of anonymous namespace
OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
}
-static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
- // Remove $stub suffix, add $lazy_ptr.
- StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
- return Ctx.getOrCreateSymbol(NoStub + "$lazy_ptr");
-}
-
-static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
- // Add $tmp suffix to $stub, yielding $stub$tmp.
- return Ctx.getOrCreateSymbol(Sym->getName() + "$tmp");
-}
-
-void PPCDarwinAsmPrinter::
-EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
- bool isPPC64 = getDataLayout().getPointerSizeInBits() == 64;
-
- // Construct a local MCSubtargetInfo and shadow EmitToStreamer here.
- // This is because the MachineFunction won't exist (but have not yet been
- // freed) and since we're at the global level we can use the default
- // constructed subtarget.
- std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
- TM.getTargetTriple().str(), TM.getTargetCPU(),
- TM.getTargetFeatureString()));
- auto EmitToStreamer = [&STI] (MCStreamer &S, const MCInst &Inst) {
- S.EmitInstruction(Inst, *STI);
- };
-
- const TargetLoweringObjectFileMachO &TLOFMacho =
- static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
-
- // .lazy_symbol_pointer
- MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
-
- // Output stubs for dynamically-linked functions
- if (TM.getRelocationModel() == Reloc::PIC_) {
- MCSection *StubSection = OutContext.getMachOSection(
- "__TEXT", "__picsymbolstub1",
- MachO::S_SYMBOL_STUBS | MachO::S_ATTR_PURE_INSTRUCTIONS, 32,
- SectionKind::getText());
- for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- OutStreamer->SwitchSection(StubSection);
- EmitAlignment(4);
-
- MCSymbol *Stub = Stubs[i].first;
- MCSymbol *RawSym = Stubs[i].second.getPointer();
- MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
- MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
-
- OutStreamer->EmitLabel(Stub);
- OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
-
- const MCExpr *Anon = MCSymbolRefExpr::create(AnonSymbol, OutContext);
- const MCExpr *LazyPtrExpr = MCSymbolRefExpr::create(LazyPtr, OutContext);
- const MCExpr *Sub =
- MCBinaryExpr::createSub(LazyPtrExpr, Anon, OutContext);
-
- // mflr r0
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
- // bcl 20, 31, AnonSymbol
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon));
- OutStreamer->EmitLabel(AnonSymbol);
- // mflr r11
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
- // addis r11, r11, ha16(LazyPtr - AnonSymbol)
- const MCExpr *SubHa16 = PPCMCExpr::createHa(Sub, true, OutContext);
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
- .addReg(PPC::R11)
- .addReg(PPC::R11)
- .addExpr(SubHa16));
- // mtlr r0
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
-
- // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
- // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
- const MCExpr *SubLo16 = PPCMCExpr::createLo(Sub, true, OutContext);
- EmitToStreamer(*OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
- .addReg(PPC::R12)
- .addExpr(SubLo16).addExpr(SubLo16)
- .addReg(PPC::R11));
- // mtctr r12
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
- // bctr
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTR));
-
- OutStreamer->SwitchSection(LSPSection);
- OutStreamer->EmitLabel(LazyPtr);
- OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
-
- MCSymbol *DyldStubBindingHelper =
- OutContext.getOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
- if (isPPC64) {
- // .quad dyld_stub_binding_helper
- OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 8);
- } else {
- // .long dyld_stub_binding_helper
- OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 4);
- }
- }
- OutStreamer->AddBlankLine();
- return;
- }
-
- MCSection *StubSection = OutContext.getMachOSection(
- "__TEXT", "__symbol_stub1",
- MachO::S_SYMBOL_STUBS | MachO::S_ATTR_PURE_INSTRUCTIONS, 16,
- SectionKind::getText());
- for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- MCSymbol *Stub = Stubs[i].first;
- MCSymbol *RawSym = Stubs[i].second.getPointer();
- MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
- const MCExpr *LazyPtrExpr = MCSymbolRefExpr::create(LazyPtr, OutContext);
-
- OutStreamer->SwitchSection(StubSection);
- EmitAlignment(4);
- OutStreamer->EmitLabel(Stub);
- OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
-
- // lis r11, ha16(LazyPtr)
- const MCExpr *LazyPtrHa16 =
- PPCMCExpr::createHa(LazyPtrExpr, true, OutContext);
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LIS)
- .addReg(PPC::R11)
- .addExpr(LazyPtrHa16));
-
- // ldu r12, lo16(LazyPtr)(r11)
- // lwzu r12, lo16(LazyPtr)(r11)
- const MCExpr *LazyPtrLo16 =
- PPCMCExpr::createLo(LazyPtrExpr, true, OutContext);
- EmitToStreamer(*OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
- .addReg(PPC::R12)
- .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
- .addReg(PPC::R11));
-
- // mtctr r12
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
- // bctr
- EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTR));
-
- OutStreamer->SwitchSection(LSPSection);
- OutStreamer->EmitLabel(LazyPtr);
- OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
-
- MCSymbol *DyldStubBindingHelper =
- OutContext.getOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
- if (isPPC64) {
- // .quad dyld_stub_binding_helper
- OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 8);
- } else {
- // .long dyld_stub_binding_helper
- OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 4);
- }
- }
-
- OutStreamer->AddBlankLine();
-}
-
bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
bool isPPC64 = getDataLayout().getPointerSizeInBits() == 64;
MachineModuleInfoMachO &MMIMacho =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
- MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
- if (!Stubs.empty())
- EmitFunctionStubs(Stubs);
-
if (MAI->doesSupportExceptionHandling() && MMI) {
// Add the (possibly multiple) personalities to the set of global values.
// Only referenced functions get into the Personalities list.
}
// Output stubs for dynamically-linked functions.
- Stubs = MMIMacho.GetGVStubList();
+ MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
// Output macho stubs for external and common global variables.
if (!Stubs.empty()) {
// we're building with the leopard linker or later, which automatically
// synthesizes these stubs.
const TargetMachine &TM = DAG.getTarget();
- const Triple &TargetTriple = Subtarget.getTargetTriple();
- bool OldMachOLinker =
- TargetTriple.isMacOSX() && TargetTriple.isMacOSXVersionLT(10, 5);
const Module *Mod = DAG.getMachineFunction().getFunction()->getParent();
const GlobalValue *GV = nullptr;
if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee))
GV = G->getGlobal();
bool Local = TM.shouldAssumeDSOLocal(*Mod, GV);
- bool UsePlt =
- !Local && (OldMachOLinker || (Subtarget.isTargetELF() && !isPPC64));
+ bool UsePlt = !Local && Subtarget.isTargetELF() && !isPPC64;
if (isFunctionGlobalAddress(Callee)) {
GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Callee);
// thread-specific pointer.
unsigned OpFlags = 0;
if (UsePlt)
- OpFlags = PPCII::MO_PLT_OR_STUB;
+ OpFlags = PPCII::MO_PLT;
// If the callee is a GlobalAddress/ExternalSymbol node (quite common,
// every direct call is) turn it into a TargetGlobalAddress /
unsigned char OpFlags = 0;
if (UsePlt)
- OpFlags = PPCII::MO_PLT_OR_STUB;
+ OpFlags = PPCII::MO_PLT;
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType(),
OpFlags);
PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
using namespace PPCII;
static const std::pair<unsigned, const char *> TargetFlags[] = {
- {MO_PLT_OR_STUB, "ppc-plt-or-stub"},
+ {MO_PLT, "ppc-plt"},
{MO_PIC_FLAG, "ppc-pic"},
{MO_NLP_FLAG, "ppc-nlp"},
{MO_NLP_HIDDEN_FLAG, "ppc-nlp-hidden"}};
Mangler *Mang = AP.Mang;
const DataLayout &DL = AP.getDataLayout();
MCContext &Ctx = AP.OutContext;
- bool isDarwin = TM.getTargetTriple().isOSDarwin();
SmallString<128> Name;
StringRef Suffix;
- if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB) {
- if (isDarwin)
- Suffix = "$stub";
- } else if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG)
+ if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG)
Suffix = "$non_lazy_ptr";
if (!Suffix.empty())
Name += DL.getPrivateGlobalPrefix();
- unsigned PrefixLen = Name.size();
-
if (!MO.isGlobal()) {
assert(MO.isSymbol() && "Isn't a symbol reference");
Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);
TM.getNameWithPrefix(Name, GV, *Mang);
}
- unsigned OrigLen = Name.size() - PrefixLen;
-
Name += Suffix;
MCSymbol *Sym = Ctx.getOrCreateSymbol(Name);
- StringRef OrigName = StringRef(Name).substr(PrefixLen, OrigLen);
-
- // If the target flags on the operand changes the name of the symbol, do that
- // before we return the symbol.
- if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && isDarwin) {
- MachineModuleInfoImpl::StubValueTy &StubSym =
- getMachOMMI(AP).getFnStubEntry(Sym);
- if (StubSym.getPointer())
- return Sym;
-
- if (MO.isGlobal()) {
- StubSym =
- MachineModuleInfoImpl::
- StubValueTy(AP.getSymbol(MO.getGlobal()),
- !MO.getGlobal()->hasInternalLinkage());
- } else {
- StubSym =
- MachineModuleInfoImpl::
- StubValueTy(Ctx.getOrCreateSymbol(OrigName), false);
- }
- return Sym;
- }
// If the symbol reference is actually to a non_lazy_ptr, not to the symbol,
// then add the suffix.
break;
}
- if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && !isDarwin)
+ if (MO.getTargetFlags() == PPCII::MO_PLT)
RefKind = MCSymbolRefExpr::VK_PLT;
const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx);
/// dllimport linkage on windows.
MO_DLLIMPORT,
- /// MO_DARWIN_STUB - On a symbol operand "FOO", this indicates that the
- /// reference is actually to the "FOO$stub" symbol. This is used for calls
- /// and jumps to external functions on Tiger and earlier.
- MO_DARWIN_STUB,
-
/// MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the
/// reference is actually to the "FOO$non_lazy_ptr" symbol, which is a
/// non-PIC-base-relative reference to a non-hidden dyld lazy pointer stub.
const GlobalValue *GV = MO.getGlobal();
MCSymbol *GVSym;
- if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
- GVSym = P.getSymbolWithGlobalValueBase(GV, "$stub");
- else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
+ if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
+ MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
GVSym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
else
GVSym = P.getSymbol(GV);
if (!StubSym.getPointer())
StubSym = MachineModuleInfoImpl::
StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
- } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$stub");
- MachineModuleInfoImpl::StubValueTy &StubSym =
- P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
- if (!StubSym.getPointer())
- StubSym = MachineModuleInfoImpl::
- StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
break;
case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DLLIMPORT:
- case X86II::MO_DARWIN_STUB:
// These affect the name of the symbol, not any suffix.
break;
case X86II::MO_GOT_ABSOLUTE_ADDRESS:
// Output stubs for dynamically-linked functions.
MachineModuleInfoMachO::SymbolListTy Stubs;
- Stubs = MMIMacho.GetFnStubList();
- if (!Stubs.empty()) {
- MCSection *TheSection = OutContext.getMachOSection(
- "__IMPORT", "__jump_table",
- MachO::S_SYMBOL_STUBS | MachO::S_ATTR_SELF_MODIFYING_CODE |
- MachO::S_ATTR_PURE_INSTRUCTIONS,
- 5, SectionKind::getMetadata());
- OutStreamer->SwitchSection(TheSection);
-
- for (const auto &Stub : Stubs) {
- // L_foo$stub:
- OutStreamer->EmitLabel(Stub.first);
- // .indirect_symbol _foo
- OutStreamer->EmitSymbolAttribute(Stub.second.getPointer(),
- MCSA_IndirectSymbol);
- // hlt; hlt; hlt; hlt; hlt hlt = 0xf4.
- const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4";
- OutStreamer->EmitBytes(StringRef(HltInsts, 5));
- }
-
- Stubs.clear();
- OutStreamer->AddBlankLine();
- }
-
// Output stubs for external and common global variables.
Stubs = MMIMacho.GetGVStubList();
if (!Stubs.empty()) {
{MO_NTPOFF, "x86-ntpoff"},
{MO_GOTNTPOFF, "x86-gotntpoff"},
{MO_DLLIMPORT, "x86-dllimport"},
- {MO_DARWIN_STUB, "x86-darwin-stub"},
{MO_DARWIN_NONLAZY, "x86-darwin-nonlazy"},
{MO_DARWIN_NONLAZY_PIC_BASE, "x86-darwin-nonlazy-pic-base"},
{MO_TLVP, "x86-tlvp"},
// Handle dllimport linkage.
Name += "__imp_";
break;
- case X86II::MO_DARWIN_STUB:
- Suffix = "$stub";
- break;
case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
Suffix = "$non_lazy_ptr";
if (!Suffix.empty())
Name += DL.getPrivateGlobalPrefix();
- unsigned PrefixLen = Name.size();
-
if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
AsmPrinter.getNameWithPrefix(Name, GV);
assert(Suffix.empty());
Sym = MO.getMBB()->getSymbol();
}
- unsigned OrigLen = Name.size() - PrefixLen;
Name += Suffix;
if (!Sym)
Sym = Ctx.getOrCreateSymbol(Name);
- StringRef OrigName = StringRef(Name).substr(PrefixLen, OrigLen);
-
// If the target flags on the operand changes the name of the symbol, do that
// before we return the symbol.
switch (MO.getTargetFlags()) {
}
break;
}
- case X86II::MO_DARWIN_STUB: {
- MachineModuleInfoImpl::StubValueTy &StubSym =
- getMachOMMI().getFnStubEntry(Sym);
- if (StubSym.getPointer())
- return Sym;
-
- if (MO.isGlobal()) {
- StubSym =
- MachineModuleInfoImpl::
- StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()),
- !MO.getGlobal()->hasInternalLinkage());
- } else {
- StubSym =
- MachineModuleInfoImpl::
- StubValueTy(Ctx.getOrCreateSymbol(OrigName), false);
- }
- break;
- }
}
return Sym;
// These affect the name of the symbol, not any suffix.
case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DLLIMPORT:
- case X86II::MO_DARWIN_STUB:
break;
case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break;
return X86II::MO_NO_FLAG;
}
- // PC-relative references to external symbols should go through $stub,
- // unless we're building with the leopard linker or later, which
- // automatically synthesizes these stubs.
- if (!getTargetTriple().isMacOSX() ||
- getTargetTriple().isMacOSXVersionLT(10, 5))
- return X86II::MO_DARWIN_STUB;
-
return X86II::MO_NO_FLAG;
}