1 //===----------- Mangling.cpp -- Name Mangling Utilities for ORC ----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/Mangling.h"
10 #include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
11 #include "llvm/IR/Constants.h"
12 #include "llvm/IR/Mangler.h"
13 #include "llvm/Object/MachO.h"
14 #include "llvm/Object/ObjectFile.h"
15 #include "llvm/Support/Debug.h"
17 #define DEBUG_TYPE "orc"
22 MangleAndInterner::MangleAndInterner(ExecutionSession
&ES
, const DataLayout
&DL
)
25 SymbolStringPtr
MangleAndInterner::operator()(StringRef Name
) {
26 std::string MangledName
;
28 raw_string_ostream
MangledNameStream(MangledName
);
29 Mangler::getNameWithPrefix(MangledNameStream
, Name
, DL
);
31 return ES
.intern(MangledName
);
34 void IRSymbolMapper::add(ExecutionSession
&ES
, const ManglingOptions
&MO
,
35 ArrayRef
<GlobalValue
*> GVs
,
36 SymbolFlagsMap
&SymbolFlags
,
37 SymbolNameToDefinitionMap
*SymbolToDefinition
) {
41 MangleAndInterner
Mangle(ES
, GVs
[0]->getParent()->getDataLayout());
43 assert(G
&& "GVs cannot contain null elements");
44 if (!G
->hasName() || G
->isDeclaration() || G
->hasLocalLinkage() ||
45 G
->hasAvailableExternallyLinkage() || G
->hasAppendingLinkage())
48 if (G
->isThreadLocal() && MO
.EmulatedTLS
) {
49 auto *GV
= cast
<GlobalVariable
>(G
);
51 auto Flags
= JITSymbolFlags::fromGlobalValue(*GV
);
53 auto EmuTLSV
= Mangle(("__emutls_v." + GV
->getName()).str());
54 SymbolFlags
[EmuTLSV
] = Flags
;
55 if (SymbolToDefinition
)
56 (*SymbolToDefinition
)[EmuTLSV
] = GV
;
58 // If this GV has a non-zero initializer we'll need to emit an
59 // __emutls.t symbol too.
60 if (GV
->hasInitializer()) {
61 const auto *InitVal
= GV
->getInitializer();
63 // Skip zero-initializers.
64 if (isa
<ConstantAggregateZero
>(InitVal
))
66 const auto *InitIntValue
= dyn_cast
<ConstantInt
>(InitVal
);
67 if (InitIntValue
&& InitIntValue
->isZero())
70 auto EmuTLST
= Mangle(("__emutls_t." + GV
->getName()).str());
71 SymbolFlags
[EmuTLST
] = Flags
;
72 if (SymbolToDefinition
)
73 (*SymbolToDefinition
)[EmuTLST
] = GV
;
78 // Otherwise we just need a normal linker mangling.
79 auto MangledName
= Mangle(G
->getName());
80 SymbolFlags
[MangledName
] = JITSymbolFlags::fromGlobalValue(*G
);
81 if (SymbolToDefinition
)
82 (*SymbolToDefinition
)[MangledName
] = G
;
86 Expected
<std::pair
<SymbolFlagsMap
, SymbolStringPtr
>>
87 getObjectSymbolInfo(ExecutionSession
&ES
, MemoryBufferRef ObjBuffer
) {
88 auto Obj
= object::ObjectFile::createObjectFile(ObjBuffer
);
91 return Obj
.takeError();
93 bool IsMachO
= isa
<object::MachOObjectFile
>(Obj
->get());
95 SymbolFlagsMap SymbolFlags
;
96 for (auto &Sym
: (*Obj
)->symbols()) {
97 Expected
<uint32_t> SymFlagsOrErr
= Sym
.getFlags();
99 // TODO: Test this error.
100 return SymFlagsOrErr
.takeError();
102 // Skip symbols not defined in this object file.
103 if (*SymFlagsOrErr
& object::BasicSymbolRef::SF_Undefined
)
106 // Skip symbols that are not global.
107 if (!(*SymFlagsOrErr
& object::BasicSymbolRef::SF_Global
))
110 // Skip symbols that have type SF_File.
111 if (auto SymType
= Sym
.getType()) {
112 if (*SymType
== object::SymbolRef::ST_File
)
115 return SymType
.takeError();
117 auto Name
= Sym
.getName();
119 return Name
.takeError();
120 auto InternedName
= ES
.intern(*Name
);
121 auto SymFlags
= JITSymbolFlags::fromObjectSymbol(Sym
);
123 return SymFlags
.takeError();
125 // Strip the 'exported' flag from MachO linker-private symbols.
126 if (IsMachO
&& Name
->startswith("l"))
127 *SymFlags
&= ~JITSymbolFlags::Exported
;
129 SymbolFlags
[InternedName
] = std::move(*SymFlags
);
132 SymbolStringPtr InitSymbol
;
135 auto AddInitSymbol
= [&]() {
137 std::string InitSymString
;
138 raw_string_ostream(InitSymString
)
139 << "$." << ObjBuffer
.getBufferIdentifier() << ".__inits."
141 InitSymbol
= ES
.intern(InitSymString
);
142 if (SymbolFlags
.count(InitSymbol
))
144 SymbolFlags
[InitSymbol
] = JITSymbolFlags::MaterializationSideEffectsOnly
;
150 auto &MachOObj
= cast
<object::MachOObjectFile
>(*Obj
->get());
151 for (auto &Sec
: MachOObj
.sections()) {
152 auto SecType
= MachOObj
.getSectionType(Sec
);
153 if ((SecType
& MachO::SECTION_TYPE
) == MachO::S_MOD_INIT_FUNC_POINTERS
) {
158 MachOObj
.getSectionFinalSegmentName(Sec
.getRawDataRefImpl());
159 auto SecName
= cantFail(MachOObj
.getSectionName(Sec
.getRawDataRefImpl()));
160 if (MachOPlatform::isInitializerSection(SegName
, SecName
)) {
167 return std::make_pair(std::move(SymbolFlags
), std::move(InitSymbol
));
170 } // End namespace orc.
171 } // End namespace llvm.