LLVM: lib/Object/ArchiveWriter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

37

38#include

39#include

40

41#if !defined(_MSC_VER) && !defined(__MINGW32__)

42#include <unistd.h>

43#else

44#include <io.h>

45#endif

46

47using namespace llvm;

49

52 std::map<std::string, uint16_t> Map;

53 std::map<std::string, uint16_t> ECMap;

54};

55

58 MemberName(BufRef.getBufferIdentifier()) {}

59

61 auto MemBufferRef = this->Buf->getMemBufferRef();

64

65 if (OptionalObject) {

66 if (isaobject::MachOObjectFile(**OptionalObject))

68 if (isaobject::XCOFFObjectFile(**OptionalObject))

70 if (isaobject::COFFObjectFile(**OptionalObject) ||

71 isaobject::COFFImportFile(**OptionalObject))

74 }

75

76

78

79

80

85 auto &IRObject = castobject::IRObjectFile(**ObjOrErr);

86 auto TargetTriple = Triple(IRObject.getTargetTriple());

88 } else {

89

91 }

92 }

93

95}

96

99 bool Deterministic) {

101 if (!BufOrErr)

103

106 M.MemberName = M.Buf->getBufferIdentifier();

107 if (!Deterministic) {

109 if (!ModTimeOrErr)

110 return ModTimeOrErr.takeError();

111 M.ModTime = ModTimeOrErr.get();

113 if (!UIDOrErr)

115 M.UID = UIDOrErr.get();

117 if (!GIDOrErr)

119 M.GID = GIDOrErr.get();

121 if (!AccessModeOrErr)

122 return AccessModeOrErr.takeError();

123 M.Perms = AccessModeOrErr.get();

124 }

125 return std::move(M);

126}

127

129 bool Deterministic) {

132 if (!FDOrErr)

133 return FDOrErr.takeError();

136

139

140

141

142

145

148 if (!MemberBufferOrErr)

150

153

155 M.Buf = std::move(*MemberBufferOrErr);

156 M.MemberName = M.Buf->getBufferIdentifier();

157 if (!Deterministic) {

158 M.ModTime = std::chrono::time_point_caststd::chrono::seconds(

159 Status.getLastModificationTime());

160 M.UID = Status.getUser();

161 M.GID = Status.getGroup();

162 M.Perms = Status.permissions();

163 }

164 return std::move(M);

165}

166

167template

171 unsigned SizeSoFar = OS.tell() - OldPos;

172 assert(SizeSoFar <= Size && "Data doesn't fit in Size");

174}

175

179}

180

183}

184

187}

188

190 switch (Kind) {

195 return false;

199 return true;

200 }

202}

203

204template

209}

210

213}

214

217 unsigned UID, unsigned GID, unsigned Perms, uint64_t Size) {

219

220

221

224

227 Out << "`\n";

228}

229

230static void

233 unsigned UID, unsigned GID, unsigned Perms,

237}

238

239static void

242 unsigned UID, unsigned GID, unsigned Perms, uint64_t Size) {

243 uint64_t PosAfterHeader = Pos + 60 + Name.size();

244

246 unsigned NameWithPadding = Name.size() + Pad;

249 NameWithPadding + Size);

251 while (Pad--)

253}

254

255static void

258 unsigned UID, unsigned GID, unsigned Perms,

261 unsigned NameLen = Name.size();

262

267

272 if (NameLen) {

274 if (NameLen % 2)

276 }

277 Out << "`\n";

278}

279

281 return Thin || Name.size() >= 16 || Name.contains('/');

282}

283

285 switch (Kind) {

290 return false;

294 return true;

295 }

297}

298

299static void

306 M.Perms, Size);

309 M.Perms, Size);

310 Out << '/';

312 if (Thin) {

315 } else {

316 auto Insertion = MemberNames.insert({M.MemberName, uint64_t(0)});

317 if (Insertion.second) {

318 Insertion.first->second = StringTable.tell();

322 else

324 }

325 NamePos = Insertion.first->second;

326 }

