xref: /freebsd/contrib/llvm-project/llvm/lib/IR/Mangler.cpp (revision 19261079b74319502c6ffa1249920079f0f69a72)
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/Triple.h"
17 #include "llvm/ADT/Twine.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 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 (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
102        AI != AE; ++AI) {
103     // 'Dereference' type in case of byval or inalloca parameter attribute.
104     uint64_t AllocSize = AI->hasPassPointeeByValueCopyAttr() ?
105       AI->getPassPointeeByValueCopySize(DL) :
106       DL.getTypeAllocSize(AI->getType());
107 
108     // Size should be aligned to pointer size.
109     ArgWords += alignTo(AllocSize, PtrSize);
110   }
111 
112   OS << '@' << ArgWords;
113 }
114 
115 void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
116                                 bool CannotUsePrivateLabel) const {
117   ManglerPrefixTy PrefixTy = Default;
118   if (GV->hasPrivateLinkage()) {
119     if (CannotUsePrivateLabel)
120       PrefixTy = LinkerPrivate;
121     else
122       PrefixTy = Private;
123   }
124 
125   const DataLayout &DL = GV->getParent()->getDataLayout();
126   if (!GV->hasName()) {
127     // Get the ID for the global, assigning a new one if we haven't got one
128     // already.
129     unsigned &ID = AnonGlobalIDs[GV];
130     if (ID == 0)
131       ID = AnonGlobalIDs.size();
132 
133     // Must mangle the global into a unique ID.
134     getNameWithPrefixImpl(OS, "__unnamed_" + Twine(ID), DL, PrefixTy);
135     return;
136   }
137 
138   StringRef Name = GV->getName();
139   char Prefix = DL.getGlobalPrefix();
140 
141   // Mangle functions with Microsoft calling conventions specially.  Only do
142   // this mangling for x86_64 vectorcall and 32-bit x86.
143   const Function *MSFunc = dyn_cast<Function>(GV);
144 
145   // Don't add byte count suffixes when '\01' or '?' are in the first
146   // character.
147   if (Name.startswith("\01") ||
148       (DL.doNotMangleLeadingQuestionMark() && Name.startswith("?")))
149     MSFunc = nullptr;
150 
151   CallingConv::ID CC =
152       MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C;
153   if (!DL.hasMicrosoftFastStdCallMangling() &&
154       CC != CallingConv::X86_VectorCall)
155     MSFunc = nullptr;
156   if (MSFunc) {
157     if (CC == CallingConv::X86_FastCall)
158       Prefix = '@'; // fastcall functions have an @ prefix instead of _.
159     else if (CC == CallingConv::X86_VectorCall)
160       Prefix = '\0'; // vectorcall functions have no prefix.
161   }
162 
163   getNameWithPrefixImpl(OS, Name, PrefixTy, DL, Prefix);
164 
165   if (!MSFunc)
166     return;
167 
168   // If we are supposed to add a microsoft-style suffix for stdcall, fastcall,
169   // or vectorcall, add it.  These functions have a suffix of @N where N is the
170   // cumulative byte size of all of the parameters to the function in decimal.
171   if (CC == CallingConv::X86_VectorCall)
172     OS << '@'; // vectorcall functions use a double @ suffix.
173   FunctionType *FT = MSFunc->getFunctionType();
174   if (hasByteCountSuffix(CC) &&
175       // "Pure" variadic functions do not receive @0 suffix.
176       (!FT->isVarArg() || FT->getNumParams() == 0 ||
177        (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr())))
178     addByteCountSuffix(OS, MSFunc, DL);
179 }
180 
181 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
182                                 const GlobalValue *GV,
183                                 bool CannotUsePrivateLabel) const {
184   raw_svector_ostream OS(OutName);
185   getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
186 }
187 
188 // Check if the name needs quotes to be safe for the linker to interpret.
189 static bool canBeUnquotedInDirective(char C) {
190   return isAlnum(C) || C == '_' || C == '$' || C == '.' || C == '@';
191 }
192 
193 static bool canBeUnquotedInDirective(StringRef Name) {
194   if (Name.empty())
195     return false;
196 
197   // If any of the characters in the string is an unacceptable character, force
198   // quotes.
199   for (char C : Name) {
200     if (!canBeUnquotedInDirective(C))
201       return false;
202   }
203 
204   return true;
205 }
206 
207 void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
208                                         const Triple &TT, Mangler &Mangler) {
209   if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
210     return;
211 
212   if (TT.isWindowsMSVCEnvironment())
213     OS << " /EXPORT:";
214   else
215     OS << " -export:";
216 
217   bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
218   if (NeedQuotes)
219     OS << "\"";
220   if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
221     std::string Flag;
222     raw_string_ostream FlagOS(Flag);
223     Mangler.getNameWithPrefix(FlagOS, GV, false);
224     FlagOS.flush();
225     if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
226       OS << Flag.substr(1);
227     else
228       OS << Flag;
229   } else {
230     Mangler.getNameWithPrefix(OS, GV, false);
231   }
232   if (NeedQuotes)
233     OS << "\"";
234 
235   if (!GV->getValueType()->isFunctionTy()) {
236     if (TT.isWindowsMSVCEnvironment())
237       OS << ",DATA";
238     else
239       OS << ",data";
240   }
241 }
242 
243 void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
244                                       const Triple &T, Mangler &M) {
245   if (!T.isWindowsMSVCEnvironment())
246     return;
247 
248   OS << " /INCLUDE:";
249   bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
250   if (NeedQuotes)
251     OS << "\"";
252   M.getNameWithPrefix(OS, GV, false);
253   if (NeedQuotes)
254     OS << "\"";
255 }
256 
257