xref: /openbsd-src/gnu/llvm/llvm/lib/IR/Mangler.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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