[AMDGPU] prevent shrinking udiv/urem if either operand is in (SignedMax,UnsignedMax...
[llvm-project.git] / llvm / lib / ExecutionEngine / Orc / ObjectFileInterface.cpp
blob71221c2d3fce5409ee0e974dbd2b2c71b0bc48df
1 //===------ ObjectFileInterface.cpp - MU interface utils for objects ------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
10 #include "llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h"
11 #include "llvm/Object/COFF.h"
12 #include "llvm/Object/ELFObjectFile.h"
13 #include "llvm/Object/MachO.h"
14 #include "llvm/Object/ObjectFile.h"
15 #include <optional>
17 #define DEBUG_TYPE "orc"
19 namespace llvm {
20 namespace orc {
22 void addInitSymbol(MaterializationUnit::Interface &I, ExecutionSession &ES,
23 StringRef ObjFileName) {
24 assert(!I.InitSymbol && "I already has an init symbol");
25 size_t Counter = 0;
27 do {
28 std::string InitSymString;
29 raw_string_ostream(InitSymString)
30 << "$." << ObjFileName << ".__inits." << Counter++;
31 I.InitSymbol = ES.intern(InitSymString);
32 } while (I.SymbolFlags.count(I.InitSymbol));
34 I.SymbolFlags[I.InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly;
37 static Expected<MaterializationUnit::Interface>
38 getMachOObjectFileSymbolInfo(ExecutionSession &ES,
39 const object::MachOObjectFile &Obj) {
40 MaterializationUnit::Interface I;
42 for (auto &Sym : Obj.symbols()) {
43 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
44 if (!SymFlagsOrErr)
45 // TODO: Test this error.
46 return SymFlagsOrErr.takeError();
48 // Skip symbols not defined in this object file.
49 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
50 continue;
52 // Skip symbols that are not global.
53 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
54 continue;
56 // Skip symbols that have type SF_File.
57 if (auto SymType = Sym.getType()) {
58 if (*SymType == object::SymbolRef::ST_File)
59 continue;
60 } else
61 return SymType.takeError();
63 auto Name = Sym.getName();
64 if (!Name)
65 return Name.takeError();
66 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
67 if (!SymFlags)
68 return SymFlags.takeError();
70 // Strip the 'exported' flag from MachO linker-private symbols.
71 if (Name->starts_with("l"))
72 *SymFlags &= ~JITSymbolFlags::Exported;
74 I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
77 for (auto &Sec : Obj.sections()) {
78 auto SecType = Obj.getSectionType(Sec);
79 if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) {
80 addInitSymbol(I, ES, Obj.getFileName());
81 break;
83 auto SegName = Obj.getSectionFinalSegmentName(Sec.getRawDataRefImpl());
84 auto SecName = cantFail(Obj.getSectionName(Sec.getRawDataRefImpl()));
85 if (isMachOInitializerSection(SegName, SecName)) {
86 addInitSymbol(I, ES, Obj.getFileName());
87 break;
91 return I;
94 static Expected<MaterializationUnit::Interface>
95 getELFObjectFileSymbolInfo(ExecutionSession &ES,
96 const object::ELFObjectFileBase &Obj) {
97 MaterializationUnit::Interface I;
99 for (auto &Sym : Obj.symbols()) {
100 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
101 if (!SymFlagsOrErr)
102 // TODO: Test this error.
103 return SymFlagsOrErr.takeError();
105 // Skip symbols not defined in this object file.
106 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
107 continue;
109 // Skip symbols that are not global.
110 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
111 continue;
113 // Skip symbols that have type SF_File.
114 if (auto SymType = Sym.getType()) {
115 if (*SymType == object::SymbolRef::ST_File)
116 continue;
117 } else
118 return SymType.takeError();
120 auto Name = Sym.getName();
121 if (!Name)
122 return Name.takeError();
124 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
125 if (!SymFlags)
126 return SymFlags.takeError();
128 // ELF STB_GNU_UNIQUE should map to Weak for ORC.
129 if (Sym.getBinding() == ELF::STB_GNU_UNIQUE)
130 *SymFlags |= JITSymbolFlags::Weak;
132 I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
135 SymbolStringPtr InitSymbol;
136 for (auto &Sec : Obj.sections()) {
137 if (auto SecName = Sec.getName()) {
138 if (isELFInitializerSection(*SecName)) {
139 addInitSymbol(I, ES, Obj.getFileName());
140 break;
145 return I;
148 static Expected<MaterializationUnit::Interface>
149 getCOFFObjectFileSymbolInfo(ExecutionSession &ES,
150 const object::COFFObjectFile &Obj) {
151 MaterializationUnit::Interface I;
152 std::vector<std::optional<object::coff_aux_section_definition>> ComdatDefs(
153 Obj.getNumberOfSections() + 1);
154 for (auto &Sym : Obj.symbols()) {
155 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
156 if (!SymFlagsOrErr)
157 // TODO: Test this error.
158 return SymFlagsOrErr.takeError();
160 // Handle comdat symbols
161 auto COFFSym = Obj.getCOFFSymbol(Sym);
162 bool IsWeak = false;
163 if (auto *Def = COFFSym.getSectionDefinition()) {
164 auto Sec = Obj.getSection(COFFSym.getSectionNumber());
165 if (!Sec)
166 return Sec.takeError();
167 if (((*Sec)->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT) &&
168 Def->Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
169 ComdatDefs[COFFSym.getSectionNumber()] = *Def;
170 continue;
173 if (!COFF::isReservedSectionNumber(COFFSym.getSectionNumber()) &&
174 ComdatDefs[COFFSym.getSectionNumber()]) {
175 auto Def = ComdatDefs[COFFSym.getSectionNumber()];
176 if (Def->Selection != COFF::IMAGE_COMDAT_SELECT_NODUPLICATES) {
177 IsWeak = true;
179 ComdatDefs[COFFSym.getSectionNumber()] = std::nullopt;
180 } else {
181 // Skip symbols not defined in this object file.
182 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
183 continue;
186 // Skip symbols that are not global.
187 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
188 continue;
190 // Skip symbols that have type SF_File.
191 if (auto SymType = Sym.getType()) {
192 if (*SymType == object::SymbolRef::ST_File)
193 continue;
194 } else
195 return SymType.takeError();
197 auto Name = Sym.getName();
198 if (!Name)
199 return Name.takeError();
201 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
202 if (!SymFlags)
203 return SymFlags.takeError();
204 *SymFlags |= JITSymbolFlags::Exported;
206 // Weak external is always a function
207 if (COFFSym.isWeakExternal())
208 *SymFlags |= JITSymbolFlags::Callable;
210 if (IsWeak)
211 *SymFlags |= JITSymbolFlags::Weak;
213 I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
216 SymbolStringPtr InitSymbol;
217 for (auto &Sec : Obj.sections()) {
218 if (auto SecName = Sec.getName()) {
219 if (isCOFFInitializerSection(*SecName)) {
220 addInitSymbol(I, ES, Obj.getFileName());
221 break;
223 } else
224 return SecName.takeError();
227 return I;
230 Expected<MaterializationUnit::Interface>
231 getGenericObjectFileSymbolInfo(ExecutionSession &ES,
232 const object::ObjectFile &Obj) {
233 MaterializationUnit::Interface I;
235 for (auto &Sym : Obj.symbols()) {
236 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
237 if (!SymFlagsOrErr)
238 // TODO: Test this error.
239 return SymFlagsOrErr.takeError();
241 // Skip symbols not defined in this object file.
242 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
243 continue;
245 // Skip symbols that are not global.
246 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
247 continue;
249 // Skip symbols that have type SF_File.
250 if (auto SymType = Sym.getType()) {
251 if (*SymType == object::SymbolRef::ST_File)
252 continue;
253 } else
254 return SymType.takeError();
256 auto Name = Sym.getName();
257 if (!Name)
258 return Name.takeError();
260 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
261 if (!SymFlags)
262 return SymFlags.takeError();
264 I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
267 return I;
270 Expected<MaterializationUnit::Interface>
271 getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {
272 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer);
274 if (!Obj)
275 return Obj.takeError();
277 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get()))
278 return getMachOObjectFileSymbolInfo(ES, *MachOObj);
279 else if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj->get()))
280 return getELFObjectFileSymbolInfo(ES, *ELFObj);
281 else if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj->get()))
282 return getCOFFObjectFileSymbolInfo(ES, *COFFObj);
284 return getGenericObjectFileSymbolInfo(ES, **Obj);
287 } // End namespace orc.
288 } // End namespace llvm.