329}

330

331namespace {

332struct MemberData {

333 std::vector Symbols;

334 std::string Header;

338 std::unique_ptr SymFile = nullptr;

339};

340}

341

343 unsigned Size = Names.size();

345 std::string Header;

349 Out << "`\n";

351 return {{}, std::move(Header), Names, Pad ? "\n" : ""};

352}

353

355 using namespace std::chrono;

356

357 if (!Deterministic)

358 return time_point_cast(system_clock::now());

360}

361

364 if (!SymFlagsOrErr)

365

368 return false;

370 return false;

372 return false;

373 return true;

374}

375

379 print<uint64_t>(Out, Kind, Val);

380 else

381 print<uint32_t>(Out, Kind, Val);

382}

383

387 uint32_t *Padding = nullptr) {

388 assert((OffsetSize == 4 || OffsetSize == 8) && "Unsupported OffsetSize");

389 uint64_t Size = OffsetSize;

391 Size += NumSyms * OffsetSize * 2;

392 else

393 Size += NumSyms * OffsetSize;

395 Size += OffsetSize;

396 Size += StringTableSize;

397

398

399

400

401

402

404 ? 0

406

408 if (Padding)

409 *Padding = Pad;

411}

412

414 uint32_t *Padding = nullptr) {

415 uint64_t Size = sizeof(uint32_t) * 2;

416 Size += NumObj * sizeof(uint32_t);

417

419 Size += sizeof(uint16_t) + S.first.length() + 1;

420

423 if (Padding)

424 *Padding = Pad;

426}

427

429 uint32_t *Padding = nullptr) {

431

433 Size += sizeof(uint16_t) + S.first.length() + 1;

434

437 if (Padding)

438 *Padding = Pad;

440}

441

444 uint64_t PrevMemberOffset = 0,

445 uint64_t NextMemberOffset = 0) {

452 PrevMemberOffset, NextMemberOffset);

453 } else {

456 }

457}

458

466 auto computeSymbolTableHeaderSize = [=] {

470 return TmpBuf.size();

471 };

472 uint32_t HeaderSize = computeSymbolTableHeaderSize();

473 uint64_t Size = strlen("!\n") + HeaderSize + SymtabSize;

474

479 }

480

481 return Size + StringMemberSize;

482}

483

488

490 return nullptr;

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510 if (!ObjOrErr) {

511 switch (Kind) {

515 Warn(ObjOrErr.takeError());

516 return nullptr;

521 return ObjOrErr.takeError();

522 }

523 }

524 return std::move(*ObjOrErr);

525 } else {

527 if (!ObjOrErr)

528 return ObjOrErr.takeError();

529 return std::move(*ObjOrErr);

530 }

531}

532

534 return SymObj != nullptr ? SymObj->is64Bit() : false;

535}

536

537

539

540

541

542

543

545

546template

549

550

551 if (AuxHeader == nullptr)

553

554

555

556

557

558 if (AuxHeaderSize < offsetof(AuxiliaryHeader, ModuleType))

560

561

562

563 if (AuxHeader->SecNumOfLoader == 0)

565

566

567

568

569

570

572 std::max(AuxHeader->MaxAlignOfText, AuxHeader->MaxAlignOfData);

573 return 1 << (Log2OfAlign > Log2OfAIXPageSize ? Log2OfMaxAlign : Log2OfAlign);

574}

575

576

577

578

579

581 XCOFFObjectFile *XCOFFObj = dyn_cast_or_null(SymObj);

582 if (!XCOFFObj)

584

585

586

587 return XCOFFObj->is64Bit()

593}

594

598 unsigned NumSyms, uint64_t PrevMemberOffset = 0,

599 uint64_t NextMemberOffset = 0,

600 bool Is64Bit = false) {

601

602

604 return;

605

611 NextMemberOffset);

612

615 else

617

618 uint64_t Pos = MembersOffset;

