xref: /freebsd/contrib/llvm-project/llvm/lib/IR/Mangler.cpp (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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/Demangle/Demangle.h"
18 #include "llvm/IR/DataLayout.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include "llvm/TargetParser/Triple.h"
24 
25 using namespace llvm;
26 
27 namespace {
28 enum ManglerPrefixTy {
29   Default,      ///< Emit default string before each symbol.
30   Private,      ///< Emit "private" prefix before each symbol.
31   LinkerPrivate ///< Emit "linker private" prefix before each symbol.
32 };
33 }
34 
35 static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
36                                   ManglerPrefixTy PrefixTy,
37                                   const DataLayout &DL, char Prefix) {
38   SmallString<256> TmpData;
39   StringRef Name = GVName.toStringRef(TmpData);
40   assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
41 
42   // No need to do anything special if the global has the special "do not
43   // mangle" flag in the name.
44   if (Name[0] == '\1') {
45     OS << Name.substr(1);
46     return;
47   }
48 
49   if (DL.doNotMangleLeadingQuestionMark() && Name[0] == '?')
50     Prefix = '\0';
51 
52   if (PrefixTy == Private)
53     OS << DL.getPrivateGlobalPrefix();
54   else if (PrefixTy == LinkerPrivate)
55     OS << DL.getLinkerPrivateGlobalPrefix();
56 
57   if (Prefix != '\0')
58     OS << Prefix;
59 
60   // If this is a simple string that doesn't need escaping, just append it.
61   OS << Name;
62 }
63 
64 static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
65                                   const DataLayout &DL,
66                                   ManglerPrefixTy PrefixTy) {
67   char Prefix = DL.getGlobalPrefix();
68   return getNameWithPrefixImpl(OS, GVName, PrefixTy, DL, Prefix);
69 }
70 
71 void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
72                                 const DataLayout &DL) {
73   return getNameWithPrefixImpl(OS, GVName, DL, Default);
74 }
75 
76 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
77                                 const Twine &GVName, const DataLayout &DL) {
78   raw_svector_ostream OS(OutName);
79   char Prefix = DL.getGlobalPrefix();
80   return getNameWithPrefixImpl(OS, GVName, Default, DL, Prefix);
81 }
82 
83 static bool hasByteCountSuffix(CallingConv::ID CC) {
84   switch (CC) {
85   case CallingConv::X86_FastCall:
86   case CallingConv::X86_StdCall:
87   case CallingConv::X86_VectorCall:
88     return true;
89   default:
90     return false;
91   }
92 }
93 
94 /// Microsoft fastcall and stdcall functions require a suffix on their name
95 /// indicating the number of words of arguments they take.
96 static void addByteCountSuffix(raw_ostream &OS, const Function *F,
97                                const DataLayout &DL) {
98   // Calculate arguments size total.
99   unsigned ArgWords = 0;
100 
101   const unsigned PtrSize = DL.getPointerSize();
102 
103   for (const Argument &A : F->args()) {
104     // For the purposes of the byte count suffix, structs returned by pointer
105     // do not count as function arguments.
106     if (A.hasStructRetAttr())
107       continue;
108 
109     // 'Dereference' type in case of byval or inalloca parameter attribute.
110     uint64_t AllocSize = A.hasPassPointeeByValueCopyAttr() ?
111       A.getPassPointeeByValueCopySize(DL) :
112       DL.getTypeAllocSize(A.getType());
113 
114     // Size should be aligned to pointer size.
115     ArgWords += alignTo(AllocSize, PtrSize);
116   }
117 
118   OS << '@' << ArgWords;
119 }
120 
121 void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
122                                 bool CannotUsePrivateLabel) const {
123   ManglerPrefixTy PrefixTy = Default;
124   assert(GV != nullptr && "Invalid Global Value");
125   if (GV->hasPrivateLinkage()) {
126     if (CannotUsePrivateLabel)
127       PrefixTy = LinkerPrivate;
128     else
129       PrefixTy = Private;
130   }
131 
132   const DataLayout &DL = GV->getDataLayout();
133   if (!GV->hasName()) {
134     // Get the ID for the global, assigning a new one if we haven't got one
135     // already.
136     unsigned &ID = AnonGlobalIDs[GV];
137     if (ID == 0)
138       ID = AnonGlobalIDs.size();
139 
140     // Must mangle the global into a unique ID.
141     getNameWithPrefixImpl(OS, "__unnamed_" + Twine(ID), DL, PrefixTy);
142     return;
143   }
144 
145   StringRef Name = GV->getName();
146   char Prefix = DL.getGlobalPrefix();
147 
148   // Mangle functions with Microsoft calling conventions specially.  Only do
149   // this mangling for x86_64 vectorcall and 32-bit x86.
150   const Function *MSFunc = dyn_cast_or_null<Function>(GV->getAliaseeObject());
151 
152   // Don't add byte count suffixes when '\01' or '?' are in the first
153   // character.
154   if (Name.starts_with("\01") ||
155       (DL.doNotMangleLeadingQuestionMark() && Name.starts_with("?")))
156     MSFunc = nullptr;
157 
158   CallingConv::ID CC =
159       MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C;
160   if (!DL.hasMicrosoftFastStdCallMangling() &&
161       CC != CallingConv::X86_VectorCall)
162     MSFunc = nullptr;
163   if (MSFunc) {
164     if (CC == CallingConv::X86_FastCall)
165       Prefix = '@'; // fastcall functions have an @ prefix instead of _.
166     else if (CC == CallingConv::X86_VectorCall)
167       Prefix = '\0'; // vectorcall functions have no prefix.
168   }
169 
170   getNameWithPrefixImpl(OS, Name, PrefixTy, DL, Prefix);
171 
172   if (!MSFunc)
173     return;
174 
175   // If we are supposed to add a microsoft-style suffix for stdcall, fastcall,
176   // or vectorcall, add it.  These functions have a suffix of @N where N is the
177   // cumulative byte size of all of the parameters to the function in decimal.
178   if (CC == CallingConv::X86_VectorCall)
179     OS << '@'; // vectorcall functions use a double @ suffix.
180   FunctionType *FT = MSFunc->getFunctionType();
181   if (hasByteCountSuffix(CC) &&
182       // "Pure" variadic functions do not receive @0 suffix.
183       (!FT->isVarArg() || FT->getNumParams() == 0 ||
184        (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr())))
185     addByteCountSuffix(OS, MSFunc, DL);
186 }
187 
188 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
189                                 const GlobalValue *GV,
190                                 bool CannotUsePrivateLabel) const {
191   raw_svector_ostream OS(OutName);
192   getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
193 }
194 
195 // Check if the name needs quotes to be safe for the linker to interpret.
196 static bool canBeUnquotedInDirective(char C) {
197   return isAlnum(C) || C == '_' || C == '@' || C == '#';
198 }
199 
200 static bool canBeUnquotedInDirective(StringRef Name) {
201   if (Name.empty())
202     return false;
203 
204   // If any of the characters in the string is an unacceptable character, force
205   // quotes.
206   for (char C : Name) {
207     if (!canBeUnquotedInDirective(C))
208       return false;
209   }
210 
211   return true;
212 }
213 
214 void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
215                                         const Triple &TT, Mangler &Mangler) {
216   if (GV->hasDLLExportStorageClass() && !GV->isDeclaration()) {
217 
218     if (TT.isWindowsMSVCEnvironment())
219       OS << " /EXPORT:";
220     else
221       OS << " -export:";
222 
223     bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
224     if (NeedQuotes)
225       OS << "\"";
226     if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
227       std::string Flag;
228       raw_string_ostream FlagOS(Flag);
229       Mangler.getNameWithPrefix(FlagOS, GV, false);
230       FlagOS.flush();
231       if (Flag[0] == GV->getDataLayout().getGlobalPrefix())
232         OS << Flag.substr(1);
233       else
234         OS << Flag;
235     } else {
236       Mangler.getNameWithPrefix(OS, GV, false);
237     }
238     if (TT.isWindowsArm64EC()) {
239       // Use EXPORTAS for mangled ARM64EC symbols.
240       // FIXME: During LTO, we're invoked prior to the EC lowering pass,
241       // so symbols are not yet mangled. Emitting the unmangled name
242       // typically functions correctly; the linker can resolve the export
243       // with the demangled alias.
244       if (std::optional<std::string> demangledName =
245               getArm64ECDemangledFunctionName(GV->getName()))
246         OS << ",EXPORTAS," << *demangledName;
247     }
248     if (NeedQuotes)
249       OS << "\"";
250 
251     if (!GV->getValueType()->isFunctionTy()) {
252       if (TT.isWindowsMSVCEnvironment())
253         OS << ",DATA";
254       else
255         OS << ",data";
256     }
257   }
258   if (GV->hasHiddenVisibility() && !GV->isDeclaration() && TT.isOSCygMing()) {
259 
260     OS << " -exclude-symbols:";
261 
262     bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
263     if (NeedQuotes)
264       OS << "\"";
265 
266     std::string Flag;
267     raw_string_ostream FlagOS(Flag);
268     Mangler.getNameWithPrefix(FlagOS, GV, false);
269     FlagOS.flush();
270     if (Flag[0] == GV->getDataLayout().getGlobalPrefix())
271       OS << Flag.substr(1);
272     else
273       OS << Flag;
274 
275     if (NeedQuotes)
276       OS << "\"";
277   }
278 }
279 
280 void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
281                                       const Triple &T, Mangler &M) {
282   if (!T.isWindowsMSVCEnvironment())
283     return;
284 
285   OS << " /INCLUDE:";
286   bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
287   if (NeedQuotes)
288     OS << "\"";
289   M.getNameWithPrefix(OS, GV, false);
290   if (NeedQuotes)
291     OS << "\"";
292 }
293 
294 std::optional<std::string> llvm::getArm64ECMangledFunctionName(StringRef Name) {
295   if (Name[0] != '?') {
296     // For non-C++ symbols, prefix the name with "#" unless it's already
297     // mangled.
298     if (Name[0] == '#')
299       return std::nullopt;
300     return std::optional<std::string>(("#" + Name).str());
301   }
302 
303   // If the name contains $$h, then it is already mangled.
304   if (Name.contains("$$h"))
305     return std::nullopt;
306 
307   // Ask the demangler where we should insert "$$h".
308   auto InsertIdx = getArm64ECInsertionPointInMangledName(Name);
309   if (!InsertIdx)
310     return std::nullopt;
311 
312   return std::optional<std::string>(
313       (Name.substr(0, *InsertIdx) + "$$h" + Name.substr(*InsertIdx)).str());
314 }
315 
316 std::optional<std::string>
317 llvm::getArm64ECDemangledFunctionName(StringRef Name) {
318   if (Name[0] == '#')
319     return std::optional<std::string>(Name.substr(1));
320   if (Name[0] != '?')
321     return std::nullopt;
322 
323   std::pair<StringRef, StringRef> Pair = Name.split("$$h");
324   if (Pair.second.empty())
325     return std::nullopt;
326   return std::optional<std::string>((Pair.first + Pair.second).str());
327 }
328