109467b48Spatrick //===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // Unified name mangler for assembly backends.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick
1309467b48Spatrick #include "llvm/IR/Mangler.h"
1409467b48Spatrick #include "llvm/ADT/SmallString.h"
1573471bf0Spatrick #include "llvm/ADT/StringExtras.h"
1609467b48Spatrick #include "llvm/ADT/Triple.h"
1709467b48Spatrick #include "llvm/ADT/Twine.h"
1809467b48Spatrick #include "llvm/IR/DataLayout.h"
1909467b48Spatrick #include "llvm/IR/DerivedTypes.h"
2009467b48Spatrick #include "llvm/IR/Function.h"
2109467b48Spatrick #include "llvm/IR/Module.h"
2209467b48Spatrick #include "llvm/Support/raw_ostream.h"
2309467b48Spatrick using namespace llvm;
2409467b48Spatrick
2509467b48Spatrick namespace {
2609467b48Spatrick enum ManglerPrefixTy {
2709467b48Spatrick Default, ///< Emit default string before each symbol.
2809467b48Spatrick Private, ///< Emit "private" prefix before each symbol.
2909467b48Spatrick LinkerPrivate ///< Emit "linker private" prefix before each symbol.
3009467b48Spatrick };
3109467b48Spatrick }
3209467b48Spatrick
getNameWithPrefixImpl(raw_ostream & OS,const Twine & GVName,ManglerPrefixTy PrefixTy,const DataLayout & DL,char Prefix)3309467b48Spatrick static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
3409467b48Spatrick ManglerPrefixTy PrefixTy,
3509467b48Spatrick const DataLayout &DL, char Prefix) {
3609467b48Spatrick SmallString<256> TmpData;
3709467b48Spatrick StringRef Name = GVName.toStringRef(TmpData);
3809467b48Spatrick assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
3909467b48Spatrick
4009467b48Spatrick // No need to do anything special if the global has the special "do not
4109467b48Spatrick // mangle" flag in the name.
4209467b48Spatrick if (Name[0] == '\1') {
4309467b48Spatrick OS << Name.substr(1);
4409467b48Spatrick return;
4509467b48Spatrick }
4609467b48Spatrick
4709467b48Spatrick if (DL.doNotMangleLeadingQuestionMark() && Name[0] == '?')
4809467b48Spatrick Prefix = '\0';
4909467b48Spatrick
5009467b48Spatrick if (PrefixTy == Private)
5109467b48Spatrick OS << DL.getPrivateGlobalPrefix();
5209467b48Spatrick else if (PrefixTy == LinkerPrivate)
5309467b48Spatrick OS << DL.getLinkerPrivateGlobalPrefix();
5409467b48Spatrick
5509467b48Spatrick if (Prefix != '\0')
5609467b48Spatrick OS << Prefix;
5709467b48Spatrick
5809467b48Spatrick // If this is a simple string that doesn't need escaping, just append it.
5909467b48Spatrick OS << Name;
6009467b48Spatrick }
6109467b48Spatrick
getNameWithPrefixImpl(raw_ostream & OS,const Twine & GVName,const DataLayout & DL,ManglerPrefixTy PrefixTy)6209467b48Spatrick static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
6309467b48Spatrick const DataLayout &DL,
6409467b48Spatrick ManglerPrefixTy PrefixTy) {
6509467b48Spatrick char Prefix = DL.getGlobalPrefix();
6609467b48Spatrick return getNameWithPrefixImpl(OS, GVName, PrefixTy, DL, Prefix);
6709467b48Spatrick }
6809467b48Spatrick
getNameWithPrefix(raw_ostream & OS,const Twine & GVName,const DataLayout & DL)6909467b48Spatrick void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
7009467b48Spatrick const DataLayout &DL) {
7109467b48Spatrick return getNameWithPrefixImpl(OS, GVName, DL, Default);
7209467b48Spatrick }
7309467b48Spatrick
getNameWithPrefix(SmallVectorImpl<char> & OutName,const Twine & GVName,const DataLayout & DL)7409467b48Spatrick void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
7509467b48Spatrick const Twine &GVName, const DataLayout &DL) {
7609467b48Spatrick raw_svector_ostream OS(OutName);
7709467b48Spatrick char Prefix = DL.getGlobalPrefix();
7809467b48Spatrick return getNameWithPrefixImpl(OS, GVName, Default, DL, Prefix);
7909467b48Spatrick }
8009467b48Spatrick
hasByteCountSuffix(CallingConv::ID CC)8109467b48Spatrick static bool hasByteCountSuffix(CallingConv::ID CC) {
8209467b48Spatrick switch (CC) {
8309467b48Spatrick case CallingConv::X86_FastCall:
8409467b48Spatrick case CallingConv::X86_StdCall:
8509467b48Spatrick case CallingConv::X86_VectorCall:
8609467b48Spatrick return true;
8709467b48Spatrick default:
8809467b48Spatrick return false;
8909467b48Spatrick }
9009467b48Spatrick }
9109467b48Spatrick
9209467b48Spatrick /// Microsoft fastcall and stdcall functions require a suffix on their name
9309467b48Spatrick /// indicating the number of words of arguments they take.
addByteCountSuffix(raw_ostream & OS,const Function * F,const DataLayout & DL)9409467b48Spatrick static void addByteCountSuffix(raw_ostream &OS, const Function *F,
9509467b48Spatrick const DataLayout &DL) {
9609467b48Spatrick // Calculate arguments size total.
9709467b48Spatrick unsigned ArgWords = 0;
98097a140dSpatrick
99097a140dSpatrick const unsigned PtrSize = DL.getPointerSize();
100097a140dSpatrick
10173471bf0Spatrick for (const Argument &A : F->args()) {
102*d415bd75Srobert // For the purposes of the byte count suffix, structs returned by pointer
103*d415bd75Srobert // do not count as function arguments.
104*d415bd75Srobert if (A.hasStructRetAttr())
105*d415bd75Srobert continue;
106*d415bd75Srobert
10709467b48Spatrick // 'Dereference' type in case of byval or inalloca parameter attribute.
10873471bf0Spatrick uint64_t AllocSize = A.hasPassPointeeByValueCopyAttr() ?
10973471bf0Spatrick A.getPassPointeeByValueCopySize(DL) :
11073471bf0Spatrick DL.getTypeAllocSize(A.getType());
111097a140dSpatrick
11209467b48Spatrick // Size should be aligned to pointer size.
113097a140dSpatrick ArgWords += alignTo(AllocSize, PtrSize);
11409467b48Spatrick }
11509467b48Spatrick
11609467b48Spatrick OS << '@' << ArgWords;
11709467b48Spatrick }
11809467b48Spatrick
getNameWithPrefix(raw_ostream & OS,const GlobalValue * GV,bool CannotUsePrivateLabel) const11909467b48Spatrick void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
12009467b48Spatrick bool CannotUsePrivateLabel) const {
12109467b48Spatrick ManglerPrefixTy PrefixTy = Default;
12209467b48Spatrick if (GV->hasPrivateLinkage()) {
12309467b48Spatrick if (CannotUsePrivateLabel)
12409467b48Spatrick PrefixTy = LinkerPrivate;
12509467b48Spatrick else
12609467b48Spatrick PrefixTy = Private;
12709467b48Spatrick }
12809467b48Spatrick
12909467b48Spatrick const DataLayout &DL = GV->getParent()->getDataLayout();
13009467b48Spatrick if (!GV->hasName()) {
13109467b48Spatrick // Get the ID for the global, assigning a new one if we haven't got one
13209467b48Spatrick // already.
13309467b48Spatrick unsigned &ID = AnonGlobalIDs[GV];
13409467b48Spatrick if (ID == 0)
13509467b48Spatrick ID = AnonGlobalIDs.size();
13609467b48Spatrick
13709467b48Spatrick // Must mangle the global into a unique ID.
13809467b48Spatrick getNameWithPrefixImpl(OS, "__unnamed_" + Twine(ID), DL, PrefixTy);
13909467b48Spatrick return;
14009467b48Spatrick }
14109467b48Spatrick
14209467b48Spatrick StringRef Name = GV->getName();
14309467b48Spatrick char Prefix = DL.getGlobalPrefix();
14409467b48Spatrick
14509467b48Spatrick // Mangle functions with Microsoft calling conventions specially. Only do
14609467b48Spatrick // this mangling for x86_64 vectorcall and 32-bit x86.
147*d415bd75Srobert const Function *MSFunc = dyn_cast_or_null<Function>(GV->getAliaseeObject());
14809467b48Spatrick
14909467b48Spatrick // Don't add byte count suffixes when '\01' or '?' are in the first
15009467b48Spatrick // character.
15109467b48Spatrick if (Name.startswith("\01") ||
15209467b48Spatrick (DL.doNotMangleLeadingQuestionMark() && Name.startswith("?")))
15309467b48Spatrick MSFunc = nullptr;
15409467b48Spatrick
15509467b48Spatrick CallingConv::ID CC =
15609467b48Spatrick MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C;
15709467b48Spatrick if (!DL.hasMicrosoftFastStdCallMangling() &&
15809467b48Spatrick CC != CallingConv::X86_VectorCall)
15909467b48Spatrick MSFunc = nullptr;
16009467b48Spatrick if (MSFunc) {
16109467b48Spatrick if (CC == CallingConv::X86_FastCall)
16209467b48Spatrick Prefix = '@'; // fastcall functions have an @ prefix instead of _.
16309467b48Spatrick else if (CC == CallingConv::X86_VectorCall)
16409467b48Spatrick Prefix = '\0'; // vectorcall functions have no prefix.
16509467b48Spatrick }
16609467b48Spatrick
16709467b48Spatrick getNameWithPrefixImpl(OS, Name, PrefixTy, DL, Prefix);
16809467b48Spatrick
16909467b48Spatrick if (!MSFunc)
17009467b48Spatrick return;
17109467b48Spatrick
17209467b48Spatrick // If we are supposed to add a microsoft-style suffix for stdcall, fastcall,
17309467b48Spatrick // or vectorcall, add it. These functions have a suffix of @N where N is the
17409467b48Spatrick // cumulative byte size of all of the parameters to the function in decimal.
17509467b48Spatrick if (CC == CallingConv::X86_VectorCall)
17609467b48Spatrick OS << '@'; // vectorcall functions use a double @ suffix.
17709467b48Spatrick FunctionType *FT = MSFunc->getFunctionType();
17809467b48Spatrick if (hasByteCountSuffix(CC) &&
17909467b48Spatrick // "Pure" variadic functions do not receive @0 suffix.
18009467b48Spatrick (!FT->isVarArg() || FT->getNumParams() == 0 ||
18109467b48Spatrick (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr())))
18209467b48Spatrick addByteCountSuffix(OS, MSFunc, DL);
18309467b48Spatrick }
18409467b48Spatrick
getNameWithPrefix(SmallVectorImpl<char> & OutName,const GlobalValue * GV,bool CannotUsePrivateLabel) const18509467b48Spatrick void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
18609467b48Spatrick const GlobalValue *GV,
18709467b48Spatrick bool CannotUsePrivateLabel) const {
18809467b48Spatrick raw_svector_ostream OS(OutName);
18909467b48Spatrick getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
19009467b48Spatrick }
19109467b48Spatrick
19273471bf0Spatrick // Check if the name needs quotes to be safe for the linker to interpret.
canBeUnquotedInDirective(char C)19373471bf0Spatrick static bool canBeUnquotedInDirective(char C) {
194*d415bd75Srobert return isAlnum(C) || C == '_' || C == '@';
19573471bf0Spatrick }
19673471bf0Spatrick
canBeUnquotedInDirective(StringRef Name)19773471bf0Spatrick static bool canBeUnquotedInDirective(StringRef Name) {
19873471bf0Spatrick if (Name.empty())
19973471bf0Spatrick return false;
20073471bf0Spatrick
20173471bf0Spatrick // If any of the characters in the string is an unacceptable character, force
20273471bf0Spatrick // quotes.
20373471bf0Spatrick for (char C : Name) {
20473471bf0Spatrick if (!canBeUnquotedInDirective(C))
20573471bf0Spatrick return false;
20673471bf0Spatrick }
20773471bf0Spatrick
20873471bf0Spatrick return true;
20973471bf0Spatrick }
21073471bf0Spatrick
emitLinkerFlagsForGlobalCOFF(raw_ostream & OS,const GlobalValue * GV,const Triple & TT,Mangler & Mangler)21109467b48Spatrick void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
21209467b48Spatrick const Triple &TT, Mangler &Mangler) {
213*d415bd75Srobert if (GV->hasDLLExportStorageClass() && !GV->isDeclaration()) {
21409467b48Spatrick
21509467b48Spatrick if (TT.isWindowsMSVCEnvironment())
21609467b48Spatrick OS << " /EXPORT:";
21709467b48Spatrick else
21809467b48Spatrick OS << " -export:";
21909467b48Spatrick
22073471bf0Spatrick bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
22173471bf0Spatrick if (NeedQuotes)
22273471bf0Spatrick OS << "\"";
22309467b48Spatrick if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
22409467b48Spatrick std::string Flag;
22509467b48Spatrick raw_string_ostream FlagOS(Flag);
22609467b48Spatrick Mangler.getNameWithPrefix(FlagOS, GV, false);
22709467b48Spatrick FlagOS.flush();
22809467b48Spatrick if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
22909467b48Spatrick OS << Flag.substr(1);
23009467b48Spatrick else
23109467b48Spatrick OS << Flag;
23209467b48Spatrick } else {
23309467b48Spatrick Mangler.getNameWithPrefix(OS, GV, false);
23409467b48Spatrick }
23573471bf0Spatrick if (NeedQuotes)
23673471bf0Spatrick OS << "\"";
23709467b48Spatrick
23809467b48Spatrick if (!GV->getValueType()->isFunctionTy()) {
23909467b48Spatrick if (TT.isWindowsMSVCEnvironment())
24009467b48Spatrick OS << ",DATA";
24109467b48Spatrick else
24209467b48Spatrick OS << ",data";
24309467b48Spatrick }
24409467b48Spatrick }
245*d415bd75Srobert if (GV->hasHiddenVisibility() && !GV->isDeclaration() && TT.isOSCygMing()) {
246*d415bd75Srobert
247*d415bd75Srobert OS << " -exclude-symbols:";
248*d415bd75Srobert
249*d415bd75Srobert bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
250*d415bd75Srobert if (NeedQuotes)
251*d415bd75Srobert OS << "\"";
252*d415bd75Srobert
253*d415bd75Srobert std::string Flag;
254*d415bd75Srobert raw_string_ostream FlagOS(Flag);
255*d415bd75Srobert Mangler.getNameWithPrefix(FlagOS, GV, false);
256*d415bd75Srobert FlagOS.flush();
257*d415bd75Srobert if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
258*d415bd75Srobert OS << Flag.substr(1);
259*d415bd75Srobert else
260*d415bd75Srobert OS << Flag;
261*d415bd75Srobert
262*d415bd75Srobert if (NeedQuotes)
263*d415bd75Srobert OS << "\"";
264*d415bd75Srobert }
265*d415bd75Srobert }
26609467b48Spatrick
emitLinkerFlagsForUsedCOFF(raw_ostream & OS,const GlobalValue * GV,const Triple & T,Mangler & M)26709467b48Spatrick void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
26809467b48Spatrick const Triple &T, Mangler &M) {
26909467b48Spatrick if (!T.isWindowsMSVCEnvironment())
27009467b48Spatrick return;
27109467b48Spatrick
27209467b48Spatrick OS << " /INCLUDE:";
27373471bf0Spatrick bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
27473471bf0Spatrick if (NeedQuotes)
27573471bf0Spatrick OS << "\"";
27609467b48Spatrick M.getNameWithPrefix(OS, GV, false);
27773471bf0Spatrick if (NeedQuotes)
27873471bf0Spatrick OS << "\"";
27909467b48Spatrick }
28009467b48Spatrick
281