619 for (const MemberData &M : Members) {

621 Pos += M.PreHeadPadSize;

623 Pos += M.Header.size() + M.Data.size() + M.Padding.size();

624 continue;

625 }

626 }

627

628 for (unsigned StringOffset : M.Symbols) {

632 }

633 Pos += M.Header.size() + M.Data.size() + M.Padding.size();

634 }

635

637

640

641 while (Pad--)

643}

644

651

652 uint32_t Pos = MembersOffset;

653

654 printLE<uint32_t>(Out, Members.size());

655 for (const MemberData &M : Members) {

656 printLE(Out, Pos);

657 Pos += M.Header.size() + M.Data.size() + M.Padding.size();

658 }

659

660 printLE<uint32_t>(Out, SymMap.Map.size());

661

665 Out << S.first << '\0';

666

667 while (Pad--)

669}

670

678

679 printLE<uint32_t>(Out, SymMap.ECMap.size());

680

684 Out << S.first << '\0';

685 while (Pad--)

687}

688

691 return castllvm::object::COFFObjectFile(&Obj)->getMachine() !=

693

695 return castllvm::object::COFFImportFile(&Obj)->getMachine() !=

697

698 if (Obj.isIR()) {

701 if (!TripleStr)

702 return false;

704 return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64;

705 }

706

707 return false;

708}

709

712 return COFF::isAnyArm64(cast(&Obj)->getMachine());

713

715 return COFF::isAnyArm64(cast(&Obj)->getMachine());

716

717 if (Obj.isIR()) {

720 if (!TripleStr)

721 return false;

724 }

725

726 return false;

727}

728

734}

735

740 std::vector Ret;

741

742 if (Obj == nullptr)

743 return Ret;

744

745 std::map<std::string, uint16_t> *Map = nullptr;

748

751 continue;

752 if (Map) {

753 std::string Name;

755 if (Error E = S.printName(NameStream))

756 return std::move(E);

757 if (!Map->try_emplace(Name, Index).second)

758 continue;

760 Ret.push_back(SymNames.tell());

761 SymNames << Name << '\0';

762

763

766 }

767 } else {

768 Ret.push_back(SymNames.tell());

769 if (Error E = S.printName(SymNames))

770 return std::move(E);

771 SymNames << '\0';

772 }

773 }

774 return Ret;

775}

776

783 static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};

787

788 std::vector Ret;

789 bool HasObject = false;

790

791

792

793

795

796

797

798

799

800

801

802

803

804

805

806

807

808

809

810

811

812

813

814

815

816

817

818

819

820

821

822

823

824

825

826

827

828

829

830

831

832

833

834

835

836

837 bool UniqueTimestamps = Deterministic && isDarwin(Kind);

838 std::map<StringRef, unsigned> FilenameCount;

839 if (UniqueTimestamps) {

841 FilenameCount[M.MemberName]++;

842 for (auto &Entry : FilenameCount)

843 Entry.second = Entry.second > 1 ? 1 : 0;

844 }

845

846 std::vector<std::unique_ptr> SymFiles;

847

851 M.Buf->getMemBufferRef(), Context, Kind, [&](Error Err) {

852 Warn(createFileError(M.MemberName, std::move(Err)));

853 });

854 if (!SymFileOrErr)

856 SymFiles.push_back(std::move(*SymFileOrErr));

857 }

858 }

859

861 if (IsEC) {

863 } else {

864

865

866

867

868 bool HaveArm64 = false, HaveEC = false;

869 for (std::unique_ptr &SymFile : SymFiles) {

870 if (!SymFile)

871 continue;

872 if (!HaveArm64)

874 if (!HaveEC)

876 if (HaveArm64 && HaveEC) {

878 break;

879 }

880 }

881 }

882 }

883

884

885

887 uint64_t NextMemHeadPadSize = 0;

888

