|
59 | 59 | #include "llvm/CodeGen/TargetLowering.h"
|
60 | 60 | #include "llvm/CodeGen/TargetOpcodes.h"
|
61 | 61 | #include "llvm/CodeGen/TargetRegisterInfo.h"
|
| 62 | +#include "llvm/CodeGen/TargetSubtargetInfo.h" |
62 | 63 | #include "llvm/Config/config.h"
|
63 | 64 | #include "llvm/IR/BasicBlock.h"
|
64 | 65 | #include "llvm/IR/Comdat.h"
|
@@ -2125,24 +2126,80 @@ void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
|
2125 | 2126 | assert(!TM.getTargetTriple().isOSBinFormatXCOFF() &&
|
2126 | 2127 | "IFunc is not supported on AIX.");
|
2127 | 2128 |
|
2128 |
| - MCSymbol *Name = getSymbol(&GI); |
| 2129 | + auto EmitLinkage = [&](MCSymbol *Sym) { |
| 2130 | + if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective()) |
| 2131 | + OutStreamer->emitSymbolAttribute(Sym, MCSA_Global); |
| 2132 | + else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage()) |
| 2133 | + OutStreamer->emitSymbolAttribute(Sym, MCSA_WeakReference); |
| 2134 | + else |
| 2135 | + assert(GI.hasLocalLinkage() && "Invalid ifunc linkage"); |
| 2136 | + }; |
2129 | 2137 |
|
2130 |
| - if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective()) |
2131 |
| - OutStreamer->emitSymbolAttribute(Name, MCSA_Global); |
2132 |
| - else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage()) |
2133 |
| - OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference); |
2134 |
| - else |
2135 |
| - assert(GI.hasLocalLinkage() && "Invalid ifunc linkage"); |
| 2138 | + if (TM.getTargetTriple().isOSBinFormatELF()) { |
| 2139 | + MCSymbol *Name = getSymbol(&GI); |
| 2140 | + EmitLinkage(Name); |
| 2141 | + OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction); |
| 2142 | + emitVisibility(Name, GI.getVisibility()); |
| 2143 | + |
| 2144 | + // Emit the directives as assignments aka .set: |
| 2145 | + const MCExpr *Expr = lowerConstant(GI.getResolver()); |
| 2146 | + OutStreamer->emitAssignment(Name, Expr); |
| 2147 | + MCSymbol *LocalAlias = getSymbolPreferLocal(GI); |
| 2148 | + if (LocalAlias != Name) |
| 2149 | + OutStreamer->emitAssignment(LocalAlias, Expr); |
| 2150 | + |
| 2151 | + return; |
| 2152 | + } |
2136 | 2153 |
|
2137 |
| - OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction); |
2138 |
| - emitVisibility(Name, GI.getVisibility()); |
| 2154 | + if (!TM.getTargetTriple().isOSBinFormatMachO() || !getIFuncMCSubtargetInfo()) |
| 2155 | + llvm::report_fatal_error("IFuncs are not supported on this platform"); |
2139 | 2156 |
|
2140 |
| - // Emit the directives as assignments aka .set: |
2141 |
| - const MCExpr *Expr = lowerConstant(GI.getResolver()); |
2142 |
| - OutStreamer->emitAssignment(Name, Expr); |
2143 |
| - MCSymbol *LocalAlias = getSymbolPreferLocal(GI); |
2144 |
| - if (LocalAlias != Name) |
2145 |
| - OutStreamer->emitAssignment(LocalAlias, Expr); |
| 2157 | + // On Darwin platforms, emit a manually-constructed .symbol_resolver that |
| 2158 | + // implements the symbol resolution duties of the IFunc. |
| 2159 | + // |
| 2160 | + // Normally, this would be handled by linker magic, but unfortunately there |
| 2161 | + // are a few limitations in ld64 and ld-prime's implementation of |
| 2162 | + // .symbol_resolver that mean we can't always use them: |
| 2163 | + // |
| 2164 | + // * resolvers cannot be the target of an alias |
| 2165 | + // * resolvers cannot have private linkage |
| 2166 | + // * resolvers cannot have linkonce linkage |
| 2167 | + // * resolvers cannot appear in executables |
| 2168 | + // * resolvers cannot appear in bundles |
| 2169 | + // |
| 2170 | + // This works around that by emitting a close approximation of what the |
| 2171 | + // linker would have done. |
| 2172 | + |
| 2173 | + MCSymbol *LazyPointer = |
| 2174 | + GetExternalSymbolSymbol(GI.getName() + ".lazy_pointer"); |
| 2175 | + MCSymbol *StubHelper = GetExternalSymbolSymbol(GI.getName() + ".stub_helper"); |
| 2176 | + |
| 2177 | + OutStreamer->switchSection(OutContext.getObjectFileInfo()->getDataSection()); |
| 2178 | + |
| 2179 | + const DataLayout &DL = M.getDataLayout(); |
| 2180 | + emitAlignment(Align(DL.getPointerSize())); |
| 2181 | + OutStreamer->emitLabel(LazyPointer); |
| 2182 | + emitVisibility(LazyPointer, GI.getVisibility()); |
| 2183 | + OutStreamer->emitValue(MCSymbolRefExpr::create(StubHelper, OutContext), 8); |
| 2184 | + |
| 2185 | + OutStreamer->switchSection(OutContext.getObjectFileInfo()->getTextSection()); |
| 2186 | + |
| 2187 | + const TargetSubtargetInfo *STI = |
| 2188 | + TM.getSubtargetImpl(*GI.getResolverFunction()); |
| 2189 | + const TargetLowering *TLI = STI->getTargetLowering(); |
| 2190 | + Align TextAlign(TLI->getMinFunctionAlignment()); |
| 2191 | + |
| 2192 | + MCSymbol *Stub = getSymbol(&GI); |
| 2193 | + EmitLinkage(Stub); |
| 2194 | + OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo()); |
| 2195 | + OutStreamer->emitLabel(Stub); |
| 2196 | + emitVisibility(Stub, GI.getVisibility()); |
| 2197 | + emitMachOIFuncStubBody(M, GI, LazyPointer); |
| 2198 | + |
| 2199 | + OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo()); |
| 2200 | + OutStreamer->emitLabel(StubHelper); |
| 2201 | + emitVisibility(StubHelper, GI.getVisibility()); |
| 2202 | + emitMachOIFuncStubHelperBody(M, GI, LazyPointer); |
2146 | 2203 | }
|
2147 | 2204 |
|
2148 | 2205 | void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
|
@@ -2289,6 +2346,32 @@ bool AsmPrinter::doFinalization(Module &M) {
|
2289 | 2346 | // through user plugins.
|
2290 | 2347 | emitStackMaps();
|
2291 | 2348 |
|
| 2349 | + // Print aliases in topological order, that is, for each alias a = b, |
| 2350 | + // b must be printed before a. |
| 2351 | + // This is because on some targets (e.g. PowerPC) linker expects aliases in |
| 2352 | + // such an order to generate correct TOC information. |
| 2353 | + SmallVector<const GlobalAlias *, 16> AliasStack; |
| 2354 | + SmallPtrSet<const GlobalAlias *, 16> AliasVisited; |
| 2355 | + for (const auto &Alias : M.aliases()) { |
| 2356 | + if (Alias.hasAvailableExternallyLinkage()) |
| 2357 | + continue; |
| 2358 | + for (const GlobalAlias *Cur = &Alias; Cur; |
| 2359 | + Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) { |
| 2360 | + if (!AliasVisited.insert(Cur).second) |
| 2361 | + break; |
| 2362 | + AliasStack.push_back(Cur); |
| 2363 | + } |
| 2364 | + for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) |
| 2365 | + emitGlobalAlias(M, *AncestorAlias); |
| 2366 | + AliasStack.clear(); |
| 2367 | + } |
| 2368 | + |
| 2369 | + // IFuncs must come before deubginfo in case the backend decides to emit them |
| 2370 | + // as actual functions, since on Mach-O targets, we cannot create regular |
| 2371 | + // sections after DWARF. |
| 2372 | + for (const auto &IFunc : M.ifuncs()) |
| 2373 | + emitGlobalIFunc(M, IFunc); |
| 2374 | + |
2292 | 2375 | // Finalize debug and EH information.
|
2293 | 2376 | for (const HandlerInfo &HI : Handlers) {
|
2294 | 2377 | NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
|
@@ -2328,28 +2411,6 @@ bool AsmPrinter::doFinalization(Module &M) {
|
2328 | 2411 | }
|
2329 | 2412 | }
|
2330 | 2413 |
|
2331 |
| - // Print aliases in topological order, that is, for each alias a = b, |
2332 |
| - // b must be printed before a. |
2333 |
| - // This is because on some targets (e.g. PowerPC) linker expects aliases in |
2334 |
| - // such an order to generate correct TOC information. |
2335 |
| - SmallVector<const GlobalAlias *, 16> AliasStack; |
2336 |
| - SmallPtrSet<const GlobalAlias *, 16> AliasVisited; |
2337 |
| - for (const auto &Alias : M.aliases()) { |
2338 |
| - if (Alias.hasAvailableExternallyLinkage()) |
2339 |
| - continue; |
2340 |
| - for (const GlobalAlias *Cur = &Alias; Cur; |
2341 |
| - Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) { |
2342 |
| - if (!AliasVisited.insert(Cur).second) |
2343 |
| - break; |
2344 |
| - AliasStack.push_back(Cur); |
2345 |
| - } |
2346 |
| - for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) |
2347 |
| - emitGlobalAlias(M, *AncestorAlias); |
2348 |
| - AliasStack.clear(); |
2349 |
| - } |
2350 |
| - for (const auto &IFunc : M.ifuncs()) |
2351 |
| - emitGlobalIFunc(M, IFunc); |
2352 |
| - |
2353 | 2414 | GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
|
2354 | 2415 | assert(MI && "AsmPrinter didn't require GCModuleInfo?");
|
2355 | 2416 | for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
|
@@ -3737,7 +3798,7 @@ MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV,
|
3737 | 3798 | }
|
3738 | 3799 |
|
3739 | 3800 | /// Return the MCSymbol for the specified ExternalSymbol.
|
3740 |
| -MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { |
| 3801 | +MCSymbol *AsmPrinter::GetExternalSymbolSymbol(Twine Sym) const { |
3741 | 3802 | SmallString<60> NameStr;
|
3742 | 3803 | Mangler::getNameWithPrefix(NameStr, Sym, getDataLayout());
|
3743 | 3804 | return OutContext.getOrCreateSymbol(NameStr);
|
|
0 commit comments