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

1

2

3

4

5

6

7

8

9

10

11

12

30#include

31#include

32#include

33#include

34#include

35#include <system_error>

36

37using namespace llvm;

38using namespace object;

40

41void Archive::anchor() {}

42

44 std::string StringMsg = "truncated or malformed archive (" + Msg.str() + ")";

45 return make_error(std::move(StringMsg),

47}

48

52 StringRef Msg("remaining size of archive too small for next archive "

53 "member header ");

54

56 if (NameOrErr)

58

62}

63

64template <class T, std::size_t N>

67}

68

69template

72}

73

74template

77}

78

85}

88 return reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();

89}

90

93

95 const char *RawHeaderPtr,

99 if (RawHeaderPtr == nullptr)

100 return;

102

105 return;

106 }

108 if (Err) {

109 std::string Buf;

114 std::string Msg("terminator characters in archive member \"" + Buf +

115 "\" not the correct \"`\\n\" values for the archive "

116 "member header ");

118 if (!NameOrErr) {

122 } else

124 }

125 return;

126 }

127}

128

130 const char *RawHeaderPtr,

134 if (RawHeaderPtr == nullptr)

135 return;

137

139 if (Err)

140 *Err = malformedError("malformed AIX big archive: remaining buffer is "

141 "unable to contain next archive member");

142 return;

143 }

144

147 if (Err)

148 *Err = std::move(SubErr);

149 }

150}

151

152

153

155 char EndCond;

161 return malformedError("name contains a leading space for archive member "

162 "header at offset " +

164 }

165 EndCond = ' ';

167 EndCond = ' ';

168 else

169 EndCond = '/';

175

177}

178

187 " field in archive member header are not "

188 "all decimal numbers: '" +

189 RawField +

190 "' for the archive "

191 "member header at offset " +

193 }

195}

196

205 " field in archive member header are not "

206 "all octal numbers: '" +

207 RawField +

208 "' for the archive "

209 "member header at offset " +

211 }

213}

214

218 if (!NameLenOrErr)

219

222

223

224

226 StringRef NameTerminator = "`\n";

227 StringRef NameStringWithNameTerminator =

229 if (!NameStringWithNameTerminator.ends_with(NameTerminator)) {

231 reinterpret_cast<const char *>(ArMemHdr->Name + NameLenWithPadding) -

233

235 "name does not have name terminator \"`\\n\" for archive member"

236 "header at offset " +

238 }

240}

241

242

243

245

246

247

248

252 return malformedError("archive header truncated before the name field "

253 "for archive member header at offset " +

254 Twine(ArchiveOffset));

255 }

256

257

259 if (!NameOrErr)

262

263

264 if (Name[0] == '/') {

265 if (Name.size() == 1)

267 if (Name.size() == 2 && Name[1] == '/')

269

270

271 if (Name == "//")

273

274

275 if (Name == "//")

277

278

279 std::size_t StringOffset;

280 if (Name.substr(1).rtrim(' ').getAsInteger(10, StringOffset)) {

281 std::string Buf;

287 return malformedError("long name offset characters after the '/' are "

288 "not all decimal numbers: '" +

289 Buf + "' for archive member header at offset " +

290 Twine(ArchiveOffset));

291 }

292

293

298 " past the end of the string table for archive "

299 "member header at offset " +

300 Twine(ArchiveOffset));

301 }

302

303

309 return malformedError("string table at long name offset " +

310 Twine(StringOffset) + "not terminated");

311 }

313 }

315 }

316

317 if (Name.starts_with("#1/")) {

319 if (Name.substr(3).rtrim(' ').getAsInteger(10, NameLength)) {

320 std::string Buf;

326 return malformedError("long name length characters after the #1/ are "

327 "not all decimal numbers: '" +

328 Buf + "' for archive member header at offset " +

329 Twine(ArchiveOffset));

330 }

335 " extends past the end of the member or archive "

336 "for archive member header at offset " +

337 Twine(ArchiveOffset));

338 }

340 NameLength)

342 }

343

344

345 if (Name[Name.size() - 1] != '/')

346 return Name.rtrim(' ');

347

348

349 return Name.drop_back(1);

350}

351

354}

355

359}

360

364 if (!SizeOrErr)

366

368 if (!NameLenOrErr)

370

371 return *SizeOrErr + alignTo(*NameLenOrErr, 2);

372}

373

377}

378

382}

383

387 if (!AccessModeOrErr)

