void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( raw_ostream &OS, const GlobalValue *GV, const Mangler &Mang) const { if (!GV->hasDLLExportStorageClass() || GV->isDeclaration()) return; const Triple &TT = getTargetTriple(); if (TT.isKnownWindowsMSVCEnvironment()) OS << " /EXPORT:"; else OS << " -export:"; if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) { std::string Flag; raw_string_ostream FlagOS(Flag); Mang.getNameWithPrefix(FlagOS, GV, false); FlagOS.flush(); if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix()) OS << Flag.substr(1); else OS << Flag; } else { Mang.getNameWithPrefix(OS, GV, false); } if (!GV->getValueType()->isFunctionTy()) { if (TT.isKnownWindowsMSVCEnvironment()) OS << ",DATA"; else OS << ",data"; } }
void LTOCodeGenerator:: applyRestriction(GlobalValue &GV, const ArrayRef<StringRef> &Libcalls, std::vector<const char*> &MustPreserveList, SmallPtrSet<GlobalValue*, 8> &AsmUsed, Mangler &Mangler) { SmallString<64> Buffer; Mangler.getNameWithPrefix(Buffer, &GV); if (GV.isDeclaration()) return; if (MustPreserveSymbols.count(Buffer)) MustPreserveList.push_back(GV.getName().data()); if (AsmUndefinedRefs.count(Buffer)) AsmUsed.insert(&GV); // Conservatively append user-supplied runtime library functions to // llvm.compiler.used. These could be internalized and deleted by // optimizations like -globalopt, causing problems when later optimizations // add new library calls (e.g., llvm.memset => memset and printf => puts). // Leave it to the linker to remove any dead code (e.g. with -dead_strip). if (isa<Function>(GV) && std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName())) AsmUsed.insert(&GV); }
std::string ExecutionEngine::getMangledName(const GlobalValue *GV) { MutexGuard locked(lock); Mangler Mang; SmallString<128> FullName; Mang.getNameWithPrefix(FullName, GV, false); return FullName.str(); }
void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV, const Triple &T, Mangler &M) { if (!T.isKnownWindowsMSVCEnvironment()) return; OS << " /INCLUDE:"; M.getNameWithPrefix(OS, GV, false); }
void TargetLoweringObjectFileMachO::getNameWithPrefix( SmallVectorImpl<char> &OutName, const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM) const { SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); const MCSection *TheSection = SectionForGlobal(GV, GVKind, Mang, TM); bool CannotUsePrivateLabel = !canUsePrivateLabel(*TM.getMCAsmInfo(), *TheSection); Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); }
void TargetLoweringObjectFileCOFF::getNameWithPrefix( SmallVectorImpl<char> &OutName, const GlobalValue *GV, bool CannotUsePrivateLabel, Mangler &Mang, const TargetMachine &TM) const { if (GV->hasPrivateLinkage() && ((isa<Function>(GV) && TM.getFunctionSections()) || (isa<GlobalVariable>(GV) && TM.getDataSections()))) CannotUsePrivateLabel = true; Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); }
std::string mangle(const GlobalValue *GV) { std::string MangledName; { Mangler Mang; raw_string_ostream MangledNameStream(MangledName); Mang.getNameWithPrefix(MangledNameStream, GV, false); } return MangledName; }
void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate) const { if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) { // Simple case: If GV is not private, it is not important to find out if // private labels are legal in this case or not. Mang.getNameWithPrefix(Name, GV, false); return; } const TargetLoweringObjectFile *TLOF = getObjFileLowering(); TLOF->getNameWithPrefix(Name, GV, Mang, *this); }
void LTOCodeGenerator::applyScopeRestrictions() { if (ScopeRestrictionsDone) return; // Declare a callback for the internalize pass that will ask for every // candidate GlobalValue if it can be internalized or not. Mangler Mang; SmallString<64> MangledName; auto mustPreserveGV = [&](const GlobalValue &GV) -> bool { // Unnamed globals can't be mangled, but they can't be preserved either. if (!GV.hasName()) return false; // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled // with the linker supplied name, which on Darwin includes a leading // underscore. MangledName.clear(); MangledName.reserve(GV.getName().size() + 1); Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); return MustPreserveSymbols.count(MangledName); }; // Preserve linkonce value on linker request preserveDiscardableGVs(*MergedModule, mustPreserveGV); if (!ShouldInternalize) return; if (ShouldRestoreGlobalsLinkage) { // Record the linkage type of non-local symbols so they can be restored // prior // to module splitting. auto RecordLinkage = [&](const GlobalValue &GV) { if (!GV.hasAvailableExternallyLinkage() && !GV.hasLocalLinkage() && GV.hasName()) ExternalSymbols.insert(std::make_pair(GV.getName(), GV.getLinkage())); }; for (auto &GV : *MergedModule) RecordLinkage(GV); for (auto &GV : MergedModule->globals()) RecordLinkage(GV); for (auto &GV : MergedModule->aliases()) RecordLinkage(GV); } // Update the llvm.compiler_used globals to force preserving libcalls and // symbols referenced from asm updateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs); internalizeModule(*MergedModule, mustPreserveGV); ScopeRestrictionsDone = true; }
void LTOCodeGenerator:: applyRestriction(GlobalValue &GV, std::vector<const char*> &mustPreserveList, SmallPtrSet<GlobalValue*, 8> &asmUsed, Mangler &mangler) { SmallString<64> Buffer; mangler.getNameWithPrefix(Buffer, &GV, false); if (GV.isDeclaration()) return; if (_mustPreserveSymbols.count(Buffer)) mustPreserveList.push_back(GV.getName().data()); if (_asmUndefinedRefs.count(Buffer)) asmUsed.insert(&GV); }
void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV, Mangler &Mang, bool MayAlwaysUsePrivate) const { if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) { // Simple case: If GV is not private, it is not important to find out if // private labels are legal in this case or not. Mang.getNameWithPrefix(Name, GV, false); return; } SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, *this); const TargetLoweringObjectFile *TLOF = getObjFileLowering(); const MCSection *TheSection = TLOF->SectionForGlobal(GV, GVKind, Mang, *this); bool CannotUsePrivateLabel = !canUsePrivateLabel(*AsmInfo, *TheSection); TLOF->getNameWithPrefix(Name, GV, CannotUsePrivateLabel, Mang, *this); }
static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ const TargetMachine &TM = AP.TM; Mangler *Mang = AP.Mang; const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); MCContext &Ctx = AP.OutContext; bool isDarwin = Triple(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) 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"); Mang->getNameWithPrefix(Name, MO.getSymbolName()); } else { const GlobalValue *GV = MO.getGlobal(); TM.getNameWithPrefix(Name, GV, *Mang); } unsigned OrigLen = Name.size() - PrefixLen; Name += Suffix; MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); 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. if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) { MachineModuleInfoMachO &MachO = getMachOMMI(AP); MachineModuleInfoImpl::StubValueTy &StubSym = (MO.getTargetFlags() & PPCII::MO_NLP_HIDDEN_FLAG) ? MachO.getHiddenGVStubEntry(Sym) : MachO.getGVStubEntry(Sym); if (!StubSym.getPointer()) { assert(MO.isGlobal() && "Extern symbol not handled yet"); StubSym = MachineModuleInfoImpl:: StubValueTy(AP.getSymbol(MO.getGlobal()), !MO.getGlobal()->hasInternalLinkage()); } return Sym; } return Sym; }
void TargetLoweringObjectFile::getNameWithPrefix( SmallVectorImpl<char> &OutName, const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM) const { Mang.getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/false); }
void RecordStreamer::flushSymverDirectives() { // Mapping from mangled name to GV. StringMap<const GlobalValue *> MangledNameMap; // The name in the assembler will be mangled, but the name in the IR // might not, so we first compute a mapping from mangled name to GV. Mangler Mang; SmallString<64> MangledName; for (const GlobalValue &GV : M.global_values()) { if (!GV.hasName()) continue; MangledName.clear(); MangledName.reserve(GV.getName().size() + 1); Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); MangledNameMap[MangledName] = &GV; } // Walk all the recorded .symver aliases, and set up the binding // for each alias. for (auto &Symver : SymverAliasMap) { const MCSymbol *Aliasee = Symver.first; MCSymbolAttr Attr = MCSA_Invalid; bool IsDefined = false; // First check if the aliasee binding was recorded in the asm. RecordStreamer::State state = getSymbolState(Aliasee); switch (state) { case RecordStreamer::Global: case RecordStreamer::DefinedGlobal: Attr = MCSA_Global; break; case RecordStreamer::UndefinedWeak: case RecordStreamer::DefinedWeak: Attr = MCSA_Weak; break; default: break; } switch (state) { case RecordStreamer::Defined: case RecordStreamer::DefinedGlobal: case RecordStreamer::DefinedWeak: IsDefined = true; break; case RecordStreamer::NeverSeen: case RecordStreamer::Global: case RecordStreamer::Used: case RecordStreamer::UndefinedWeak: break; } if (Attr == MCSA_Invalid || !IsDefined) { const GlobalValue *GV = M.getNamedValue(Aliasee->getName()); if (!GV) { auto MI = MangledNameMap.find(Aliasee->getName()); if (MI != MangledNameMap.end()) GV = MI->second; } if (GV) { // If we don't have a symbol attribute from assembly, then check if // the aliasee was defined in the IR. if (Attr == MCSA_Invalid) { if (GV->hasExternalLinkage()) Attr = MCSA_Global; else if (GV->hasLocalLinkage()) Attr = MCSA_Local; else if (GV->isWeakForLinker()) Attr = MCSA_Weak; } IsDefined = IsDefined || !GV->isDeclarationForLinker(); } } // Set the detected binding on each alias with this aliasee. for (auto AliasName : Symver.second) { std::pair<StringRef, StringRef> Split = AliasName.split("@@@"); SmallString<128> NewName; if (!Split.second.empty() && !Split.second.startswith("@")) { // Special processing for "@@@" according // https://sourceware.org/binutils/docs/as/Symver.html const char *Separator = IsDefined ? "@@" : "@"; AliasName = (Split.first + Separator + Split.second).toStringRef(NewName); } MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be // converted into @ or @@. const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext()); if (IsDefined) markDefined(*Alias); // Don't use EmitAssignment override as it always marks alias as defined. MCStreamer::EmitAssignment(Alias, Value); if (Attr != MCSA_Invalid) EmitSymbolAttribute(Alias, Attr); } } }
// Ensure ELF .symver aliases get the same binding as the defined symbol // they alias with. static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) { if (Streamer.symverAliases().empty()) return; // The name in the assembler will be mangled, but the name in the IR // might not, so we first compute a mapping from mangled name to GV. Mangler Mang; SmallString<64> MangledName; StringMap<const GlobalValue *> MangledNameMap; auto GetMangledName = [&](const GlobalValue &GV) { if (!GV.hasName()) return; MangledName.clear(); MangledName.reserve(GV.getName().size() + 1); Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false); MangledNameMap[MangledName] = &GV; }; for (const Function &F : M) GetMangledName(F); for (const GlobalVariable &GV : M.globals()) GetMangledName(GV); for (const GlobalAlias &GA : M.aliases()) GetMangledName(GA); // Walk all the recorded .symver aliases, and set up the binding // for each alias. for (auto &Symver : Streamer.symverAliases()) { const MCSymbol *Aliasee = Symver.first; MCSymbolAttr Attr = MCSA_Invalid; // First check if the aliasee binding was recorded in the asm. RecordStreamer::State state = Streamer.getSymbolState(Aliasee); switch (state) { case RecordStreamer::Global: case RecordStreamer::DefinedGlobal: Attr = MCSA_Global; break; case RecordStreamer::UndefinedWeak: case RecordStreamer::DefinedWeak: Attr = MCSA_Weak; break; default: break; } // If we don't have a symbol attribute from assembly, then check if // the aliasee was defined in the IR. if (Attr == MCSA_Invalid) { const auto *GV = M.getNamedValue(Aliasee->getName()); if (!GV) { auto MI = MangledNameMap.find(Aliasee->getName()); if (MI != MangledNameMap.end()) GV = MI->second; else continue; } if (GV->hasExternalLinkage()) Attr = MCSA_Global; else if (GV->hasLocalLinkage()) Attr = MCSA_Local; else if (GV->isWeakForLinker()) Attr = MCSA_Weak; } if (Attr == MCSA_Invalid) continue; // Set the detected binding on each alias with this aliasee. for (auto &Alias : Symver.second) Streamer.EmitSymbolAttribute(Alias, Attr); } }