889 for (uint32_t Index = 0; Index < NewMembers.size(); ++Index) {

891 std::string Header;

893

896

897

898

899

900

901 unsigned MemberPadding =

903 unsigned TailPadding =

905 StringRef Padding = StringRef(PaddingData, MemberPadding + TailPadding);

906

908 if (UniqueTimestamps)

909

911 else

912 ModTime = M->ModTime;

913

916 std::string StringMsg =

917 "File " + M->MemberName.str() + " exceeds size limit";

918 return make_errorobject::GenericBinaryError(

920 }

921

922 std::unique_ptr CurSymFile;

923 if (!SymFiles.empty())

924 CurSymFile = std::move(SymFiles[Index]);

925

926

927

930 alignTo(M->MemberName.size(), 2);

931

932 if (M == NewMembers.begin())

933 NextMemHeadPadSize =

936 OffsetToMemData;

937

938 MemHeadPadSize = NextMemHeadPadSize;

939 Pos += MemHeadPadSize;

942

943

944

945 if (Index + 1 != SymFiles.size()) {

946 uint64_t OffsetToNextMemData =

948 alignTo(NewMembers[Index + 1].MemberName.size(), 2);

949 NextMemHeadPadSize =

952 OffsetToNextMemData;

953 NextOffset += NextMemHeadPadSize;

954 }

956 M->Perms, Size, PrevOffset, NextOffset);

957 PrevOffset = Pos;

958 } else {

960 ModTime, Size);

961 }

963

964 std::vector Symbols;

968 if (!SymbolsOrErr)

970 Symbols = std::move(*SymbolsOrErr);

971 if (CurSymFile)

972 HasObject = true;

973 }

974

975 Pos += Header.size() + Data.size() + Padding.size();

976 Ret.push_back({std::move(Symbols), std::move(Header), Data, Padding,

977 MemHeadPadSize, std::move(CurSymFile)});

978 }

979

980

981

983 SymNames << '\0' << '\0' << '\0';

984 return std::move(Ret);

985}

986

987namespace llvm {

988

992 if (Err)

993 return Err;

995 return Ret;

996}

997

998

1002 if (!PathToOrErr || !DirFromOrErr)

1004

1007

1008

1011

1012

1013 auto FromTo =

1016 auto FromI = FromTo.first;

1017 auto ToI = FromTo.second;

1018

1019

1021 for (auto FromE = sys::path::end(DirFrom); FromI != FromE; ++FromI)

1023

1024 for (auto ToE = sys::path::end(PathTo); ToI != ToE; ++ToI)

1026

1027 return std::string(Relative);

1028}

1029

1034 bool Thin, std::optional IsEC,

1036 assert((!Thin || isBSDLike(Kind)) && "Only the gnu format has a thin mode");

1037

1044

1045

1046

1047

1050

1051

1052

1054

1056 StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,

1059 return E;

1060 std::vector &Data = *DataOrErr;

1061

1062 uint64_t StringTableSize = 0;

1063 MemberData StringTableMember;

1066 StringTableSize = StringTableMember.Header.size() +

1067 StringTableMember.Data.size() +

1068 StringTableMember.Padding.size();

1069 }

1070

1071

1072 uint64_t LastMemberEndOffset = 0;

1073 uint64_t LastMemberHeaderOffset = 0;

1075 uint64_t NumSyms32 = 0;

1076

1077 for (const auto &M : Data) {

1078

1079 LastMemberEndOffset += M.PreHeadPadSize;

1080 LastMemberHeaderOffset = LastMemberEndOffset;

1081

1082 LastMemberEndOffset += M.Header.size() + M.Data.size() + M.Padding.size();

1083 NumSyms += M.Symbols.size();

1084

1085

1086

1087

1088

1089

1092 NumSyms32 += M.Symbols.size();

1093 }

1094 }

1095

1096 std::optional<uint64_t> HeadersSize;

1097

1098

1099

1101

1103 NumSyms, SymNamesBuf.size(),

1105

1106

1107

1108

1109

1110

1111

1112

1113 uint64_t Sym64Threshold = 1ULL << 32;

