1 //===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Unified name mangler for assembly backends. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Target/Mangler.h" 15 #include "llvm/ADT/SmallString.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/MC/MCAsmInfo.h" 21 #include "llvm/MC/MCContext.h" 22 #include "llvm/Target/TargetMachine.h" 23 #include "llvm/Support/raw_ostream.h" 24 using namespace llvm; 25 26 static bool isAcceptableChar(char C, bool AllowPeriod, bool AllowUTF8) { 27 if ((C < 'a' || C > 'z') && 28 (C < 'A' || C > 'Z') && 29 (C < '0' || C > '9') && 30 C != '_' && C != '$' && C != '@' && 31 !(AllowPeriod && C == '.') && 32 !(AllowUTF8 && (C & 0x80))) 33 return false; 34 return true; 35 } 36 37 static char HexDigit(int V) { 38 return V < 10 ? V+'0' : V+'A'-10; 39 } 40 41 static void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) { 42 OutName.push_back('_'); 43 OutName.push_back(HexDigit(C >> 4)); 44 OutName.push_back(HexDigit(C & 15)); 45 OutName.push_back('_'); 46 } 47 48 /// NameNeedsEscaping - Return true if the identifier \p Str needs quotes 49 /// for this assembler. 50 static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo *MAI) { 51 assert(!Str.empty() && "Cannot create an empty MCSymbol"); 52 53 // If the first character is a number and the target does not allow this, we 54 // need quotes. 55 if (!MAI->doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') 56 return true; 57 58 // If any of the characters in the string is an unacceptable character, force 59 // quotes. 60 bool AllowPeriod = MAI->doesAllowPeriodsInName(); 61 bool AllowUTF8 = MAI->doesAllowUTF8(); 62 for (unsigned i = 0, e = Str.size(); i != e; ++i) 63 if (!isAcceptableChar(Str[i], AllowPeriod, AllowUTF8)) 64 return true; 65 return false; 66 } 67 68 /// appendMangledName - Add the specified string in mangled form if it uses 69 /// any unusual characters. 70 static void appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str, 71 const MCAsmInfo *MAI) { 72 // The first character is not allowed to be a number unless the target 73 // explicitly allows it. 74 if (!MAI->doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') { 75 MangleLetter(OutName, Str[0]); 76 Str = Str.substr(1); 77 } 78 79 bool AllowPeriod = MAI->doesAllowPeriodsInName(); 80 bool AllowUTF8 = MAI->doesAllowUTF8(); 81 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 82 if (!isAcceptableChar(Str[i], AllowPeriod, AllowUTF8)) 83 MangleLetter(OutName, Str[i]); 84 else 85 OutName.push_back(Str[i]); 86 } 87 } 88 89 90 /// appendMangledQuotedName - On systems that support quoted symbols, we still 91 /// have to escape some (obscure) characters like " and \n which would break the 92 /// assembler's lexing. 93 static void appendMangledQuotedName(SmallVectorImpl<char> &OutName, 94 StringRef Str) { 95 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 96 if (Str[i] == '"' || Str[i] == '\n') 97 MangleLetter(OutName, Str[i]); 98 else 99 OutName.push_back(Str[i]); 100 } 101 } 102 103 104 /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix 105 /// and the specified name as the global variable name. GVName must not be 106 /// empty. 107 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, 108 const Twine &GVName, ManglerPrefixTy PrefixTy, 109 bool UseGlobalPrefix) { 110 SmallString<256> TmpData; 111 StringRef Name = GVName.toStringRef(TmpData); 112 assert(!Name.empty() && "getNameWithPrefix requires non-empty name"); 113 114 const MCAsmInfo *MAI = Context.getAsmInfo(); 115 116 // If the global name is not led with \1, add the appropriate prefixes. 117 if (Name[0] == '\1') { 118 Name = Name.substr(1); 119 } else { 120 if (PrefixTy == Mangler::Private) { 121 const char *Prefix = MAI->getPrivateGlobalPrefix(); 122 OutName.append(Prefix, Prefix+strlen(Prefix)); 123 } else if (PrefixTy == Mangler::LinkerPrivate) { 124 const char *Prefix = MAI->getLinkerPrivateGlobalPrefix(); 125 OutName.append(Prefix, Prefix+strlen(Prefix)); 126 } 127 128 if (UseGlobalPrefix) { 129 const char *Prefix = MAI->getGlobalPrefix(); 130 if (Prefix[0] == 0) 131 ; // Common noop, no prefix. 132 else if (Prefix[1] == 0) 133 OutName.push_back(Prefix[0]); // Common, one character prefix. 134 else 135 // Arbitrary length prefix. 136 OutName.append(Prefix, Prefix+strlen(Prefix)); 137 } 138 } 139 140 // If this is a simple string that doesn't need escaping, just append it. 141 if (!NameNeedsEscaping(Name, MAI) || 142 // If quotes are supported, they can be used unless the string contains 143 // a quote or newline. 144 (MAI->doesAllowQuotesInName() && 145 Name.find_first_of("\n\"") == StringRef::npos)) { 146 OutName.append(Name.begin(), Name.end()); 147 return; 148 } 149 150 // On systems that do not allow quoted names, we need to mangle most 151 // strange characters. 152 if (!MAI->doesAllowQuotesInName()) 153 return appendMangledName(OutName, Name, MAI); 154 155 // Okay, the system allows quoted strings. We can quote most anything, the 156 // only characters that need escaping are " and \n. 157 assert(Name.find_first_of("\n\"") != StringRef::npos); 158 return appendMangledQuotedName(OutName, Name); 159 } 160 161 /// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require 162 /// a suffix on their name indicating the number of words of arguments they 163 /// take. 164 static void AddFastCallStdCallSuffix(SmallVectorImpl<char> &OutName, 165 const Function *F, const DataLayout &TD) { 166 // Calculate arguments size total. 167 unsigned ArgWords = 0; 168 for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); 169 AI != AE; ++AI) { 170 Type *Ty = AI->getType(); 171 // 'Dereference' type in case of byval parameter attribute 172 if (AI->hasByValAttr()) 173 Ty = cast<PointerType>(Ty)->getElementType(); 174 // Size should be aligned to DWORD boundary 175 ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4; 176 } 177 178 raw_svector_ostream(OutName) << '@' << ArgWords; 179 } 180 181 182 /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix 183 /// and the specified global variable's name. If the global variable doesn't 184 /// have a name, this fills in a unique name for the global. 185 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, 186 const GlobalValue *GV, bool isImplicitlyPrivate, 187 bool UseGlobalPrefix) { 188 ManglerPrefixTy PrefixTy = Mangler::Default; 189 if (GV->hasPrivateLinkage() || isImplicitlyPrivate) 190 PrefixTy = Mangler::Private; 191 else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage()) 192 PrefixTy = Mangler::LinkerPrivate; 193 194 // If this global has a name, handle it simply. 195 if (GV->hasName()) { 196 StringRef Name = GV->getName(); 197 getNameWithPrefix(OutName, Name, PrefixTy, UseGlobalPrefix); 198 // No need to do anything else if the global has the special "do not mangle" 199 // flag in the name. 200 if (Name[0] == 1) 201 return; 202 } else { 203 // Get the ID for the global, assigning a new one if we haven't got one 204 // already. 205 unsigned &ID = AnonGlobalIDs[GV]; 206 if (ID == 0) ID = NextAnonGlobalID++; 207 208 // Must mangle the global into a unique ID. 209 getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy, 210 UseGlobalPrefix); 211 } 212 213 // If we are supposed to add a microsoft-style suffix for stdcall/fastcall, 214 // add it. 215 if (Context.getAsmInfo()->hasMicrosoftFastStdCallMangling()) { 216 if (const Function *F = dyn_cast<Function>(GV)) { 217 CallingConv::ID CC = F->getCallingConv(); 218 219 // fastcall functions need to start with @. 220 // FIXME: This logic seems unlikely to be right. 221 if (CC == CallingConv::X86_FastCall) { 222 if (OutName[0] == '_') 223 OutName[0] = '@'; 224 else 225 OutName.insert(OutName.begin(), '@'); 226 } 227 228 // fastcall and stdcall functions usually need @42 at the end to specify 229 // the argument info. 230 FunctionType *FT = F->getFunctionType(); 231 if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) && 232 // "Pure" variadic functions do not receive @0 suffix. 233 (!FT->isVarArg() || FT->getNumParams() == 0 || 234 (FT->getNumParams() == 1 && F->hasStructRetAttr()))) 235 AddFastCallStdCallSuffix(OutName, F, *TM->getDataLayout()); 236 } 237 } 238 } 239 240 /// getSymbol - Return the MCSymbol for the specified global value. This 241 /// symbol is the main label that is the address of the global. 242 MCSymbol *Mangler::getSymbol(const GlobalValue *GV) { 243 SmallString<60> NameStr; 244 getNameWithPrefix(NameStr, GV, false); 245 return Context.GetOrCreateSymbol(NameStr.str()); 246 } 247 248 249