1 //===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Unified name mangler for assembly backends. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/IR/Mangler.h" 14 #include "llvm/ADT/SmallString.h" 15 #include "llvm/ADT/StringExtras.h" 16 #include "llvm/ADT/Twine.h" 17 #include "llvm/IR/DataLayout.h" 18 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/Function.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include "llvm/TargetParser/Triple.h" 23 using namespace llvm; 24 25 namespace { 26 enum ManglerPrefixTy { 27 Default, ///< Emit default string before each symbol. 28 Private, ///< Emit "private" prefix before each symbol. 29 LinkerPrivate ///< Emit "linker private" prefix before each symbol. 30 }; 31 } 32 33 static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName, 34 ManglerPrefixTy PrefixTy, 35 const DataLayout &DL, char Prefix) { 36 SmallString<256> TmpData; 37 StringRef Name = GVName.toStringRef(TmpData); 38 assert(!Name.empty() && "getNameWithPrefix requires non-empty name"); 39 40 // No need to do anything special if the global has the special "do not 41 // mangle" flag in the name. 42 if (Name[0] == '\1') { 43 OS << Name.substr(1); 44 return; 45 } 46 47 if (DL.doNotMangleLeadingQuestionMark() && Name[0] == '?') 48 Prefix = '\0'; 49 50 if (PrefixTy == Private) 51 OS << DL.getPrivateGlobalPrefix(); 52 else if (PrefixTy == LinkerPrivate) 53 OS << DL.getLinkerPrivateGlobalPrefix(); 54 55 if (Prefix != '\0') 56 OS << Prefix; 57 58 // If this is a simple string that doesn't need escaping, just append it. 59 OS << Name; 60 } 61 62 static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName, 63 const DataLayout &DL, 64 ManglerPrefixTy PrefixTy) { 65 char Prefix = DL.getGlobalPrefix(); 66 return getNameWithPrefixImpl(OS, GVName, PrefixTy, DL, Prefix); 67 } 68 69 void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName, 70 const DataLayout &DL) { 71 return getNameWithPrefixImpl(OS, GVName, DL, Default); 72 } 73 74 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, 75 const Twine &GVName, const DataLayout &DL) { 76 raw_svector_ostream OS(OutName); 77 char Prefix = DL.getGlobalPrefix(); 78 return getNameWithPrefixImpl(OS, GVName, Default, DL, Prefix); 79 } 80 81 static bool hasByteCountSuffix(CallingConv::ID CC) { 82 switch (CC) { 83 case CallingConv::X86_FastCall: 84 case CallingConv::X86_StdCall: 85 case CallingConv::X86_VectorCall: 86 return true; 87 default: 88 return false; 89 } 90 } 91 92 /// Microsoft fastcall and stdcall functions require a suffix on their name 93 /// indicating the number of words of arguments they take. 94 static void addByteCountSuffix(raw_ostream &OS, const Function *F, 95 const DataLayout &DL) { 96 // Calculate arguments size total. 97 unsigned ArgWords = 0; 98 99 const unsigned PtrSize = DL.getPointerSize(); 100 101 for (const Argument &A : F->args()) { 102 // For the purposes of the byte count suffix, structs returned by pointer 103 // do not count as function arguments. 104 if (A.hasStructRetAttr()) 105 continue; 106 107 // 'Dereference' type in case of byval or inalloca parameter attribute. 108 uint64_t AllocSize = A.hasPassPointeeByValueCopyAttr() ? 109 A.getPassPointeeByValueCopySize(DL) : 110 DL.getTypeAllocSize(A.getType()); 111 112 // Size should be aligned to pointer size. 113 ArgWords += alignTo(AllocSize, PtrSize); 114 } 115 116 OS << '@' << ArgWords; 117 } 118 119 void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, 120 bool CannotUsePrivateLabel) const { 121 ManglerPrefixTy PrefixTy = Default; 122 assert(GV != nullptr && "Invalid Global Value"); 123 if (GV->hasPrivateLinkage()) { 124 if (CannotUsePrivateLabel) 125 PrefixTy = LinkerPrivate; 126 else 127 PrefixTy = Private; 128 } 129 130 const DataLayout &DL = GV->getParent()->getDataLayout(); 131 if (!GV->hasName()) { 132 // Get the ID for the global, assigning a new one if we haven't got one 133 // already. 134 unsigned &ID = AnonGlobalIDs[GV]; 135 if (ID == 0) 136 ID = AnonGlobalIDs.size(); 137 138 // Must mangle the global into a unique ID. 139 getNameWithPrefixImpl(OS, "__unnamed_" + Twine(ID), DL, PrefixTy); 140 return; 141 } 142 143 StringRef Name = GV->getName(); 144 char Prefix = DL.getGlobalPrefix(); 145 146 // Mangle functions with Microsoft calling conventions specially. Only do 147 // this mangling for x86_64 vectorcall and 32-bit x86. 148 const Function *MSFunc = dyn_cast_or_null<Function>(GV->getAliaseeObject()); 149 150 // Don't add byte count suffixes when '\01' or '?' are in the first 151 // character. 152 if (Name.startswith("\01") || 153 (DL.doNotMangleLeadingQuestionMark() && Name.startswith("?"))) 154 MSFunc = nullptr; 155 156 CallingConv::ID CC = 157 MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C; 158 if (!DL.hasMicrosoftFastStdCallMangling() && 159 CC != CallingConv::X86_VectorCall) 160 MSFunc = nullptr; 161 if (MSFunc) { 162 if (CC == CallingConv::X86_FastCall) 163 Prefix = '@'; // fastcall functions have an @ prefix instead of _. 164 else if (CC == CallingConv::X86_VectorCall) 165 Prefix = '\0'; // vectorcall functions have no prefix. 166 } 167 168 getNameWithPrefixImpl(OS, Name, PrefixTy, DL, Prefix); 169 170 if (!MSFunc) 171 return; 172 173 // If we are supposed to add a microsoft-style suffix for stdcall, fastcall, 174 // or vectorcall, add it. These functions have a suffix of @N where N is the 175 // cumulative byte size of all of the parameters to the function in decimal. 176 if (CC == CallingConv::X86_VectorCall) 177 OS << '@'; // vectorcall functions use a double @ suffix. 178 FunctionType *FT = MSFunc->getFunctionType(); 179 if (hasByteCountSuffix(CC) && 180 // "Pure" variadic functions do not receive @0 suffix. 181 (!FT->isVarArg() || FT->getNumParams() == 0 || 182 (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr()))) 183 addByteCountSuffix(OS, MSFunc, DL); 184 } 185 186 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, 187 const GlobalValue *GV, 188 bool CannotUsePrivateLabel) const { 189 raw_svector_ostream OS(OutName); 190 getNameWithPrefix(OS, GV, CannotUsePrivateLabel); 191 } 192 193 // Check if the name needs quotes to be safe for the linker to interpret. 194 static bool canBeUnquotedInDirective(char C) { 195 return isAlnum(C) || C == '_' || C == '@'; 196 } 197 198 static bool canBeUnquotedInDirective(StringRef Name) { 199 if (Name.empty()) 200 return false; 201 202 // If any of the characters in the string is an unacceptable character, force 203 // quotes. 204 for (char C : Name) { 205 if (!canBeUnquotedInDirective(C)) 206 return false; 207 } 208 209 return true; 210 } 211 212 void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV, 213 const Triple &TT, Mangler &Mangler) { 214 if (GV->hasDLLExportStorageClass() && !GV->isDeclaration()) { 215 216 if (TT.isWindowsMSVCEnvironment()) 217 OS << " /EXPORT:"; 218 else 219 OS << " -export:"; 220 221 bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName()); 222 if (NeedQuotes) 223 OS << "\""; 224 if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) { 225 std::string Flag; 226 raw_string_ostream FlagOS(Flag); 227 Mangler.getNameWithPrefix(FlagOS, GV, false); 228 FlagOS.flush(); 229 if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix()) 230 OS << Flag.substr(1); 231 else 232 OS << Flag; 233 } else { 234 Mangler.getNameWithPrefix(OS, GV, false); 235 } 236 if (NeedQuotes) 237 OS << "\""; 238 239 if (!GV->getValueType()->isFunctionTy()) { 240 if (TT.isWindowsMSVCEnvironment()) 241 OS << ",DATA"; 242 else 243 OS << ",data"; 244 } 245 } 246 if (GV->hasHiddenVisibility() && !GV->isDeclaration() && TT.isOSCygMing()) { 247 248 OS << " -exclude-symbols:"; 249 250 bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName()); 251 if (NeedQuotes) 252 OS << "\""; 253 254 std::string Flag; 255 raw_string_ostream FlagOS(Flag); 256 Mangler.getNameWithPrefix(FlagOS, GV, false); 257 FlagOS.flush(); 258 if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix()) 259 OS << Flag.substr(1); 260 else 261 OS << Flag; 262 263 if (NeedQuotes) 264 OS << "\""; 265 } 266 } 267 268 void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV, 269 const Triple &T, Mangler &M) { 270 if (!T.isWindowsMSVCEnvironment()) 271 return; 272 273 OS << " /INCLUDE:"; 274 bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName()); 275 if (NeedQuotes) 276 OS << "\""; 277 M.getNameWithPrefix(OS, GV, false); 278 if (NeedQuotes) 279 OS << "\""; 280 } 281 282