1114 const char *Sym64Env = std::getenv("SYM64_THRESHOLD");

1115 if (Sym64Env)

1117

1118

1119

1120

1121 if (*HeadersSize + LastMemberHeaderOffset >= Sym64Threshold) {

1124 else

1126 HeadersSize.reset();

1127 }

1128 }

1129

1130 if (Thin)

1131 Out << "!\n";

1133 Out << "\n";

1134 else

1135 Out << "!\n";

1136

1138 if (ShouldWriteSymtab) {

1139 if (!HeadersSize)

1141 Kind, Data.size(), StringTableSize, NumSyms, SymNamesBuf.size(),

1144 *HeadersSize, NumSyms);

1145

1148 }

1149

1150 if (StringTableSize)

1151 Out << StringTableMember.Header << StringTableMember.Data

1152 << StringTableMember.Padding;

1153

1154 if (ShouldWriteSymtab && SymMap.ECMap.size())

1156

1157 for (const MemberData &M : Data)

1158 Out << M.Header << M.Data << M.Padding;

1159 } else {

1161 LastMemberEndOffset += *HeadersSize;

1162 LastMemberHeaderOffset += *HeadersSize;

1163

1164

1165

1166 uint64_t MemberTableNameStrTblSize = 0;

1167 std::vector<size_t> MemberOffsets;

1168 std::vector MemberNames;

1169

1171 for (size_t I = 0, Size = NewMembers.size(); I != Size; ++I) {

1173 MemberTableNameStrTblSize += Member.MemberName.size() + 1;

1174 MemberEndOffset += Data[I].PreHeadPadSize;

1175 MemberOffsets.push_back(MemberEndOffset);

1176 MemberNames.push_back(Member.MemberName);

1177

1178

1181 alignTo(Member.MemberName.size(), 2);

1182 }

1183

1184

1185 uint64_t MemberTableSize = 20 +

1186 20 * MemberOffsets.size() +

1187 MemberTableNameStrTblSize;

1188

1193

1194 if (ShouldWriteSymtab && NumSyms)

1195

1196 for (const auto &M : Data) {

1198 M.SymFile.get(), 0,

1200 nullptr);

1201 if (!SymbolsOrErr)

1202 return SymbolsOrErr.takeError();

1203 }

1204

1205 uint64_t MemberTableEndOffset =

1206 LastMemberEndOffset +

1208

1209

1210

1211

1212 uint64_t GlobalSymbolOffset =

1213 (ShouldWriteSymtab &&

1215 ? MemberTableEndOffset

1216 : 0;

1217

1218 uint64_t GlobalSymbolOffset64 = 0;

1219 uint64_t NumSyms64 = NumSyms - NumSyms32;

1221 NumSyms64 > 0) {

1222 if (GlobalSymbolOffset == 0)

1223 GlobalSymbolOffset64 = MemberTableEndOffset;

1224 else

1225

1226

1227 GlobalSymbolOffset64 =

1229 (NumSyms32 + 1) * 8 + alignTo(SymNamesBuf32.size(), 2);

1230 }

1231

1232

1234 20);

1235

1236

1240 NewMembers.size()

1242 Data[0].PreHeadPadSize

1243 : 0,

1244 20);

1246 20);

1248 Out, 0,

1249 20);

1250

1251 for (const MemberData &M : Data) {

1252 Out << std::string(M.PreHeadPadSize, '\0');

1253 Out << M.Header << M.Data;

1254 if (M.Data.size() % 2)

1255 Out << '\0';

1256 }

1257

1258 if (NewMembers.size()) {

1259

1261 MemberTableSize, LastMemberHeaderOffset,

1262 GlobalSymbolOffset ? GlobalSymbolOffset

1263 : GlobalSymbolOffset64);

1265 for (uint64_t MemberOffset : MemberOffsets)

1267 20);

1268 for (StringRef MemberName : MemberNames)

1269 Out << MemberName << '\0';

1270