388 return AccessModeOrErr.takeError();

389 return static_cast<sys::fs::perms>(*AccessModeOrErr);

390}

391

396

397 if (!SecondsOrErr)

399

401}

402

405 if (User.empty())

406 return 0;

408}

409

412 if (Group.empty())

413 return 0;

415}

416

419 if (!NameOrErr)

423}

424

428 if (!isThinOrErr)

430

434 if (!MemberSize)

436

437 Size += MemberSize.get();

438 }

439

440

441 const char *NextLoc =

443

445 return nullptr;

446

447 return NextLoc;

448}

449

452 static_cast<const BigArchive *>(Parent)->getLastChildOffset())

453 return nullptr;

454

456 if (!NextOffsetOrErr)

457 return NextOffsetOrErr.takeError();

459}

460

463 : Parent(Parent), Data(Data), StartOfFile(StartOfFile) {

465}

466

468 : Parent(Parent) {

469 if (!Start) {

470 Header = nullptr;

471 StartOfFile = -1;

472 return;

473 }

474

476 Start,

478 : 0,

479 Err);

480

481

482

483

484

485 assert(Err && "Err can't be nullptr if Start is not a nullptr");

486

488

489

490

491 if (*Err)

492 return;

493

497 if (!isThinOrErr) {

499 return;

500 }

504 if (!MemberSize) {

506 return;

507 }

508 Size += MemberSize.get();

510 }

511

512

513 StartOfFile = Header->getSizeOf();

514

516 if (!NameOrErr) {

518 return;

519 }

521

523

524

525 StartOfFile += ((Name.size() + 1) >> 1) << 1;

526 } else if (Name.starts_with("#1/")) {

528 StringRef RawNameSize = Name.substr(3).rtrim(' ');

531 *Err = malformedError("long name length characters after the #1/ are "

532 "not all decimal numbers: '" +

533 RawNameSize +

534 "' for archive member header at offset " +

536 return;

537 }

539 }

540}

541

543 if (Parent->IsThin)

544 return Header->getSize();

545 return Data.size() - StartOfFile;

546}

547

549 return Header->getSize();

550}

551

552Expected Archive::Child::isThinMember() const { return Header->isThin(); }

553

557 return isThin.takeError();

560 if (!NameOrErr)

564 return std::string(Name);

565

567 Parent->getMemoryBufferRef().getBufferIdentifier());

569 return std::string(FullName);

570}

571

574 if (!isThinOrErr)

580 return Size.takeError();

582 }

584 if (!FullNameOrErr)

585 return FullNameOrErr.takeError();

586 const std::string &FullName = *FullNameOrErr;

588 if (std::error_code EC = Buf.getError())

590 Parent->ThinBuffers.push_back(std::move(*Buf));

591 return Parent->ThinBuffers.back()->getBuffer();

592}

593

596 if (!NextLocOrErr)

598

599 const char *NextLoc = *NextLocOrErr;

600

601

602 if (NextLoc == nullptr)

603 return Child(nullptr, nullptr, nullptr);

604

605

606 if (NextLoc > Parent->Data.getBufferEnd()) {

607 std::string Msg("offset to next archive member past the end of the archive "

608 "after member ");

610 if (!NameOrErr) {

614 } else

616 }

617

619 Child Ret(Parent, NextLoc, &Err);

620 if (Err)

621 return std::move(Err);

622 return Ret;

623}

624

626 const char *a = Parent->Data.getBuffer().data();

627 const char *c = Data.data();

629 return offset;

630}

631

634 if (!RawSizeOrErr)

638 Header->getName(Header->getSizeOf() + RawSize);

639 if (!NameOrErr)

643}

644

647 if (!NameOrErr)

651 if (!Buf)

654}

655

659 if (!BuffOrErr)

661

662 auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);

663 if (BinaryOrErr)

664 return std::move(*BinaryOrErr);

665 return BinaryOrErr.takeError();

666}

667

670 std::unique_ptr Ret;

671 StringRef Buffer = Source.getBuffer();

672

674 Ret = std::make_unique(Source, Err);

675 else

676 Ret = std::make_unique(Source, Err);

677

678 if (Err)

679 return std::move(Err);

680 return std::move(Ret);

681}

682

683std::unique_ptr

685 Error *Err) const {

688 return std::make_unique(this, RawHeaderPtr, Size, Err);

689 return std::make_unique(this, RawHeaderPtr, Size,

690 Err);

691}

