LLVM: lib/TextAPI/BinaryReader/DylibReader.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
24#include
25#include
26#include
27#include
28
29using namespace llvm;
33
37 return std::forward_as_tuple(CT.getArch(), CT.getOS(),
39 std::forward_as_tuple(T.getArch(), T.getOS(), T.getEnvironment());
40 });
41
42 if (I != Container.end() && *I == T)
43 return I;
44 return Container.emplace(I, T);
45}
46
49 auto getOSVersionStr = [](uint32_t V) {
51 std::string Vers;
53 VStream << OSVersion;
54 return VStream.str();
55 };
57 auto Vers = Obj->getVersionMinLoadCommand(cmd);
58 return getOSVersionStr(Vers.version);
59 };
60
64
65 for (const auto &cmd : Obj->load_commands()) {
66 std::string OSVersion;
67 switch (cmd.C.cmd) {
68 case MachO::LC_VERSION_MIN_MACOSX:
69 OSVersion = getOSVersion(cmd);
70 emplace(Triples, {Arch, "apple", "macos" + OSVersion});
71 break;
72 case MachO::LC_VERSION_MIN_IPHONEOS:
73 OSVersion = getOSVersion(cmd);
74 if (IsIntel)
75 emplace(Triples, {Arch, "apple", "ios" + OSVersion, "simulator"});
76 else
77 emplace(Triples, {Arch, "apple", "ios" + OSVersion});
78 break;
79 case MachO::LC_VERSION_MIN_TVOS:
80 OSVersion = getOSVersion(cmd);
81 if (IsIntel)
82 emplace(Triples, {Arch, "apple", "tvos" + OSVersion, "simulator"});
83 else
84 emplace(Triples, {Arch, "apple", "tvos" + OSVersion});
85 break;
86 case MachO::LC_VERSION_MIN_WATCHOS:
87 OSVersion = getOSVersion(cmd);
88 if (IsIntel)
89 emplace(Triples, {Arch, "apple", "watchos" + OSVersion, "simulator"});
90 else
91 emplace(Triples, {Arch, "apple", "watchos" + OSVersion});
92 break;
93 case MachO::LC_BUILD_VERSION: {
94 OSVersion = getOSVersionStr(Obj->getBuildVersionLoadCommand(cmd).minos);
95 switch (Obj->getBuildVersionLoadCommand(cmd).platform) {
96 case MachO::PLATFORM_MACOS:
97 emplace(Triples, {Arch, "apple", "macos" + OSVersion});
98 break;
99 case MachO::PLATFORM_IOS:
100 emplace(Triples, {Arch, "apple", "ios" + OSVersion});
101 break;
102 case MachO::PLATFORM_TVOS:
103 emplace(Triples, {Arch, "apple", "tvos" + OSVersion});
104 break;
105 case MachO::PLATFORM_WATCHOS:
106 emplace(Triples, {Arch, "apple", "watchos" + OSVersion});
107 break;
108 case MachO::PLATFORM_BRIDGEOS:
109 emplace(Triples, {Arch, "apple", "bridgeos" + OSVersion});
110 break;
111 case MachO::PLATFORM_MACCATALYST:
112 emplace(Triples, {Arch, "apple", "ios" + OSVersion, "macabi"});
113 break;
114 case MachO::PLATFORM_IOSSIMULATOR:
115 emplace(Triples, {Arch, "apple", "ios" + OSVersion, "simulator"});
116 break;
117 case MachO::PLATFORM_TVOSSIMULATOR:
118 emplace(Triples, {Arch, "apple", "tvos" + OSVersion, "simulator"});
119 break;
120 case MachO::PLATFORM_WATCHOSSIMULATOR:
121 emplace(Triples, {Arch, "apple", "watchos" + OSVersion, "simulator"});
122 break;
123 case MachO::PLATFORM_DRIVERKIT:
124 emplace(Triples, {Arch, "apple", "driverkit" + OSVersion});
125 break;
126 default:
127 break;
128 }
129 break;
130 }
131 default:
132 break;
133 }
134 }
135
136
137
138 if (Triples.empty())
139 emplace(Triples, {Arch, "apple", "unknown"});
140
141 return Triples;
142}
143
145 auto H = Obj->getHeader();
146 auto &BA = Slice.getBinaryAttrs();
147
148 switch (H.filetype) {
149 default:
153 break;
156 break;
159 break;
160 }
161
163 BA.TwoLevelNamespace = true;
165 BA.AppExtensionSafe = true;
166
167 for (const auto &LCI : Obj->load_commands()) {
168 switch (LCI.C.cmd) {
169 case MachO::LC_ID_DYLIB: {
170 auto DLLC = Obj->getDylibIDLoadCommand(LCI);
171 BA.InstallName = Slice.copyString(LCI.Ptr + DLLC.dylib.name);
172 BA.CurrentVersion = DLLC.dylib.current_version;
173 BA.CompatVersion = DLLC.dylib.compatibility_version;
174 break;
175 }
176 case MachO::LC_REEXPORT_DYLIB: {
177 auto DLLC = Obj->getDylibIDLoadCommand(LCI);
178 BA.RexportedLibraries.emplace_back(
179 Slice.copyString(LCI.Ptr + DLLC.dylib.name));
180 break;
181 }
182 case MachO::LC_SUB_FRAMEWORK: {
183 auto SFC = Obj->getSubFrameworkCommand(LCI);
184 BA.ParentUmbrella = Slice.copyString(LCI.Ptr + SFC.umbrella);
185 break;
186 }
187 case MachO::LC_SUB_CLIENT: {
188 auto SCLC = Obj->getSubClientCommand(LCI);
189 BA.AllowableClients.emplace_back(Slice.copyString(LCI.Ptr + SCLC.client));
190 break;
191 }
192 case MachO::LC_UUID: {
193 auto UUIDLC = Obj->getUuidCommand(LCI);
194 std::stringstream Stream;
195 for (unsigned I = 0; I < 16; ++I) {
196 if (I == 4 || I == 6 || I == 8 || I == 10)
197 Stream << '-';
198 Stream << std::setfill('0') << std::setw(2) << std::uppercase
199 << std::hex << static_cast(UUIDLC.uuid[I]);
200 }
201 BA.UUID = Slice.copyString(Stream.str());
202 break;
203 }
204 case MachO::LC_RPATH: {
205 auto RPLC = Obj->getRpathCommand(LCI);
206 BA.RPaths.emplace_back(Slice.copyString(LCI.Ptr + RPLC.path));
207 break;
208 }
209 case MachO::LC_SEGMENT_SPLIT_INFO: {
210 auto SSILC = Obj->getLinkeditDataLoadCommand(LCI);
211 if (SSILC.datasize == 0)
212 BA.OSLibNotForSharedCache = true;
213 break;
214 }
215 default:
216 break;
217 }
218 }
219
220 for (auto &Sect : Obj->sections()) {
221 auto SectName = Sect.getName();
222 if (!SectName)
223 return SectName.takeError();
224 if (*SectName != "__objc_imageinfo" && *SectName != "__image_info")
225 continue;
226
227 auto Content = Sect.getContents();
228 if (!Content)
229 return Content.takeError();
230
231 if ((Content->size() >= 8) && (Content->front() == 0)) {
233 if (Obj->isLittleEndian()) {
234 auto *p =
236 Flags = *p;
237 } else {
238 auto *p =
239 reinterpret_cast<const support::ubig32_t *>(Content->data() + 4);
240 Flags = *p;
241 }
242 BA.SwiftABI = (Flags >> 8) & 0xFF;
243 }
244 }
246}
247
250
251 auto parseExport = [](const auto ExportFlags,
252 auto Addr) -> std::tuple<SymbolFlags, RecordLinkage> {
258 break;
261 break;
262 }
263
268 };
269
271
273
274
275
276 for (auto &Sym : Obj->exports(Err)) {
277 auto [Flags, Linkage] = parseExport(Sym.flags(), Sym.address());
279 Exports[Sym.name()] = {Flags, Linkage};
280 }
281
282 for (const auto &Sym : Obj->symbols()) {
283 auto FlagsOrErr = Sym.getFlags();
284 if (!FlagsOrErr)
285 return FlagsOrErr.takeError();
286 auto Flags = *FlagsOrErr;
287
288 auto NameOrErr = Sym.getName();
289 if (!NameOrErr)
290 return NameOrErr.takeError();
291 auto Name = *NameOrErr;
292
295
299 else
300 continue;
304 auto Exp = Exports.find(Name);
305
306
307
308 if (Exp != Exports.end())
309 std::tie(RecordFlags, Linkage) = Exp->second;
310 else
314 } else
315 continue;
316
317 auto TypeOrErr = Sym.getType();
318 if (!TypeOrErr)
319 return TypeOrErr.takeError();
320 auto Type = *TypeOrErr;
321
325
328 else
330
331 Slice.addRecord(Name, RecordFlags, GV, Linkage);
332 }
333 return Err;
334}
335
340
343 return Err;
344
347 return Err;
348
350}
351
355
357 if (!BinOrErr)
358 return BinOrErr.takeError();
359
363 Obj->getHeader().cpusubtype);
366
368 for (const auto &T : Triples) {
372 if (auto Err = load(Obj, *Results.back(), Opt, Arch))
373 return std::move(Err);
375 }
377 }
378
379
381 "Expected a MachO universal binary.");
383
384 for (auto OI = UB->begin_objects(), OE = UB->end_objects(); OI != OE; ++OI) {
385
386 auto Arch =
389 continue;
390
391
393 continue;
394
395
396 auto ObjOrErr = OI->getAsObjectFile();
397
398
399 if (!ObjOrErr) {
401 continue;
402 }
403
404 auto &Obj = *ObjOrErr.get();
405 switch (Obj.getHeader().filetype) {
406 default:
407 break;
413 if (auto Err = load(&Obj, *Results.back(), Opt, Arch))
414 return std::move(Err);
416 }
417 break;
418 }
419 }
420
424}
425
430 if (!SlicesOrErr)
431 return SlicesOrErr.takeError();
432
434}
435
437
440 const std::unique_ptr &DiCtx) {
442 for (const auto &Symbol : Obj.symbols()) {
444 if (!FlagsOrErr) {
446 continue;
447 }
448
450 continue;
451
453 if (!AddressOrErr) {
455 continue;
456 }
457 const uint64_t Address = *AddressOrErr;
458
459 auto TypeOrErr = Symbol.getType();
460 if (!TypeOrErr) {
462 continue;
463 }
465
466 auto *DWARFCU = IsCode ? DiCtx->getCompileUnitForCodeAddress(Address)
467 : DiCtx->getCompileUnitForDataAddress(Address);
468 if (!DWARFCU)
469 continue;
470
471 const DWARFDie &DIE = IsCode ? DWARFCU->getSubroutineForAddress(Address)
472 : DWARFCU->getVariableForAddress(Address);
473 const std::string File = DIE.getDeclFile(
476
478 if (!NameOrErr) {
480 continue;
481 }
482 auto Name = *NameOrErr;
484
485 if (!File.empty() && Line != 0)
487 }
488
490}
491
495
497 if (!DSYMsOrErr) {
500 }
501 if (DSYMsOrErr->empty())
503
504 const StringRef Path = DSYMsOrErr->front();
506 if (auto Err = BufOrErr.getError())
508
509 auto BinOrErr = createBinary(*BufOrErr.get());
510 if (!BinOrErr) {
513 }
514
519
521 }
522
525 if (!ObjForArch) {
528 }
529 auto MachOOrErr = ObjForArch->getAsObjectFile();
530 if (!MachOOrErr) {
533 }
534 auto &Obj = **MachOOrErr;
538
540 }
542}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Mark last scratch load
Function Alias Analysis Results
static TripleVec::iterator emplace(TripleVec &Container, Triple &&T)
Definition DylibReader.cpp:35
static SymbolToSourceLocMap accumulateLocs(MachOObjectFile &Obj, const std::unique_ptr< DWARFContext > &DiCtx)
Definition DylibReader.cpp:439
static Error readSymbols(MachOObjectFile *Obj, RecordsSlice &Slice, const ParseOption &Opt)
Definition DylibReader.cpp:248
static Error readMachOHeader(MachOObjectFile *Obj, RecordsSlice &Slice)
Definition DylibReader.cpp:144
static TripleVec constructTriples(MachOObjectFile *Obj, const Architecture ArchT)
Definition DylibReader.cpp:47
std::vector< Triple > TripleVec
Definition DylibReader.cpp:34
static void DWARFErrorHandler(Error Err)
Definition DylibReader.cpp:436
IntervalMap< SlotIndex, DbgVariableValue, 4 > LocMap
Map of where a user value is live to that value.
Implements the TAPI Record Collection Type.
Define TAPI specific error codes.
A structured debug information entry.
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, ProcessDebugRelocations RelocAction=ProcessDebugRelocations::Process, const LoadedObjectInfo *L=nullptr, std::string DWPName="", std::function< void(Error)> RecoverableErrorHandler=WithColor::defaultErrorHandler, std::function< void(Error)> WarningHandler=WithColor::defaultWarningHandler, bool ThreadSafe=false)
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
bool has(Architecture Arch) const
SymbolFlags getFlags() const
StringRef getName() const
StringRef getBufferIdentifier() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
OSType getOS() const
Get the parsed operating system type of this triple.
ArchType getArch() const
Get the parsed architecture type of this triple.
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
The instances of the Type class are immutable: once they are created, they are never changed.
static Expected< std::vector< std::string > > findDsymObjectMembers(StringRef Path)
If the input path is a .dSYM bundle (as created by the dsymutil tool), return the paths to the object...
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Defines the MachO Dynamic Library Reader.
llvm::StringMap< RecordLoc > SymbolToSourceLocMap
LLVM_ABI Expected< Records > readFile(MemoryBufferRef Buffer, const ParseOption &Opt)
Parse Mach-O dynamic libraries to extract TAPI attributes.
Definition DylibReader.cpp:352
LLVM_ABI SymbolToSourceLocMap accumulateSourceLocFromDSYM(const StringRef DSYM, const Target &T)
Get the source location for each symbol from dylib.
Definition DylibReader.cpp:493
LLVM_ABI Expected< std::unique_ptr< InterfaceFile > > get(MemoryBufferRef Buffer)
Get TAPI file representation of binary dylib.
Definition DylibReader.cpp:427
@ MachO_DynamicLibrary_Stub
MachO Dynamic Library Stub file.
@ MachO_DynamicLibrary
MachO Dynamic Library file.
@ MachO_Bundle
MachO Bundle file.
@ EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
@ EXPORT_SYMBOL_FLAGS_KIND_REGULAR
@ EXPORT_SYMBOL_FLAGS_REEXPORT
@ EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
@ EXPORT_SYMBOL_FLAGS_KIND_MASK
LLVM_ABI StringRef getArchitectureName(Architecture Arch)
Convert an architecture slice to a string.
Architecture
Defines the architecture slices that are supported by Text-based Stub files.
LLVM_ABI PlatformType mapToPlatformType(PlatformType Platform, bool WantSim)
LLVM_ABI std::unique_ptr< InterfaceFile > convertToInterfaceFile(const Records &Slices)
LLVM_ABI SimpleSymbol parseSymbol(StringRef SymName)
Get symbol classification by parsing the name of a symbol.
llvm::SmallVector< std::shared_ptr< RecordsSlice >, 4 > Records
@ ThreadLocalValue
Thread-local value symbol.
@ WeakReferenced
Weak referenced symbol.
@ WeakDefined
Weak defined symbol.
LLVM_ABI Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType)
Convert a CPU Type and Subtype pair to an architecture slice.
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::big, unaligned > ubig32_t
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
void consumeError(Error Err)
Consume a Error without doing anything.
bool Undefineds
Capture undefined symbols too.
bool MachOHeader
Capture Mach-O header from binary, primarily load commands.
bool SymbolTable
Capture defined symbols out of export trie and n-list.
ArchitectureSet Archs
Determines arch slice to parse.