1271 if (MemberTableNameStrTblSize % 2)

1272 Out << '\0';

1273

1274

1275 if (ShouldWriteSymtab) {

1276

1277 if (GlobalSymbolOffset) {

1279 *HeadersSize, NumSyms32, LastMemberEndOffset,

1280 GlobalSymbolOffset64);

1281

1282 if (GlobalSymbolOffset64 && (SymNamesBuf32.size() % 2))

1283 Out << '\0';

1284 }

1285

1286

1287 if (GlobalSymbolOffset64)

1289 *HeadersSize, NumSyms64,

1290 GlobalSymbolOffset ? GlobalSymbolOffset

1291 : LastMemberEndOffset,

1292 0, true);

1293 }

1294 }

1295 }

1298}

1299

1302}

1303

1306 bool Deterministic, bool Thin,

1307 std::unique_ptr OldArchiveBuf,

1311 if (!Temp)

1314

1316 Deterministic, Thin, IsEC, Warn)) {

1317 if (Error DiscardError = Temp->discard())

1318 return joinErrors(std::move(E), std::move(DiscardError));

1319 return E;

1320 }

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331

1332 OldArchiveBuf.reset();

1333

1334 return Temp->keep(ArcName);

1335}

1336

1340 bool Deterministic, bool Thin,

1344

1347 Deterministic, Thin, std::nullopt, Warn))

1348 return std::move(E);

1349

1350 return std::make_unique(

1351 std::move(ArchiveBufferVector), false);

1352}

1353

1354}

This file defines the StringMap class.

#define offsetof(TYPE, MEMBER)

static void printNBits(raw_ostream &Out, object::Archive::Kind Kind, uint64_t Val)

bool isImportDescriptor(StringRef Name)

static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)

static bool isDarwin(object::Archive::Kind Kind)

static uint64_t computeECSymbolsSize(SymMap &SymMap, uint32_t *Padding=nullptr)

static Expected< std::vector< unsigned > > getSymbols(SymbolicFile *Obj, uint16_t Index, raw_ostream &SymNames, SymMap *SymMap)

static bool is64BitSymbolicFile(const SymbolicFile *SymObj)

static uint64_t computeHeadersSize(object::Archive::Kind Kind, uint64_t NumMembers, uint64_t StringMemberSize, uint64_t NumSyms, uint64_t SymNamesSize, SymMap *SymMap)

static bool isBSDLike(object::Archive::Kind Kind)

static void printBSDMemberHeader(raw_ostream &Out, uint64_t Pos, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)

static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, StringRef StringTable, uint64_t MembersOffset, unsigned NumSyms, uint64_t PrevMemberOffset=0, uint64_t NextMemberOffset=0, bool Is64Bit=false)

static const uint32_t MinBigArchiveMemDataAlign

static void writeSymbolMap(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, SymMap &SymMap, uint64_t MembersOffset)

static MemberData computeStringTable(StringRef Names)

uint16_t getAuxMaxAlignment(uint16_t AuxHeaderSize, AuxiliaryHeader *AuxHeader, uint16_t Log2OfMaxAlign)

static const uint32_t Log2OfAIXPageSize

static bool isECObject(object::SymbolicFile &Obj)

static Expected< std::unique_ptr< SymbolicFile > > getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context, object::Archive::Kind Kind, function_ref< void(Error)> Warn)

static bool isAIXBigArchive(object::Archive::Kind Kind)

static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, uint64_t Size, uint64_t PrevMemberOffset=0, uint64_t NextMemberOffset=0)

static void printRestOfMemberHeader(raw_ostream &Out, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)

static uint64_t computeSymbolTableSize(object::Archive::Kind Kind, uint64_t NumSyms, uint64_t OffsetSize, uint64_t StringTableSize, uint32_t *Padding=nullptr)

static bool isArchiveSymbol(const object::BasicSymbolRef &S)

static bool isCOFFArchive(object::Archive::Kind Kind)