692

696

699

701}

702

704 FirstRegularData = C.Data;

705 FirstRegularStartOfFile = C.StartOfFile;

706}

707

712

714 IsThin = true;

716 IsThin = false;

719 IsThin = false;

720 return;

721 } else {

722 Err = make_error("file too small to be an archive",

724 return;

725 }

726

727

728

729

730

731

733

734

736 if (Err)

737 return;

739

740

741 if (I == E) {

743 return;

744 }

746

747 auto Increment = [&]() {

748 ++I;

749 if (Err)

750 return true;

751 C = &*I;

752 return false;

753 };

754

756 if (!NameOrErr) {

758 return;

759 }

761

762

763

764

765

766

767

768

769

770

771

772

773

774

775

776

777

778

779

780

781 if (Name == "__.SYMDEF" || Name == "__.SYMDEF_64") {

782 if (Name == "__.SYMDEF")

784 else

786

787

789 if (!BufOrErr) {

791 return;

792 }

794 if (Increment())

795 return;

797

799 return;

800 }

801

802 if (Name.starts_with("#1/")) {

804

806 if (!NameOrErr) {

808 return;

809 }

811 if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {

812

813

815 if (!BufOrErr) {

817 return;

818 }

820 if (Increment())

821 return;

822 } else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {

824

825

827 if (!BufOrErr) {

829 return;

830 }

832 if (Increment())

833 return;

834 }

836 return;

837 }

838

839

840

841

842

843

844 bool has64SymTable = false;

845 if (Name == "/" || Name == "/SYM64/") {

846

847

849 if (!BufOrErr) {

851 return;

852 }

854 if (Name == "/SYM64/")

855 has64SymTable = true;

856

857 if (Increment())

858 return;

859 if (I == E) {

861 return;

862 }

864 if (!NameOrErr) {

866 return;

867 }

869 }

870

871 if (Name == "//") {

873

874

876 if (!BufOrErr) {

878 return;

879 }

881 if (Increment())

882 return;

885 return;

886 }

887

888 if (Name[0] != '/') {

892 return;

893 }

894

895 if (Name != "/") {

897 return;

898 }

899

901

902

904 if (!BufOrErr) {

906 return;

907 }

909

910 if (Increment())

911 return;

912

913 if (I == E) {

916 return;

917 }

918

919 NameOrErr = C->getRawName();

920 if (!NameOrErr) {

922 return;

923 }

925

926 if (Name == "//") {

927

928

930 if (!BufOrErr) {

932 return;

933 }

935 if (Increment())

936 return;

937

938 if (I == E) {

941 return;

942 }

943

944 NameOrErr = C->getRawName();

945 if (!NameOrErr) {

947 return;

948 }

950 }

951

952 if (Name == "//") {

953

954

955

956

958 if (!BufOrErr) {

960 return;

961 }

963 if (Increment())

964 return;

965 }

966

969}

970

972 if (T.isOSDarwin())

974 if (T.isOSAIX())

976 if (T.isOSWindows())

979}

980

984}

985

987 bool SkipInternal) const {

990

991 if (SkipInternal)

993 Child(this, FirstRegularData, FirstRegularStartOfFile), Err);

994

996 Child C(this, Loc, &Err);

997 if (Err)

1000}

1001

1004}

1005

1007

1008

1010 return SymbolCount <= SymbolIndex &&

1012}

1013

1015 if (isECSymbol())

1016 return Parent->ECSymbolTable.begin() + StringIndex;

1017 return Parent->getSymbolTable().begin() + StringIndex;

1018}

1019

1021 const char *Buf = Parent->getSymbolTable().begin();

1022 const char *Offsets = Buf;

1023 if (Parent->kind() == K_GNU64 || Parent->kind() == K_DARWIN64 ||

1025 Offsets += sizeof(uint64_t);

1026 else

1027 Offsets += sizeof(uint32_t);

1029 if (Parent->kind() == K_GNU) {

1031 } else if (Parent->kind() == K_GNU64 || Parent->kind() == K_AIXBIG) {

1033 } else if (Parent->kind() == K_BSD) {

1034

1035

1036

1037

1038

1039

1041 } else if (Parent->kind() == K_DARWIN64) {

1042

1043

1044

1045

1046

1047

1049 } else {

1050

1052 Buf += MemberCount * 4 + 4;

1053

1056 if (SymbolIndex < SymbolCount) {

1057

1058 const char *Indices = Buf + 4;

1059

1060

1061

1062 OffsetIndex = read16le(Indices + SymbolIndex * 2);

1063 } else if (isECSymbol()) {

1064

1065 const char *Indices = Parent->ECSymbolTable.begin() + 4;

1066

1067

1068

1069 OffsetIndex = read16le(Indices + (SymbolIndex - SymbolCount) * 2);

1070 } else {

1072 }

1073

1074 --OffsetIndex;

1075

1076 if (OffsetIndex >= MemberCount)

1078

1080 }

1081

1082 const char *Loc = Parent->getData().begin() + Offset;

1084 Child C(Parent, Loc, &Err);

1085 if (Err)

1086 return std::move(Err);

1087 return C;

1088}

