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(Out&: 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(Start: 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, PrefixTy: 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, PrefixTy: 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(Ty: A.getType()); |
113 | |
114 | // Size should be aligned to pointer size. |
115 | ArgWords += alignTo(Value: AllocSize, Align: 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, GVName: "__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>(Val: GV->getAliaseeObject()); |
151 | |
152 | // Don't add byte count suffixes when '\01' or '?' are in the first |
153 | // character. |
154 | if (Name.starts_with(Prefix: "\01" ) || |
155 | (DL.doNotMangleLeadingQuestionMark() && Name.starts_with(Prefix: "?" ))) |
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, GVName: 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, F: 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() || TT.isUEFI()) |
219 | OS << " /EXPORT:" ; |
220 | else |
221 | OS << " -export:" ; |
222 | |
223 | bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(Name: 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(OS&: FlagOS, GV, CannotUsePrivateLabel: false); |
230 | FlagOS.flush(); |
231 | if (Flag[0] == GV->getDataLayout().getGlobalPrefix()) |
232 | OS << Flag.substr(pos: 1); |
233 | else |
234 | OS << Flag; |
235 | } else { |
236 | Mangler.getNameWithPrefix(OS, GV, CannotUsePrivateLabel: 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(Name: GV->getName())) |
246 | OS << ",EXPORTAS," << *demangledName; |
247 | } |
248 | if (NeedQuotes) |
249 | OS << "\"" ; |
250 | |
251 | if (!GV->getValueType()->isFunctionTy()) { |
252 | if (TT.isWindowsMSVCEnvironment() || TT.isUEFI()) |
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(Name: GV->getName()); |
263 | if (NeedQuotes) |
264 | OS << "\"" ; |
265 | |
266 | std::string Flag; |
267 | raw_string_ostream FlagOS(Flag); |
268 | Mangler.getNameWithPrefix(OS&: FlagOS, GV, CannotUsePrivateLabel: false); |
269 | FlagOS.flush(); |
270 | if (Flag[0] == GV->getDataLayout().getGlobalPrefix()) |
271 | OS << Flag.substr(pos: 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(Name: GV->getName()); |
287 | if (NeedQuotes) |
288 | OS << "\"" ; |
289 | M.getNameWithPrefix(OS, GV, CannotUsePrivateLabel: 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(Other: "$$h" )) |
305 | return std::nullopt; |
306 | |
307 | // Ask the demangler where we should insert "$$h". |
308 | auto InsertIdx = getArm64ECInsertionPointInMangledName(MangledName: Name); |
309 | if (!InsertIdx) |
310 | return std::nullopt; |
311 | |
312 | return std::optional<std::string>( |
313 | (Name.substr(Start: 0, N: *InsertIdx) + "$$h" + Name.substr(Start: *InsertIdx)).str()); |
314 | } |
315 | |
316 | std::optional<std::string> |
317 | llvm::getArm64ECDemangledFunctionName(StringRef Name) { |
318 | // For non-C++ names, drop the "#" prefix. |
319 | if (Name[0] == '#') |
320 | return std::optional<std::string>(Name.substr(Start: 1)); |
321 | if (Name[0] != '?') |
322 | return std::nullopt; |
323 | |
324 | // Drop the ARM64EC "$$h" tag. |
325 | std::pair<StringRef, StringRef> Pair = Name.split(Separator: "$$h" ); |
326 | if (Pair.second.empty()) |
327 | return std::nullopt; |
328 | return std::optional<std::string>((Pair.first + Pair.second).str()); |
329 | } |
330 | |