static Expected< std::vector< MemberData > > computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, object::Archive::Kind Kind, bool Thin, bool Deterministic, SymtabWritingMode NeedSymbols, SymMap *SymMap, LLVMContext &Context, ArrayRef< NewArchiveMember > NewMembers, std::optional< bool > IsEC, function_ref< void(Error)> Warn)

static void printMemberHeader(raw_ostream &Out, uint64_t Pos, raw_ostream &StringTable, StringMap< uint64_t > &MemberNames, object::Archive::Kind Kind, bool Thin, const NewArchiveMember &M, sys::TimePoint< std::chrono::seconds > ModTime, uint64_t Size)

static void writeECSymbols(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, SymMap &SymMap)

static uint64_t computeSymbolMapSize(uint64_t NumObj, SymMap &SymMap, uint32_t *Padding=nullptr)

static void printLE(raw_ostream &Out, T Val)

static void printGNUSmallMemberHeader(raw_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)

static bool useStringTable(bool Thin, StringRef Name)

static bool is64BitKind(object::Archive::Kind Kind)

static uint32_t getMemberAlignment(SymbolicFile *SymObj)

static void printBigArchiveMemberHeader(raw_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size, uint64_t PrevOffset, uint64_t NextOffset)

static void printWithSpacePadding(raw_ostream &OS, T Data, unsigned Size)

static bool isAnyArm64COFF(object::SymbolicFile &Obj)

BlockVerifier::State From

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

Represents either an error or a value T.

std::error_code getError() const

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.

reference get()

Returns a reference to the stored T value.

This is an important class for using LLVM in a threaded context.

size_t getBufferSize() const

StringRef getBuffer() const

This interface provides simple read-only access to a block of memory, and provides simple methods for...

static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Given an already-open file descriptor, read the file and return a MemoryBuffer.

static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)

Open the specified memory range as a MemoryBuffer.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

bool insert(MapEntryTy *KeyValue)

insert - Insert the specified key/value pair into the map.

StringRef - Represent a constant reference to a string, i.e.

bool getAsInteger(unsigned Radix, T &Result) const

Parse the current string as an integer of the specified radix.

constexpr size_t size() const

size - Get the string size.

A table of densely packed, null-terminated strings indexed by offset.

constexpr size_t size() const

Returns the byte size of the table.

Triple - Helper class for working with autoconf configuration names.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

An efficient, type-erasing, non-owning reference to a callable.

Expected< unsigned > getGID() const

Expected< MemoryBufferRef > getMemoryBufferRef() const

Expected< unsigned > getUID() const

Expected< sys::fs::perms > getAccessMode() const

Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const

static object::Archive::Kind getDefaultKind()

static object::Archive::Kind getDefaultKindForTriple(const Triple &T)

static const uint64_t MaxMemberSize

Size field is 10 decimal digits long.

This is a value type class that represents a single symbol in the list of symbols in the object file.

Expected< uint32_t > getFlags() const

Get symbol flags (bitwise OR of SymbolRef::Flags)

bool isCOFFImportFile() const

MemoryBufferRef getMemoryBufferRef() const

static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)

static Expected< std::unique_ptr< SymbolicFile > > createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type, LLVMContext *Context, bool InitContent=true)

virtual bool is64Bit() const =0

basic_symbol_iterator_range symbols() const

static bool isSymbolicFile(file_magic Type, const LLVMContext *Context)

const XCOFFAuxiliaryHeader32 * auxiliaryHeader32() const

const XCOFFFileHeader64 * fileHeader64() const

const XCOFFFileHeader32 * fileHeader32() const

const XCOFFAuxiliaryHeader64 * auxiliaryHeader64() const

bool is64Bit() const override

A raw_ostream that writes to a file descriptor.

This class implements an extremely fast bulk output stream that can only output to a stream.

uint64_t tell() const

tell - Return the current offset with the file.

raw_ostream & write(unsigned char C)

raw_ostream & indent(unsigned NumSpaces)