1089

1092 if (Parent->kind() == K_BSD) {

1093

1094

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1105

1106 const char *Buf = Parent->getSymbolTable().begin();

1108 RanlibCount = read32le(Buf) / 8;

1109

1110

1111

1112 if (t.SymbolIndex + 1 < RanlibCount) {

1113 const char *Ranlibs = Buf + 4;

1116 CurRanStrx = read32le(Ranlibs + t.SymbolIndex * 8);

1117 NextRanStrx = read32le(Ranlibs + (t.SymbolIndex + 1) * 8);

1118 t.StringIndex -= CurRanStrx;

1119 t.StringIndex += NextRanStrx;

1120 }

1122

1123 t.StringIndex = Parent->ECSymbolTable.find('\0', t.StringIndex) + 1;

1124 } else {

1125

1126 t.StringIndex = Parent->getSymbolTable().find('\0', t.StringIndex) + 1;

1127 }

1128 ++t.SymbolIndex;

1129 return t;

1130}

1131

1135

1139 symbol_count = read32be(buf);

1140 buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));

1143 buf += sizeof(uint64_t) + (symbol_count * (sizeof(uint64_t)));

1145

1146

1147

1148

1149

1150

1152 ranlib_count = read32le(buf) / 8;

1153 const char *ranlibs = buf + 4;

1155 ran_strx = read32le(ranlibs);

1156 buf += sizeof(uint32_t) + (ranlib_count * (2 * (sizeof(uint32_t))));

1157

1159 buf += ran_strx;

1161

1162

1163

1164

1165

1166

1168 ranlib_count = read64le(buf) / 16;

1169 const char *ranlibs = buf + 8;

1171 ran_strx = read64le(ranlibs);

1172 buf += sizeof(uint64_t) + (ranlib_count * (2 * (sizeof(uint64_t))));

1173

1175 buf += ran_strx;

1178 } else {

1181 member_count = read32le(buf);

1182 buf += 4 + (member_count * 4);

1183 symbol_count = read32le(buf);

1184 buf += 4 + (symbol_count * 2);

1185 }

1188}

1189

1192}

1193

1196

1197

1205

1207 size_t StringIndex = sizeof(uint32_t) + Count * sizeof(uint16_t);

1209 return malformedError("invalid EC symbols size. Size was " +

1211 Twine(StringIndex));

1212

1215

1216 for (uint32_t i = 0; i < Count; ++i) {

1218 if (!Index)

1220 if (Index > MemberCount)

1222 " is larger than member count " +

1223 Twine(MemberCount));

1224

1227 return malformedError("malformed EC symbol names: not null-terminated");

1228 ++StringIndex;

1229 }

1230 }

1231

1237}

1238

1241 return 0;

1252 member_count = read32le(buf);

1253 buf += 4 + (member_count * 4);

1255}

1256

1259 return 0;

1261}

1262

1266

1267 for (; bs != es; ++bs) {

1269 if (SymName == name) {

1270 if (auto MemberOrErr = bs->getMember())

1271 return Child(*MemberOrErr);

1272 else

1273 return MemberOrErr.takeError();

1274 }

1275 }

1276 return std::nullopt;

1277}

1278

1279

1282}

1283

1285

1287 uint64_t GlobalSymtabOffset,

1288 const char *&GlobalSymtabLoc,

1291 uint64_t GlobalSymtabContentOffset =

1293 if (GlobalSymtabContentOffset > BufferSize)

1295 Twine(BitMessage) + " global symbol table header at offset 0x" +

1298 " goes past the end of file");

1299

1302 reinterpret_cast<const BigArMemHdrType *>(GlobalSymtabLoc);

