Skip to content

Commit 2e6a4fc

Browse files
committed
[ORC][JITLink][ELF] Treat STB_GNU_UNIQUE as Weak in the JIT.
This should fix the bot error in https://lab.llvm.org/buildbot/#/builders/112/builds/8599 which forced reversion of the ELFNixPlatform in 45ac5f5. This should allow us to re-enable the ELFNixPlatform in a follow-up patch.
1 parent ca4be0f commit 2e6a4fc

File tree

2 files changed

+117
-29
lines changed

2 files changed

+117
-29
lines changed

llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ ELFLinkGraphBuilder<ELFT>::getSymbolLinkageAndScope(
170170
// Nothing to do here.
171171
break;
172172
case ELF::STB_WEAK:
173+
case ELF::STB_GNU_UNIQUE:
173174
L = Linkage::Weak;
174175
break;
175176
default:

llvm/lib/ExecutionEngine/Orc/Mangling.cpp

+116-29
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
1111
#include "llvm/IR/Constants.h"
1212
#include "llvm/IR/Mangler.h"
13+
#include "llvm/Object/ELFObjectFile.h"
1314
#include "llvm/Object/MachO.h"
1415
#include "llvm/Object/ObjectFile.h"
1516
#include "llvm/Support/Debug.h"
@@ -83,17 +84,12 @@ void IRSymbolMapper::add(ExecutionSession &ES, const ManglingOptions &MO,
8384
}
8485
}
8586

