|
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"
|
@@ -2147,24 +2148,80 @@ void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
|
2147 | 2148 | assert(!TM.getTargetTriple().isOSBinFormatXCOFF() &&
|
2148 | 2149 | "IFunc is not supported on AIX.");
|
2149 | 2150 |
|
2150 |
| - MCSymbol *Name = getSymbol(&GI); |
| 2151 | + auto EmitLinkage = [&](MCSymbol *Sym) { |
| 2152 | + if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective()) |
| 2153 | + OutStreamer->emitSymbolAttribute(Sym, MCSA_Global); |
| 2154 | + else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage()) |
| 2155 | + OutStreamer->emitSymbolAttribute(Sym, MCSA_WeakReference); |
| 2156 | + else |
| 2157 | + assert(GI.hasLocalLinkage() && "Invalid ifunc linkage"); |
| 2158 | + }; |
2151 | 2159 |
|
2152 |
| - if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective()) |
2153 |
| - OutStreamer->emitSymbolAttribute(Name, MCSA_Global); |
2154 |
| - else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage()) |
2155 |
| - OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference); |
2156 |
| - else |
2157 |
| - assert(GI.hasLocalLinkage() && "Invalid ifunc linkage"); |
| 2160 | + if (TM.getTargetTriple().isOSBinFormatELF()) { |
| 2161 | + MCSymbol *Name = getSymbol(&GI); |
| 2162 | + EmitLinkage(Name); |
| 2163 | + OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction); |
| 2164 | + emitVisibility(Name, GI.getVisibility()); |
| 2165 | + |
| 2166 | + // Emit the directives as assignments aka .set: |
| 2167 | + const MCExpr *Expr = lowerConstant(GI.getResolver()); |
| 2168 | + OutStreamer->emitAssignment(Name, Expr); |
| 2169 | + MCSymbol *LocalAlias = getSymbolPreferLocal(GI); |
| 2170 | + if (LocalAlias != Name) |
| 2171 | + OutStreamer->emitAssignment(LocalAlias, Expr); |
| 2172 | + |
| 2173 | + return; |
| 2174 | + } |
2158 | 2175 |
|
2159 |
| - OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction); |
2160 |
| - emitVisibility(Name, GI.getVisibility()); |
| 2176 | + if (!TM.getTargetTriple().isOSBinFormatMachO() || !getIFuncMCSubtargetInfo()) |
| 2177 | + llvm::report_fatal_error("IFuncs are not supported on this platform"); |
2161 | 2178 |
|
2162 |
| - // Emit the directives as assignments aka .set: |
2163 |
| - const MCExpr *Expr = lowerConstant(GI.getResolver()); |
2164 |
| - OutStreamer->emitAssignment(Name, Expr); |
2165 |
| - MCSymbol *LocalAlias = getSymbolPreferLocal(GI); |
2166 |
| - if (LocalAlias != Name) |
2167 |
| - OutStreamer->emitAssignment(LocalAlias, Expr); |
| 2179 | + // On Darwin platforms, emit a manually-constructed .symbol_resolver that |
| 2180 | + // implements the symbol resolution duties of the IFunc. |
| 2181 | + // |
| 2182 | + // Normally, this would be handled by linker magic, but unfortunately there |
| 2183 | + // are a few limitations in ld64 and ld-prime's implementation of |
| 2184 | + // .symbol_resolver that mean we can't always use them: |
| 2185 | + // |
| 2186 | + // * resolvers cannot be the target of an alias |
| 2187 | + // * resolvers cannot have private linkage |
| 2188 | + // * resolvers cannot have linkonce linkage |
| 2189 | + // * resolvers cannot appear in executables |
| 2190 | + // * resolvers cannot appear in bundles |
| 2191 | + // |
| 2192 | + // This works around that by emitting a close approximation of what the |
| 2193 | + // linker would have done. |
| 2194 | + |
| 2195 | + MCSymbol *LazyPointer = |
| 2196 | + GetExternalSymbolSymbol(GI.getName() + ".lazy_pointer"); |
| 2197 | + MCSymbol *StubHelper = GetExternalSymbolSymbol(GI.getName() + ".stub_helper"); |
| 2198 | + |
| 2199 | + OutStreamer->switchSection(OutContext.getObjectFileInfo()->getDataSection()); |
| 2200 | + |
| 2201 | + const DataLayout &DL = M.getDataLayout(); |
| 2202 | + emitAlignment(Align(DL.getPointerSize())); |
| 2203 | + OutStreamer->emitLabel(LazyPointer); |
| 2204 | + emitVisibility(LazyPointer, GI.getVisibility()); |
| 2205 | + OutStreamer->emitValue(MCSymbolRefExpr::create(StubHelper, OutContext), 8); |
| 2206 | + |
| 2207 | + OutStreamer->switchSection(OutContext.getObjectFileInfo()->getTextSection()); |
| 2208 | + |
| 2209 | + const TargetSubtargetInfo *STI = |
| 2210 | + TM.getSubtargetImpl(*GI.getResolverFunction()); |
| 2211 | + const TargetLowering *TLI = STI->getTargetLowering(); |
| 2212 | + Align TextAlign(TLI->getMinFunctionAlignment()); |
| 2213 | + |
| 2214 | + MCSymbol *Stub = getSymbol(&GI); |
| 2215 | + EmitLinkage(Stub); |
| 2216 | + OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo()); |
| 2217 | + OutStreamer->emitLabel(Stub); |
| 2218 | + emitVisibility(Stub, GI.getVisibility()); |
| 2219 | + emitMachOIFuncStubBody(M, GI, LazyPointer); |
| 2220 | + |
| 2221 | + OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo()); |
| 2222 | + OutStreamer->emitLabel(StubHelper); |
| 2223 | + emitVisibility(StubHelper, GI.getVisibility()); |
| 2224 | + emitMachOIFuncStubHelperBody(M, GI, LazyPointer); |
2168 | 2225 | }
|
2169 | 2226 |
|
2170 | 2227 | void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
|
@@ -2311,6 +2368,32 @@ bool AsmPrinter::doFinalization(Module &M) {
|
2311 | 2368 | // through user plugins.
|
2312 | 2369 | emitStackMaps();
|
2313 | 2370 |
|
| 2371 | + // Print aliases in topological order, that is, for each alias a = b, |
| 2372 | + // b must be printed before a. |
| 2373 | + // This is because on some targets (e.g. PowerPC) linker expects aliases in |
| 2374 | + // such an order to generate correct TOC information. |
| 2375 | + SmallVector<const GlobalAlias *, 16> AliasStack; |
| 2376 | + SmallPtrSet<const GlobalAlias *, 16> AliasVisited; |
| 2377 | + for (const auto &Alias : M.aliases()) { |
| 2378 | + if (Alias.hasAvailableExternallyLinkage()) |
| 2379 | + continue; |
| 2380 | + for (const GlobalAlias *Cur = &Alias; Cur; |
| 2381 | + Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) { |
| 2382 | + if (!AliasVisited.insert(Cur).second) |
| 2383 | + break; |
| 2384 | + AliasStack.push_back(Cur); |
| 2385 | + } |
| 2386 | + for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) |
| 2387 | + emitGlobalAlias(M, *AncestorAlias); |
| 2388 | + AliasStack.clear(); |
| 2389 | + } |
| 2390 | + |
| 2391 | + // IFuncs must come before deubginfo in case the backend decides to emit them |
| 2392 | + // as actual functions, since on Mach-O targets, we cannot create regular |
| 2393 | + // sections after DWARF. |
| 2394 | + for (const auto &IFunc : M.ifuncs()) |
| 2395 | + emitGlobalIFunc(M, IFunc); |
| 2396 | + |
2314 | 2397 | // Finalize debug and EH information.
|
2315 | 2398 | for (const HandlerInfo &HI : Handlers) {
|
2316 | 2399 | NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName,
|
@@ -2350,28 +2433,6 @@ bool AsmPrinter::doFinalization(Module &M) {
|
2350 | 2433 | }
|
2351 | 2434 | }
|
2352 | 2435 |
|
2353 |
| - // Print aliases in topological order, that is, for each alias a = b, |
2354 |
| - // b must be printed before a. |
2355 |
| - // This is because on some targets (e.g. PowerPC) linker expects aliases in |
2356 |
| - // such an order to generate correct TOC information. |
2357 |
| - SmallVector<const GlobalAlias *, 16> AliasStack; |
2358 |
| - SmallPtrSet<const GlobalAlias *, 16> AliasVisited; |
2359 |
| - for (const auto &Alias : M.aliases()) { |
2360 |
| - if (Alias.hasAvailableExternallyLinkage()) |
2361 |
| - continue; |
2362 |
| - for (const GlobalAlias *Cur = &Alias; Cur; |
2363 |
| - Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) { |
2364 |
| - if (!AliasVisited.insert(Cur).second) |
2365 |
| - break; |
2366 |
| - AliasStack.push_back(Cur); |
2367 |
| - } |
2368 |
| - for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) |
2369 |
| - emitGlobalAlias(M, *AncestorAlias); |
2370 |
| - AliasStack.clear(); |
2371 |
| - } |
2372 |
| - for (const auto &IFunc : M.ifuncs()) |
2373 |
| - emitGlobalIFunc(M, IFunc); |
2374 |
| - |
2375 | 2436 | GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
|
2376 | 2437 | assert(MI && "AsmPrinter didn't require GCModuleInfo?");
|
2377 | 2438 | for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
|
@@ -3745,7 +3806,7 @@ MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV,
|
3745 | 3806 | }
|
3746 | 3807 |
|
3747 | 3808 | /// Return the MCSymbol for the specified ExternalSymbol.
|
3748 |
| -MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { |
| 3809 | +MCSymbol *AsmPrinter::GetExternalSymbolSymbol(Twine Sym) const { |
3749 | 3810 | SmallString<60> NameStr;
|
3750 | 3811 | Mangler::getNameWithPrefix(NameStr, Sym, getDataLayout());
|
3751 | 3812 | return OutContext.getOrCreateSymbol(NameStr);
|
|
0 commit comments