1305 return malformedError(Twine(BitMessage) + " global symbol table size \"" +

1306 RawOffset + "\" is not a number");

1307

1308 if (GlobalSymtabContentOffset + Size > BufferSize)

1310 Twine(BitMessage) + " global symbol table content at offset 0x" +

1311 Twine::utohexstr(GlobalSymtabContentOffset) + " and size 0x" +

1313

1315}

1316

1322};

1323

1324static void

1326 const char *GlobalSymtabLoc, uint64_t Size) {

1327

1328

1329

1330

1331

1332

1333

1338 unsigned SymOffsetsSize = 8 * (SymNum + 1);

1339 uint64_t SymbolTableStringSize = Size - SymOffsetsSize;

1343}

1344

1346 : Archive(Source, Err) {

1351

1352 if (BufferSize < sizeof(FixLenHdr)) {

1353 Err = malformedError("malformed AIX big archive: incomplete fixed length "

1354 "header, the archive is only" +

1355 Twine(BufferSize) + " byte(s)");

1356 return;

1357 }

1358

1361

1362 Err = malformedError("malformed AIX big archive: first member offset \"" +

1363 RawOffset + "\" is not a number");

1364

1367

1368 Err = malformedError("malformed AIX big archive: last member offset \"" +

1369 RawOffset + "\" is not a number");

1370

1371 uint64_t GlobSymtab32Offset = 0;

1373 if (RawOffset.getAsInteger(10, GlobSymtab32Offset)) {

1375 "offset of 32-bit members \"" +

1376 RawOffset + "\" is not a number");

1377 return;

1378 }

1379

1380 uint64_t GlobSymtab64Offset = 0;

1382 if (RawOffset.getAsInteger(10, GlobSymtab64Offset)) {

1384 "offset of 64-bit members\"" +

1385 RawOffset + "\" is not a number");

1386 return;

1387 }

1388

1389 const char *GlobSymtab32Loc = nullptr;

1390 const char *GlobSymtab64Loc = nullptr;

1391 uint64_t GlobSymtab32Size = 0;

1392 uint64_t GlobSymtab64Size = 0;

1394

1395 if (GlobSymtab32Offset) {

1396 Err =

1398 GlobSymtab32Loc, GlobSymtab32Size, "32-bit");

1399 if (Err)

1400 return;

1401

1403 }

1404

1405 if (GlobSymtab64Offset) {

1406 Err =

1408 GlobSymtab64Loc, GlobSymtab64Size, "64-bit");

1409 if (Err)

1410 return;

1411

1413 }

1414

1416

1417 if (GlobSymtab32Offset)

1419 if (GlobSymtab64Offset)

1421

1422 if (SymtabInfos.size() == 1) {

1423 SymbolTable = SymtabInfos[0].SymbolTable;

1424 StringTable = SymtabInfos[0].StringTable;

1425 } else if (SymtabInfos.size() == 2) {

1426

1427

1429 uint64_t SymNum = SymtabInfos[0].SymNum + SymtabInfos[1].SymNum;

1431

1432 Out << SymtabInfos[0].SymbolOffsetTable;

1433 Out << SymtabInfos[1].SymbolOffsetTable;

1434

1435 Out << SymtabInfos[0].StringTable;

1436 Out << SymtabInfos[1].StringTable;

1438

1440 SymtabInfos[0].StringTable.size() +

1441 SymtabInfos[1].StringTable.size());

1442 }

1443

1445 if (Err)

1446 return;

1448 if (I == E) {

1450 return;

1451 }

1454}

#define offsetof(TYPE, MEMBER)

Provides ErrorOr smart pointer.

static void appendGlobalSymbolTableInfo(SmallVector< GlobalSymtabInfo > &SymtabInfos, const char *GlobalSymtabLoc, uint64_t Size)

static Error getGlobalSymtabLocAndSize(const MemoryBufferRef &Data, uint64_t GlobalSymtabOffset, const char *&GlobalSymtabLoc, uint64_t &Size, const char *BitMessage)

static Error malformedError(Twine Msg)

StringRef getFieldRawString(const T(&Field)[N])

Expected< uint64_t > getArchiveMemberOctField(Twine FieldName, const StringRef RawField, const Archive *Parent, const AbstractArchiveMemberHeader *MemHeader)

Expected< uint64_t > getArchiveMemberDecField(Twine FieldName, const StringRef RawField, const Archive *Parent, const AbstractArchiveMemberHeader *MemHeader)