86-
Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>>
87-
getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {
88-
auto Obj = object::ObjectFile::createObjectFile(ObjBuffer);
89-
90-
if (!Obj)
91-
return Obj.takeError();
92-
93-
bool IsMachO = isa<object::MachOObjectFile>(Obj->get());
94-
87+
static Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>>
88+
getMachOObjectFileSymbolInfo(ExecutionSession &ES,
89+
const object::MachOObjectFile &Obj) {
9590
SymbolFlagsMap SymbolFlags;
96-
for (auto &Sym : (*Obj)->symbols()) {
91+
92+
for (auto &Sym : Obj.symbols()) {
9793
Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
9894
if (!SymFlagsOrErr)
9995
// TODO: Test this error.
@@ -123,21 +119,19 @@ getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {
123119
return SymFlags.takeError();
124120

125121
// Strip the 'exported' flag from MachO linker-private symbols.
126-
if (IsMachO && Name->startswith("l"))
122+
if (Name->startswith("l"))
127123
*SymFlags &= ~JITSymbolFlags::Exported;
128124

129125
SymbolFlags[InternedName] = std::move(*SymFlags);
130126
}
131127

132128
SymbolStringPtr InitSymbol;
133-
134129
size_t Counter = 0;
135130
auto AddInitSymbol = [&]() {
136131
while (true) {
137132
std::string InitSymString;
138133
raw_string_ostream(InitSymString)
139-
<< "$." << ObjBuffer.getBufferIdentifier() << ".__inits."
140-
<< Counter++;
134+
<< "$." << Obj.getFileName() << ".__inits." << Counter++;
141135
InitSymbol = ES.intern(InitSymString);
142136
if (SymbolFlags.count(InitSymbol))
143137
continue;
@@ -146,26 +140,119 @@ getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {
146140
}
147141
};
148142

149-
if (IsMachO) {
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) {
154-
AddInitSymbol();
155-
break;
156-
}
157-
auto SegName =
158-
MachOObj.getSectionFinalSegmentName(Sec.getRawDataRefImpl());
159-
auto SecName = cantFail(MachOObj.getSectionName(Sec.getRawDataRefImpl()));
160-
if (MachOPlatform::isInitializerSection(SegName, SecName)) {
161-
AddInitSymbol();
162-
break;
163-
}
143+
for (auto &Sec : Obj.sections()) {
144+
auto SecType = Obj.getSectionType(Sec);
145+
if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) {
146+
AddInitSymbol();
147+
break;
148+
}
149+
auto SegName = Obj.getSectionFinalSegmentName(Sec.getRawDataRefImpl());
150+
auto SecName = cantFail(Obj.getSectionName(Sec.getRawDataRefImpl()));
151+
if (MachOPlatform::isInitializerSection(SegName, SecName)) {
152+
AddInitSymbol();
153+
break;
164154
}
165155
}
166156

167157
return std::make_pair(std::move(SymbolFlags), std::move(InitSymbol));
168158
}
169159

160+
static Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>>
161+
getELFObjectFileSymbolInfo(ExecutionSession &ES,
162+
const object::ELFObjectFileBase &Obj) {
163+
SymbolFlagsMap SymbolFlags;
164+
for (auto &Sym : Obj.symbols()) {
165+
Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
166+
if (!SymFlagsOrErr)
167+
// TODO: Test this error.
168+
return SymFlagsOrErr.takeError();
169+
170+
// Skip symbols not defined in this object file.
171+
if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
172+
continue;
173+
174+
// Skip symbols that are not global.
175+
if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
176+
continue;
177+
178+
// Skip symbols that have type SF_File.
179+
if (auto SymType = Sym.getType()) {
180+
if (*SymType == object::SymbolRef::ST_File)
181+
continue;
182+
} else
183+
return SymType.takeError();
184+
185+
auto Name = Sym.getName();
186+
if (!Name)
187+
return Name.takeError();
188+
auto InternedName = ES.intern(*Name);
189+
auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
190+
if (!SymFlags)
191+
return SymFlags.takeError();
192+
193+
// ELF STB_GNU_UNIQUE should map to Weak for ORC.
194+
if (Sym.getBinding() == ELF::STB_GNU_UNIQUE)
195+
*SymFlags |= JITSymbolFlags::Weak;
196+
197+
SymbolFlags[InternedName] = std::move(*SymFlags);
198+
}
199+
200+
return std::make_pair(std::move(SymbolFlags), nullptr);
201+
}
202+
203+
Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>>
204+
getGenericObjectFileSymbolInfo(ExecutionSession &ES,
205+
const object::ObjectFile &Obj) {
206+
SymbolFlagsMap SymbolFlags;
207+
for (auto &Sym : Obj.symbols()) {
208+
Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
209+
if (!SymFlagsOrErr)
210+
// TODO: Test this error.
211+
return SymFlagsOrErr.takeError();
212+
213+
// Skip symbols not defined in this object file.
214+
if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
215+
continue;
216+
217+
// Skip symbols that are not global.
218+
if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
219+
continue;
220+
221+
// Skip symbols that have type SF_File.
222+
if (auto SymType = Sym.getType()) {
223+
if (*SymType == object::SymbolRef::ST_File)
224+
continue;
225+
} else
226+
return SymType.takeError();
227+
228+
auto Name = Sym.getName();
229+
if (!Name)
230+
return Name.takeError();
231+
auto InternedName = ES.intern(*Name);
232+
auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
233+
if (!SymFlags)
234+
return SymFlags.takeError();
235+
236+
SymbolFlags[InternedName] = std::move(*SymFlags);
237+
}
238+
239+
return std::make_pair(std::move(SymbolFlags), nullptr);
240+
}
241+
242+
Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>>
243+
getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {
244+
auto Obj = object::ObjectFile::createObjectFile(ObjBuffer);
245+
246+
if (!Obj)
247+
return Obj.takeError();
248+
249+
if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get()))
250+
return getMachOObjectFileSymbolInfo(ES, *MachOObj);
251+
else if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj->get()))
252+
return getELFObjectFileSymbolInfo(ES, *ELFObj);
253+
254+
return getGenericObjectFileSymbolInfo(ES, **Obj);
255+
}
256+
170257
} // End namespace orc.
171258
} // End namespace llvm.

0 commit comments

Comments
 (0)