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/Triple.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 using namespace llvm;
23 
24 namespace {
25 enum ManglerPrefixTy {
26   Default,      ///< Emit default string before each symbol.
27   Private,      ///< Emit "private" prefix before each symbol.
28   LinkerPrivate ///< Emit "linker private" prefix before each symbol.
29 };
30 }
31 
32 static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
33                                   ManglerPrefixTy PrefixTy,
34                                   const DataLayout &DL, char Prefix) {
35   SmallString<256> TmpData;
36   StringRef Name = GVName.toStringRef(TmpData);
37   assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
38 
39   // No need to do anything special if the global has the special "do not
40   // mangle" flag in the name.
41   if (Name[0] == '\1') {
42     OS << Name.substr(1);
43     return;
44   }
45 
46   if (DL.doNotMangleLeadingQuestionMark() && Name[0] == '?')
47     Prefix = '\0';
48 
49   if (PrefixTy == Private)
50     OS << DL.getPrivateGlobalPrefix();
51   else if (PrefixTy == LinkerPrivate)
52     OS << DL.getLinkerPrivateGlobalPrefix();
53 
54   if (Prefix != '\0')
55     OS << Prefix;
56 
57   // If this is a simple string that doesn't need escaping, just append it.
58   OS << Name;
59 }
60 
61 static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
62                                   const DataLayout &DL,
63                                   ManglerPrefixTy PrefixTy) {
64   char Prefix = DL.getGlobalPrefix();
65   return getNameWithPrefixImpl(OS, GVName, PrefixTy, DL, Prefix);
66 }
67 
68 void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
69                                 const DataLayout &DL) {
70   return getNameWithPrefixImpl(OS, GVName, DL, Default);
71 }
72 
73 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
74                                 const Twine &GVName, const DataLayout &DL) {
75   raw_svector_ostream OS(OutName);
76   char Prefix = DL.getGlobalPrefix();
77   return getNameWithPrefixImpl(OS, GVName, Default, DL, Prefix);
78 }
79 
80 static bool hasByteCountSuffix(CallingConv::ID CC) {
81   switch (CC) {
82   case CallingConv::X86_FastCall:
83   case CallingConv::X86_StdCall:
84   case CallingConv::X86_VectorCall:
85     return true;
86   default:
87     return false;
88   }
89 }
90 
91 /// Microsoft fastcall and stdcall functions require a suffix on their name
92 /// indicating the number of words of arguments they take.
93 static void addByteCountSuffix(raw_ostream &OS, const Function *F,
94                                const DataLayout &DL) {
95   // Calculate arguments size total.
96   unsigned ArgWords = 0;
97   for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
98        AI != AE; ++AI) {
99     Type *Ty = AI->getType();
100     // 'Dereference' type in case of byval or inalloca parameter attribute.
101     if (AI->hasByValOrInAllocaAttr())
102       Ty = cast<PointerType>(Ty)->getElementType();
103     // Size should be aligned to pointer size.
104     unsigned PtrSize = DL.getPointerSize();
105     ArgWords += alignTo(DL.getTypeAllocSize(Ty), PtrSize);
106   }
107 
108   OS << '@' << ArgWords;
109 }
110 
111 void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
112                                 bool CannotUsePrivateLabel) const {
113   ManglerPrefixTy PrefixTy = Default;
114   if (GV->hasPrivateLinkage()) {
115     if (CannotUsePrivateLabel)
116       PrefixTy = LinkerPrivate;
117     else
118       PrefixTy = Private;
119   }
120 
121   const DataLayout &DL = GV->getParent()->getDataLayout();
122   if (!GV->hasName()) {
123     // Get the ID for the global, assigning a new one if we haven't got one
124     // already.
125     unsigned &ID = AnonGlobalIDs[GV];
126     if (ID == 0)
127       ID = AnonGlobalIDs.size();
128 
129     // Must mangle the global into a unique ID.
130     getNameWithPrefixImpl(OS, "__unnamed_" + Twine(ID), DL, PrefixTy);
131     return;
132   }
133 
134   StringRef Name = GV->getName();
135   char Prefix = DL.getGlobalPrefix();
136 
137   // Mangle functions with Microsoft calling conventions specially.  Only do
138   // this mangling for x86_64 vectorcall and 32-bit x86.
139   const Function *MSFunc = dyn_cast<Function>(GV);
140 
141   // Don't add byte count suffixes when '\01' or '?' are in the first
142   // character.
143   if (Name.startswith("\01") ||
144       (DL.doNotMangleLeadingQuestionMark() && Name.startswith("?")))
145     MSFunc = nullptr;
146 
147   CallingConv::ID CC =
148       MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C;
149   if (!DL.hasMicrosoftFastStdCallMangling() &&
150       CC != CallingConv::X86_VectorCall)
151     MSFunc = nullptr;
152   if (MSFunc) {
153     if (CC == CallingConv::X86_FastCall)
154       Prefix = '@'; // fastcall functions have an @ prefix instead of _.
155     else if (CC == CallingConv::X86_VectorCall)
156       Prefix = '\0'; // vectorcall functions have no prefix.
157   }
158 
159   getNameWithPrefixImpl(OS, Name, PrefixTy, DL, Prefix);
160 
161   if (!MSFunc)
162     return;
163 
164   // If we are supposed to add a microsoft-style suffix for stdcall, fastcall,
165   // or vectorcall, add it.  These functions have a suffix of @N where N is the
166   // cumulative byte size of all of the parameters to the function in decimal.
167   if (CC == CallingConv::X86_VectorCall)
168     OS << '@'; // vectorcall functions use a double @ suffix.
169   FunctionType *FT = MSFunc->getFunctionType();
170   if (hasByteCountSuffix(CC) &&
171       // "Pure" variadic functions do not receive @0 suffix.
172       (!FT->isVarArg() || FT->getNumParams() == 0 ||
173        (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr())))
174     addByteCountSuffix(OS, MSFunc, DL);
175 }
176 
177 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
178                                 const GlobalValue *GV,
179                                 bool CannotUsePrivateLabel) const {
180   raw_svector_ostream OS(OutName);
181   getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
182 }
183 
184 void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
185                                         const Triple &TT, Mangler &Mangler) {
186   if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
187     return;
188 
189   if (TT.isWindowsMSVCEnvironment())
190     OS << " /EXPORT:";
191   else
192     OS << " -export:";
193 
194   if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
195     std::string Flag;
196     raw_string_ostream FlagOS(Flag);
197     Mangler.getNameWithPrefix(FlagOS, GV, false);
198     FlagOS.flush();
199     if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
200       OS << Flag.substr(1);
201     else
202       OS << Flag;
203   } else {
204     Mangler.getNameWithPrefix(OS, GV, false);
205   }
206 
207   if (!GV->getValueType()->isFunctionTy()) {
208     if (TT.isWindowsMSVCEnvironment())
209       OS << ",DATA";
210     else
211       OS << ",data";
212   }
213 }
214 
215 void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
216                                       const Triple &T, Mangler &M) {
217   if (!T.isWindowsMSVCEnvironment())
218     return;
219 
220   OS << " /INCLUDE:";
221   M.getNameWithPrefix(OS, GV, false);
222 }
223 
224