static Error createMemberHeaderParseError(const AbstractArchiveMemberHeader *ArMemHeader, const char *RawHeaderPtr, uint64_t Size)

static StringRef getName(Value *V)

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

This file defines the SmallString class.

static unsigned getSize(unsigned Kind)

Helper for Errors used as out-parameters.

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

const char * getBufferStart() const

StringRef getBuffer() const

const char * getBufferEnd() 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,...

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

void push_back(const T &Elt)

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

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.

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

StringRef slice(size_t Start, size_t End) const

Return a reference to the substring from [Start, End).

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

StringRef rtrim(char Char) const

Return string with consecutive Char characters starting from the right removed.

size_t find(char C, size_t From=0) const

Search for the first character C in the string.

bool ends_with(StringRef Suffix) const

Check if this string ends with the given Suffix.

static constexpr size_t npos

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

Triple - Helper class for working with autoconf configuration names.

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

std::string str() const

Return the twine contents as a std::string.

static Twine utohexstr(const uint64_t &Val)

LLVM Value Representation.

A wrapper class for fallible iterators.

static fallible_iterator end(Underlying I)

Construct a fallible iterator that can be used as an end-of-range value.

static fallible_iterator itr(Underlying I, Error &Err)

Construct a fallible iterator that cannot be used as an end-of-range value.

Expected< StringRef > getBuffer() const

Expected< Child > getNext() const

Expected< std::string > getFullName() const

uint64_t getChildOffset() const

Expected< uint64_t > getRawSize() const

Expected< StringRef > getName() const

Expected< uint64_t > getSize() const

Expected< StringRef > getRawName() const

Expected< std::unique_ptr< Binary > > getAsBinary(LLVMContext *Context=nullptr) const

Expected< MemoryBufferRef > getMemoryBufferRef() const

Child(const Archive *Parent, const char *Start, Error *Err)

Expected< Child > getMember() const

StringRef getName() const

std::unique_ptr< AbstractArchiveMemberHeader > createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size, Error *Err) const

symbol_iterator symbol_begin() const

virtual uint64_t getFirstChildOffset() const

StringRef getStringTable() const

uint32_t getNumberOfSymbols() const

uint32_t getNumberOfECSymbols() const

void setFirstRegular(const Child &C)

uint64_t getArchiveMagicLen() const

StringRef getSymbolTable() const

symbol_iterator symbol_end() const

static object::Archive::Kind getDefaultKind()

virtual bool isEmpty() const

child_iterator child_end() const

bool hasSymbolTable() const

Archive(MemoryBufferRef Source, Error &Err)

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

Expected< iterator_range< symbol_iterator > > ec_symbols() const

Expected< std::optional< Child > > findSym(StringRef name) const

child_iterator child_begin(Error &Err, bool SkipInternal=true) const

static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)

bool Has32BitGlobalSymtab

std::string MergedGlobalSymtabBuf

bool Has64BitGlobalSymtab

const FixLenHdr * ArFixLenHdr

uint64_t FirstChildOffset

BigArchive(MemoryBufferRef Source, Error &Err)

StringRef getData() const

MemoryBufferRef getMemoryBufferRef() const

raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)

Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...

A raw_ostream that writes to an std::string.

@ C

The default llvm calling convention, compatible with C.

constexpr size_t NameSize

const char ArchiveMagic[]

const char ThinArchiveMagic[]

const char BigArchiveMagic[]

Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)

Create a Binary from Source, autodetecting the file type.

uint64_t read64le(const void *P)

uint16_t read16le(const void *P)

uint64_t read64be(const void *P)

uint32_t read32be(const void *P)

uint32_t read32le(const void *P)

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

Get parent path.

bool is_absolute(const Twine &path, Style style=Style::native)

Is path absolute?

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

Append to path.

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

Convert a std::time_t to a TimePoint.

std::string getDefaultTargetTriple()

getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...

This is an optimization pass for GlobalISel generic memory operations.

Error createFileError(const Twine &F, Error E)

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

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

Error errorCodeToError(std::error_code EC)

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

void consumeError(Error Err)

Consume a Error without doing anything.

StringRef SymbolOffsetTable

char FirstChildOffset[20]

Offset to first archive member.

char LastChildOffset[20]

Offset to last archive member.

char GlobSym64Offset[20]

Offset global symbol table for 64-bit objects.

char GlobSymOffset[20]

Offset to global symbol table.

char Size[10]

Size of data, not including header or padding.