indent - Insert 'NumSpaces' spaces.

A raw_ostream that writes to an std::string.

A raw_ostream that writes to an SmallVector or SmallString.

static Expected< TempFile > create(const Twine &Model, unsigned Mode=all_read|all_write, OpenFlags ExtraFlags=OF_None)

This creates a temporary file with createUniqueFile and schedules it for deletion with sys::RemoveFil...

Represents the result of a call to sys::fs::status().

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ IMAGE_FILE_MACHINE_ARM64

bool isAnyArm64(T Machine)

constexpr std::string_view NullImportDescriptorSymbolName

constexpr std::string_view NullThunkDataPrefix

constexpr std::string_view NullThunkDataSuffix

constexpr std::string_view ImportDescriptorPrefix

void write(void *memory, value_type value, endianness endian)

Write a value to memory with a particular endianness.

void make_absolute(const Twine &current_directory, SmallVectorImpl< char > &path)

Make path an absolute path.

const file_t kInvalidFile

std::error_code closeFile(file_t &F)

Close the file object.

std::error_code status(const Twine &path, file_status &result, bool follow=true)

Get file status as if by POSIX stat().

Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)

Opens the file with the given name in a read-only mode, returning its open file descriptor.

const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get begin iterator over path.

bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)

In-place remove any '.

StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get parent path.

std::string convert_to_slash(StringRef path, Style style=Style::native)

Replaces backslashes with slashes if Windows.

StringRef root_name(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get root name.

void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to path.

const_iterator end(StringRef path LLVM_LIFETIME_BOUND)

Get end iterator over path.

std::chrono::time_point< std::chrono::system_clock, D > TimePoint

A time point on the system clock.

TimePoint< std::chrono::seconds > toTimePoint(std::time_t T)

Convert a std::time_t to a TimePoint.

std::time_t toTimeT(TimePoint<> TP)

Convert a TimePoint to std::time_t.

This is an optimization pass for GlobalISel generic memory operations.

file_magic identify_magic(StringRef magic)

Identify the type of a binary file based on how magical it is.

void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})

Log all errors (if any) in E to OS.

Expected< std::unique_ptr< MemoryBuffer > > writeArchiveToBuffer(ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, function_ref< void(Error)> Warn=warnToStderr)

Error createFileError(const Twine &F, Error E)

Concatenate a source file path and/or name with an Error.

Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, std::optional< bool > IsEC=std::nullopt, function_ref< void(Error)> Warn=warnToStderr)

std::error_code make_error_code(BitcodeError E)

Expected< std::string > getBitcodeTargetTriple(MemoryBufferRef Buffer)

Read the header of the specified bitcode buffer and extract just the triple information.

Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)

Error joinErrors(Error E1, Error E2)

Concatenate errors.

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

constexpr T alignToPowerOf2(U Value, V Align)

Will overflow only if result is not representable in T.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

uint64_t offsetToAlignment(uint64_t Value, Align Alignment)

Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

void warnToStderr(Error Err)

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

Expected< std::string > computeArchiveRelativePath(StringRef From, StringRef To)

Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

static ErrorOr< SmallString< 128 > > canonicalizePath(StringRef P)

std::error_code errnoAsErrorCode()

Helper to get errno as an std::error_code.

Error writeArchiveToStream(raw_ostream &Out, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::optional< bool > IsEC=std::nullopt, function_ref< void(Error)> Warn=warnToStderr)

void consumeError(Error Err)

Consume a Error without doing anything.

std::map< std::string, uint16_t > ECMap

std::map< std::string, uint16_t > Map

This struct is a compact representation of a valid (non-zero power of two) alignment.

object::Archive::Kind detectKindFromObject() const

NewArchiveMember()=default

static Expected< NewArchiveMember > getFile(StringRef FileName, bool Deterministic)

static Expected< NewArchiveMember > getOldMember(const object::Archive::Child &OldMember, bool Deterministic)

std::unique_ptr< MemoryBuffer > Buf

file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...