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.