Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Object/Archive.cpp
35232 views
1
//===- Archive.cpp - ar File Format implementation ------------------------===//
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
//===----------------------------------------------------------------------===//
8
//
9
// This file defines the ArchiveObjectFile class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/Object/Archive.h"
14
#include "llvm/ADT/SmallString.h"
15
#include "llvm/ADT/StringRef.h"
16
#include "llvm/ADT/Twine.h"
17
#include "llvm/Object/Binary.h"
18
#include "llvm/Object/Error.h"
19
#include "llvm/Support/Chrono.h"
20
#include "llvm/Support/Endian.h"
21
#include "llvm/Support/EndianStream.h"
22
#include "llvm/Support/Error.h"
23
#include "llvm/Support/ErrorOr.h"
24
#include "llvm/Support/FileSystem.h"
25
#include "llvm/Support/MathExtras.h"
26
#include "llvm/Support/MemoryBuffer.h"
27
#include "llvm/Support/Path.h"
28
#include "llvm/Support/raw_ostream.h"
29
#include "llvm/TargetParser/Host.h"
30
#include <algorithm>
31
#include <cassert>
32
#include <cstddef>
33
#include <cstdint>
34
#include <memory>
35
#include <string>
36
#include <system_error>
37
38
using namespace llvm;
39
using namespace object;
40
using namespace llvm::support::endian;
41
42
void Archive::anchor() {}
43
44
static Error malformedError(Twine Msg) {
45
std::string StringMsg = "truncated or malformed archive (" + Msg.str() + ")";
46
return make_error<GenericBinaryError>(std::move(StringMsg),
47
object_error::parse_failed);
48
}
49
50
static Error
51
createMemberHeaderParseError(const AbstractArchiveMemberHeader *ArMemHeader,
52
const char *RawHeaderPtr, uint64_t Size) {
53
StringRef Msg("remaining size of archive too small for next archive "
54
"member header ");
55
56
Expected<StringRef> NameOrErr = ArMemHeader->getName(Size);
57
if (NameOrErr)
58
return malformedError(Msg + "for " + *NameOrErr);
59
60
consumeError(NameOrErr.takeError());
61
uint64_t Offset = RawHeaderPtr - ArMemHeader->Parent->getData().data();
62
return malformedError(Msg + "at offset " + Twine(Offset));
63
}
64
65
template <class T, std::size_t N>
66
StringRef getFieldRawString(const T (&Field)[N]) {
67
return StringRef(Field, N).rtrim(" ");
68
}
69
70
template <class T>
71
StringRef CommonArchiveMemberHeader<T>::getRawAccessMode() const {
72
return getFieldRawString(ArMemHdr->AccessMode);
73
}
74
75
template <class T>
76
StringRef CommonArchiveMemberHeader<T>::getRawLastModified() const {
77
return getFieldRawString(ArMemHdr->LastModified);
78
}
79
80
template <class T> StringRef CommonArchiveMemberHeader<T>::getRawUID() const {
81
return getFieldRawString(ArMemHdr->UID);
82
}
83
84
template <class T> StringRef CommonArchiveMemberHeader<T>::getRawGID() const {
85
return getFieldRawString(ArMemHdr->GID);
86
}
87
88
template <class T> uint64_t CommonArchiveMemberHeader<T>::getOffset() const {
89
return reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
90
}
91
92
template class object::CommonArchiveMemberHeader<UnixArMemHdrType>;
93
template class object::CommonArchiveMemberHeader<BigArMemHdrType>;
94
95
ArchiveMemberHeader::ArchiveMemberHeader(const Archive *Parent,
96
const char *RawHeaderPtr,
97
uint64_t Size, Error *Err)
98
: CommonArchiveMemberHeader<UnixArMemHdrType>(
99
Parent, reinterpret_cast<const UnixArMemHdrType *>(RawHeaderPtr)) {
100
if (RawHeaderPtr == nullptr)
101
return;
102
ErrorAsOutParameter ErrAsOutParam(Err);
103
104
if (Size < getSizeOf()) {
105
*Err = createMemberHeaderParseError(this, RawHeaderPtr, Size);
106
return;
107
}
108
if (ArMemHdr->Terminator[0] != '`' || ArMemHdr->Terminator[1] != '\n') {
109
if (Err) {
110
std::string Buf;
111
raw_string_ostream OS(Buf);
112
OS.write_escaped(
113
StringRef(ArMemHdr->Terminator, sizeof(ArMemHdr->Terminator)));
114
OS.flush();
115
std::string Msg("terminator characters in archive member \"" + Buf +
116
"\" not the correct \"`\\n\" values for the archive "
117
"member header ");
118
Expected<StringRef> NameOrErr = getName(Size);
119
if (!NameOrErr) {
120
consumeError(NameOrErr.takeError());
121
uint64_t Offset = RawHeaderPtr - Parent->getData().data();
122
*Err = malformedError(Msg + "at offset " + Twine(Offset));
123
} else
124
*Err = malformedError(Msg + "for " + NameOrErr.get());
125
}
126
return;
127
}
128
}
129
130
BigArchiveMemberHeader::BigArchiveMemberHeader(const Archive *Parent,
131
const char *RawHeaderPtr,
132
uint64_t Size, Error *Err)
133
: CommonArchiveMemberHeader<BigArMemHdrType>(
134
Parent, reinterpret_cast<const BigArMemHdrType *>(RawHeaderPtr)) {
135
if (RawHeaderPtr == nullptr)
136
return;
137
ErrorAsOutParameter ErrAsOutParam(Err);
138
139
if (RawHeaderPtr + getSizeOf() >= Parent->getData().end()) {
140
if (Err)
141
*Err = malformedError("malformed AIX big archive: remaining buffer is "
142
"unable to contain next archive member");
143
return;
144
}
145
146
if (Size < getSizeOf()) {
147
Error SubErr = createMemberHeaderParseError(this, RawHeaderPtr, Size);
148
if (Err)
149
*Err = std::move(SubErr);
150
}
151
}
152
153
// This gets the raw name from the ArMemHdr->Name field and checks that it is
154
// valid for the kind of archive. If it is not valid it returns an Error.
155
Expected<StringRef> ArchiveMemberHeader::getRawName() const {
156
char EndCond;
157
auto Kind = Parent->kind();
158
if (Kind == Archive::K_BSD || Kind == Archive::K_DARWIN64) {
159
if (ArMemHdr->Name[0] == ' ') {
160
uint64_t Offset =
161
reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
162
return malformedError("name contains a leading space for archive member "
163
"header at offset " +
164
Twine(Offset));
165
}
166
EndCond = ' ';
167
} else if (ArMemHdr->Name[0] == '/' || ArMemHdr->Name[0] == '#')
168
EndCond = ' ';
169
else
170
EndCond = '/';
171
StringRef::size_type end =
172
StringRef(ArMemHdr->Name, sizeof(ArMemHdr->Name)).find(EndCond);
173
if (end == StringRef::npos)
174
end = sizeof(ArMemHdr->Name);
175
assert(end <= sizeof(ArMemHdr->Name) && end > 0);
176
// Don't include the EndCond if there is one.
177
return StringRef(ArMemHdr->Name, end);
178
}
179
180
Expected<uint64_t>
181
getArchiveMemberDecField(Twine FieldName, const StringRef RawField,
182
const Archive *Parent,
183
const AbstractArchiveMemberHeader *MemHeader) {
184
uint64_t Value;
185
if (RawField.getAsInteger(10, Value)) {
186
uint64_t Offset = MemHeader->getOffset();
187
return malformedError("characters in " + FieldName +
188
" field in archive member header are not "
189
"all decimal numbers: '" +
190
RawField +
191
"' for the archive "
192
"member header at offset " +
193
Twine(Offset));
194
}
195
return Value;
196
}
197
198
Expected<uint64_t>
199
getArchiveMemberOctField(Twine FieldName, const StringRef RawField,
200
const Archive *Parent,
201
const AbstractArchiveMemberHeader *MemHeader) {
202
uint64_t Value;
203
if (RawField.getAsInteger(8, Value)) {
204
uint64_t Offset = MemHeader->getOffset();
205
return malformedError("characters in " + FieldName +
206
" field in archive member header are not "
207
"all octal numbers: '" +
208
RawField +
209
"' for the archive "
210
"member header at offset " +
211
Twine(Offset));
212
}
213
return Value;
214
}
215
216
Expected<StringRef> BigArchiveMemberHeader::getRawName() const {
217
Expected<uint64_t> NameLenOrErr = getArchiveMemberDecField(
218
"NameLen", getFieldRawString(ArMemHdr->NameLen), Parent, this);
219
if (!NameLenOrErr)
220
// TODO: Out-of-line.
221
return NameLenOrErr.takeError();
222
uint64_t NameLen = NameLenOrErr.get();
223
224
// If the name length is odd, pad with '\0' to get an even length. After
225
// padding, there is the name terminator "`\n".
226
uint64_t NameLenWithPadding = alignTo(NameLen, 2);
227
StringRef NameTerminator = "`\n";
228
StringRef NameStringWithNameTerminator =
229
StringRef(ArMemHdr->Name, NameLenWithPadding + NameTerminator.size());
230
if (!NameStringWithNameTerminator.ends_with(NameTerminator)) {
231
uint64_t Offset =
232
reinterpret_cast<const char *>(ArMemHdr->Name + NameLenWithPadding) -
233
Parent->getData().data();
234
// TODO: Out-of-line.
235
return malformedError(
236
"name does not have name terminator \"`\\n\" for archive member"
237
"header at offset " +
238
Twine(Offset));
239
}
240
return StringRef(ArMemHdr->Name, NameLen);
241
}
242
243
// member including the header, so the size of any name following the header
244
// is checked to make sure it does not overflow.
245
Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const {
246
247
// This can be called from the ArchiveMemberHeader constructor when the
248
// archive header is truncated to produce an error message with the name.
249
// Make sure the name field is not truncated.
250
if (Size < offsetof(UnixArMemHdrType, Name) + sizeof(ArMemHdr->Name)) {
251
uint64_t ArchiveOffset =
252
reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
253
return malformedError("archive header truncated before the name field "
254
"for archive member header at offset " +
255
Twine(ArchiveOffset));
256
}
257
258
// The raw name itself can be invalid.
259
Expected<StringRef> NameOrErr = getRawName();
260
if (!NameOrErr)
261
return NameOrErr.takeError();
262
StringRef Name = NameOrErr.get();
263
264
// Check if it's a special name.
265
if (Name[0] == '/') {
266
if (Name.size() == 1) // Linker member.
267
return Name;
268
if (Name.size() == 2 && Name[1] == '/') // String table.
269
return Name;
270
// System libraries from the Windows SDK for Windows 11 contain this symbol.
271
// It looks like a CFG guard: we just skip it for now.
272
if (Name == "/<XFGHASHMAP>/")
273
return Name;
274
// Some libraries (e.g., arm64rt.lib) from the Windows WDK
275
// (version 10.0.22000.0) contain this undocumented special member.
276
if (Name == "/<ECSYMBOLS>/")
277
return Name;
278
// It's a long name.
279
// Get the string table offset.
280
std::size_t StringOffset;
281
if (Name.substr(1).rtrim(' ').getAsInteger(10, StringOffset)) {
282
std::string Buf;
283
raw_string_ostream OS(Buf);
284
OS.write_escaped(Name.substr(1).rtrim(' '));
285
OS.flush();
286
uint64_t ArchiveOffset =
287
reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
288
return malformedError("long name offset characters after the '/' are "
289
"not all decimal numbers: '" +
290
Buf + "' for archive member header at offset " +
291
Twine(ArchiveOffset));
292
}
293
294
// Verify it.
295
if (StringOffset >= Parent->getStringTable().size()) {
296
uint64_t ArchiveOffset =
297
reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
298
return malformedError("long name offset " + Twine(StringOffset) +
299
" past the end of the string table for archive "
300
"member header at offset " +
301
Twine(ArchiveOffset));
302
}
303
304
// GNU long file names end with a "/\n".
305
if (Parent->kind() == Archive::K_GNU ||
306
Parent->kind() == Archive::K_GNU64) {
307
size_t End = Parent->getStringTable().find('\n', /*From=*/StringOffset);
308
if (End == StringRef::npos || End < 1 ||
309
Parent->getStringTable()[End - 1] != '/') {
310
return malformedError("string table at long name offset " +
311
Twine(StringOffset) + "not terminated");
312
}
313
return Parent->getStringTable().slice(StringOffset, End - 1);
314
}
315
return Parent->getStringTable().begin() + StringOffset;
316
}
317
318
if (Name.starts_with("#1/")) {
319
uint64_t NameLength;
320
if (Name.substr(3).rtrim(' ').getAsInteger(10, NameLength)) {
321
std::string Buf;
322
raw_string_ostream OS(Buf);
323
OS.write_escaped(Name.substr(3).rtrim(' '));
324
OS.flush();
325
uint64_t ArchiveOffset =
326
reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
327
return malformedError("long name length characters after the #1/ are "
328
"not all decimal numbers: '" +
329
Buf + "' for archive member header at offset " +
330
Twine(ArchiveOffset));
331
}
332
if (getSizeOf() + NameLength > Size) {
333
uint64_t ArchiveOffset =
334
reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
335
return malformedError("long name length: " + Twine(NameLength) +
336
" extends past the end of the member or archive "
337
"for archive member header at offset " +
338
Twine(ArchiveOffset));
339
}
340
return StringRef(reinterpret_cast<const char *>(ArMemHdr) + getSizeOf(),
341
NameLength)
342
.rtrim('\0');
343
}
344
345
// It is not a long name so trim the blanks at the end of the name.
346
if (Name[Name.size() - 1] != '/')
347
return Name.rtrim(' ');
348
349
// It's a simple name.
350
return Name.drop_back(1);
351
}
352
353
Expected<StringRef> BigArchiveMemberHeader::getName(uint64_t Size) const {
354
return getRawName();
355
}
356
357
Expected<uint64_t> ArchiveMemberHeader::getSize() const {
358
return getArchiveMemberDecField("size", getFieldRawString(ArMemHdr->Size),
359
Parent, this);
360
}
361
362
Expected<uint64_t> BigArchiveMemberHeader::getSize() const {
363
Expected<uint64_t> SizeOrErr = getArchiveMemberDecField(
364
"size", getFieldRawString(ArMemHdr->Size), Parent, this);
365
if (!SizeOrErr)
366
return SizeOrErr.takeError();
367
368
Expected<uint64_t> NameLenOrErr = getRawNameSize();
369
if (!NameLenOrErr)
370
return NameLenOrErr.takeError();
371
372
return *SizeOrErr + alignTo(*NameLenOrErr, 2);
373
}
374
375
Expected<uint64_t> BigArchiveMemberHeader::getRawNameSize() const {
376
return getArchiveMemberDecField(
377
"NameLen", getFieldRawString(ArMemHdr->NameLen), Parent, this);
378
}
379
380
Expected<uint64_t> BigArchiveMemberHeader::getNextOffset() const {
381
return getArchiveMemberDecField(
382
"NextOffset", getFieldRawString(ArMemHdr->NextOffset), Parent, this);
383
}
384
385
Expected<sys::fs::perms> AbstractArchiveMemberHeader::getAccessMode() const {
386
Expected<uint64_t> AccessModeOrErr =
387
getArchiveMemberOctField("AccessMode", getRawAccessMode(), Parent, this);
388
if (!AccessModeOrErr)
389
return AccessModeOrErr.takeError();
390
return static_cast<sys::fs::perms>(*AccessModeOrErr);
391
}
392
393
Expected<sys::TimePoint<std::chrono::seconds>>
394
AbstractArchiveMemberHeader::getLastModified() const {
395
Expected<uint64_t> SecondsOrErr = getArchiveMemberDecField(
396
"LastModified", getRawLastModified(), Parent, this);
397
398
if (!SecondsOrErr)
399
return SecondsOrErr.takeError();
400
401
return sys::toTimePoint(*SecondsOrErr);
402
}
403
404
Expected<unsigned> AbstractArchiveMemberHeader::getUID() const {
405
StringRef User = getRawUID();
406
if (User.empty())
407
return 0;
408
return getArchiveMemberDecField("UID", User, Parent, this);
409
}
410
411
Expected<unsigned> AbstractArchiveMemberHeader::getGID() const {
412
StringRef Group = getRawGID();
413
if (Group.empty())
414
return 0;
415
return getArchiveMemberDecField("GID", Group, Parent, this);
416
}
417
418
Expected<bool> ArchiveMemberHeader::isThin() const {
419
Expected<StringRef> NameOrErr = getRawName();
420
if (!NameOrErr)
421
return NameOrErr.takeError();
422
StringRef Name = NameOrErr.get();
423
return Parent->isThin() && Name != "/" && Name != "//" && Name != "/SYM64/";
424
}
425
426
Expected<const char *> ArchiveMemberHeader::getNextChildLoc() const {
427
uint64_t Size = getSizeOf();
428
Expected<bool> isThinOrErr = isThin();
429
if (!isThinOrErr)
430
return isThinOrErr.takeError();
431
432
bool isThin = isThinOrErr.get();
433
if (!isThin) {
434
Expected<uint64_t> MemberSize = getSize();
435
if (!MemberSize)
436
return MemberSize.takeError();
437
438
Size += MemberSize.get();
439
}
440
441
// If Size is odd, add 1 to make it even.
442
const char *NextLoc =
443
reinterpret_cast<const char *>(ArMemHdr) + alignTo(Size, 2);
444
445
if (NextLoc == Parent->getMemoryBufferRef().getBufferEnd())
446
return nullptr;
447
448
return NextLoc;
449
}
450
451
Expected<const char *> BigArchiveMemberHeader::getNextChildLoc() const {
452
if (getOffset() ==
453
static_cast<const BigArchive *>(Parent)->getLastChildOffset())
454
return nullptr;
455
456
Expected<uint64_t> NextOffsetOrErr = getNextOffset();
457
if (!NextOffsetOrErr)
458
return NextOffsetOrErr.takeError();
459
return Parent->getData().data() + NextOffsetOrErr.get();
460
}
461
462
Archive::Child::Child(const Archive *Parent, StringRef Data,
463
uint16_t StartOfFile)
464
: Parent(Parent), Data(Data), StartOfFile(StartOfFile) {
465
Header = Parent->createArchiveMemberHeader(Data.data(), Data.size(), nullptr);
466
}
467
468
Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
469
: Parent(Parent) {
470
if (!Start) {
471
Header = nullptr;
472
StartOfFile = -1;
473
return;
474
}
475
476
Header = Parent->createArchiveMemberHeader(
477
Start,
478
Parent ? Parent->getData().size() - (Start - Parent->getData().data())
479
: 0,
480
Err);
481
482
// If we are pointed to real data, Start is not a nullptr, then there must be
483
// a non-null Err pointer available to report malformed data on. Only in
484
// the case sentinel value is being constructed is Err is permitted to be a
485
// nullptr.
486
assert(Err && "Err can't be nullptr if Start is not a nullptr");
487
488
ErrorAsOutParameter ErrAsOutParam(Err);
489
490
// If there was an error in the construction of the Header
491
// then just return with the error now set.
492
if (*Err)
493
return;
494
495
uint64_t Size = Header->getSizeOf();
496
Data = StringRef(Start, Size);
497
Expected<bool> isThinOrErr = isThinMember();
498
if (!isThinOrErr) {
499
*Err = isThinOrErr.takeError();
500
return;
501
}
502
bool isThin = isThinOrErr.get();
503
if (!isThin) {
504
Expected<uint64_t> MemberSize = getRawSize();
505
if (!MemberSize) {
506
*Err = MemberSize.takeError();
507
return;
508
}
509
Size += MemberSize.get();
510
Data = StringRef(Start, Size);
511
}
512
513
// Setup StartOfFile and PaddingBytes.
514
StartOfFile = Header->getSizeOf();
515
// Don't include attached name.
516
Expected<StringRef> NameOrErr = getRawName();
517
if (!NameOrErr) {
518
*Err = NameOrErr.takeError();
519
return;
520
}
521
StringRef Name = NameOrErr.get();
522
523
if (Parent->kind() == Archive::K_AIXBIG) {
524
// The actual start of the file is after the name and any necessary
525
// even-alignment padding.
526
StartOfFile += ((Name.size() + 1) >> 1) << 1;
527
} else if (Name.starts_with("#1/")) {
528
uint64_t NameSize;
529
StringRef RawNameSize = Name.substr(3).rtrim(' ');
530
if (RawNameSize.getAsInteger(10, NameSize)) {
531
uint64_t Offset = Start - Parent->getData().data();
532
*Err = malformedError("long name length characters after the #1/ are "
533
"not all decimal numbers: '" +
534
RawNameSize +
535
"' for archive member header at offset " +
536
Twine(Offset));
537
return;
538
}
539
StartOfFile += NameSize;
540
}
541
}
542
543
Expected<uint64_t> Archive::Child::getSize() const {
544
if (Parent->IsThin)
545
return Header->getSize();
546
return Data.size() - StartOfFile;
547
}
548
549
Expected<uint64_t> Archive::Child::getRawSize() const {
550
return Header->getSize();
551
}
552
553
Expected<bool> Archive::Child::isThinMember() const { return Header->isThin(); }
554
555
Expected<std::string> Archive::Child::getFullName() const {
556
Expected<bool> isThin = isThinMember();
557
if (!isThin)
558
return isThin.takeError();
559
assert(isThin.get());
560
Expected<StringRef> NameOrErr = getName();
561
if (!NameOrErr)
562
return NameOrErr.takeError();
563
StringRef Name = *NameOrErr;
564
if (sys::path::is_absolute(Name))
565
return std::string(Name);
566
567
SmallString<128> FullName = sys::path::parent_path(
568
Parent->getMemoryBufferRef().getBufferIdentifier());
569
sys::path::append(FullName, Name);
570
return std::string(FullName);
571
}
572
573
Expected<StringRef> Archive::Child::getBuffer() const {
574
Expected<bool> isThinOrErr = isThinMember();
575
if (!isThinOrErr)
576
return isThinOrErr.takeError();
577
bool isThin = isThinOrErr.get();
578
if (!isThin) {
579
Expected<uint64_t> Size = getSize();
580
if (!Size)
581
return Size.takeError();
582
return StringRef(Data.data() + StartOfFile, Size.get());
583
}
584
Expected<std::string> FullNameOrErr = getFullName();
585
if (!FullNameOrErr)
586
return FullNameOrErr.takeError();
587
const std::string &FullName = *FullNameOrErr;
588
ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(FullName);
589
if (std::error_code EC = Buf.getError())
590
return errorCodeToError(EC);
591
Parent->ThinBuffers.push_back(std::move(*Buf));
592
return Parent->ThinBuffers.back()->getBuffer();
593
}
594
595
Expected<Archive::Child> Archive::Child::getNext() const {
596
Expected<const char *> NextLocOrErr = Header->getNextChildLoc();
597
if (!NextLocOrErr)
598
return NextLocOrErr.takeError();
599
600
const char *NextLoc = *NextLocOrErr;
601
602
// Check to see if this is at the end of the archive.
603
if (NextLoc == nullptr)
604
return Child(nullptr, nullptr, nullptr);
605
606
// Check to see if this is past the end of the archive.
607
if (NextLoc > Parent->Data.getBufferEnd()) {
608
std::string Msg("offset to next archive member past the end of the archive "
609
"after member ");
610
Expected<StringRef> NameOrErr = getName();
611
if (!NameOrErr) {
612
consumeError(NameOrErr.takeError());
613
uint64_t Offset = Data.data() - Parent->getData().data();
614
return malformedError(Msg + "at offset " + Twine(Offset));
615
} else
616
return malformedError(Msg + NameOrErr.get());
617
}
618
619
Error Err = Error::success();
620
Child Ret(Parent, NextLoc, &Err);
621
if (Err)
622
return std::move(Err);
623
return Ret;
624
}
625
626
uint64_t Archive::Child::getChildOffset() const {
627
const char *a = Parent->Data.getBuffer().data();
628
const char *c = Data.data();
629
uint64_t offset = c - a;
630
return offset;
631
}
632
633
Expected<StringRef> Archive::Child::getName() const {
634
Expected<uint64_t> RawSizeOrErr = getRawSize();
635
if (!RawSizeOrErr)
636
return RawSizeOrErr.takeError();
637
uint64_t RawSize = RawSizeOrErr.get();
638
Expected<StringRef> NameOrErr =
639
Header->getName(Header->getSizeOf() + RawSize);
640
if (!NameOrErr)
641
return NameOrErr.takeError();
642
StringRef Name = NameOrErr.get();
643
return Name;
644
}
645
646
Expected<MemoryBufferRef> Archive::Child::getMemoryBufferRef() const {
647
Expected<StringRef> NameOrErr = getName();
648
if (!NameOrErr)
649
return NameOrErr.takeError();
650
StringRef Name = NameOrErr.get();
651
Expected<StringRef> Buf = getBuffer();
652
if (!Buf)
653
return createFileError(Name, Buf.takeError());
654
return MemoryBufferRef(*Buf, Name);
655
}
656
657
Expected<std::unique_ptr<Binary>>
658
Archive::Child::getAsBinary(LLVMContext *Context) const {
659
Expected<MemoryBufferRef> BuffOrErr = getMemoryBufferRef();
660
if (!BuffOrErr)
661
return BuffOrErr.takeError();
662
663
auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);
664
if (BinaryOrErr)
665
return std::move(*BinaryOrErr);
666
return BinaryOrErr.takeError();
667
}
668
669
Expected<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) {
670
Error Err = Error::success();
671
std::unique_ptr<Archive> Ret;
672
StringRef Buffer = Source.getBuffer();
673
674
if (Buffer.starts_with(BigArchiveMagic))
675
Ret = std::make_unique<BigArchive>(Source, Err);
676
else
677
Ret = std::make_unique<Archive>(Source, Err);
678
679
if (Err)
680
return std::move(Err);
681
return std::move(Ret);
682
}
683
684
std::unique_ptr<AbstractArchiveMemberHeader>
685
Archive::createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size,
686
Error *Err) const {
687
ErrorAsOutParameter ErrAsOutParam(Err);
688
if (kind() != K_AIXBIG)
689
return std::make_unique<ArchiveMemberHeader>(this, RawHeaderPtr, Size, Err);
690
return std::make_unique<BigArchiveMemberHeader>(this, RawHeaderPtr, Size,
691
Err);
692
}
693
694
uint64_t Archive::getArchiveMagicLen() const {
695
if (isThin())
696
return sizeof(ThinArchiveMagic) - 1;
697
698
if (Kind() == K_AIXBIG)
699
return sizeof(BigArchiveMagic) - 1;
700
701
return sizeof(ArchiveMagic) - 1;
702
}
703
704
void Archive::setFirstRegular(const Child &C) {
705
FirstRegularData = C.Data;
706
FirstRegularStartOfFile = C.StartOfFile;
707
}
708
709
Archive::Archive(MemoryBufferRef Source, Error &Err)
710
: Binary(Binary::ID_Archive, Source) {
711
ErrorAsOutParameter ErrAsOutParam(&Err);
712
StringRef Buffer = Data.getBuffer();
713
// Check for sufficient magic.
714
if (Buffer.starts_with(ThinArchiveMagic)) {
715
IsThin = true;
716
} else if (Buffer.starts_with(ArchiveMagic)) {
717
IsThin = false;
718
} else if (Buffer.starts_with(BigArchiveMagic)) {
719
Format = K_AIXBIG;
720
IsThin = false;
721
return;
722
} else {
723
Err = make_error<GenericBinaryError>("file too small to be an archive",
724
object_error::invalid_file_type);
725
return;
726
}
727
728
// Make sure Format is initialized before any call to
729
// ArchiveMemberHeader::getName() is made. This could be a valid empty
730
// archive which is the same in all formats. So claiming it to be gnu to is
731
// fine if not totally correct before we look for a string table or table of
732
// contents.
733
Format = K_GNU;
734
735
// Get the special members.
736
child_iterator I = child_begin(Err, false);
737
if (Err)
738
return;
739
child_iterator E = child_end();
740
741
// See if this is a valid empty archive and if so return.
742
if (I == E) {
743
Err = Error::success();
744
return;
745
}
746
const Child *C = &*I;
747
748
auto Increment = [&]() {
749
++I;
750
if (Err)
751
return true;
752
C = &*I;
753
return false;
754
};
755
756
Expected<StringRef> NameOrErr = C->getRawName();
757
if (!NameOrErr) {
758
Err = NameOrErr.takeError();
759
return;
760
}
761
StringRef Name = NameOrErr.get();
762
763
// Below is the pattern that is used to figure out the archive format
764
// GNU archive format
765
// First member : / (may exist, if it exists, points to the symbol table )
766
// Second member : // (may exist, if it exists, points to the string table)
767
// Note : The string table is used if the filename exceeds 15 characters
768
// BSD archive format
769
// First member : __.SYMDEF or "__.SYMDEF SORTED" (the symbol table)
770
// There is no string table, if the filename exceeds 15 characters or has a
771
// embedded space, the filename has #1/<size>, The size represents the size
772
// of the filename that needs to be read after the archive header
773
// COFF archive format
774
// First member : /
775
// Second member : / (provides a directory of symbols)
776
// Third member : // (may exist, if it exists, contains the string table)
777
// Note: Microsoft PE/COFF Spec 8.3 says that the third member is present
778
// even if the string table is empty. However, lib.exe does not in fact
779
// seem to create the third member if there's no member whose filename
780
// exceeds 15 characters. So the third member is optional.
781
782
if (Name == "__.SYMDEF" || Name == "__.SYMDEF_64") {
783
if (Name == "__.SYMDEF")
784
Format = K_BSD;
785
else // Name == "__.SYMDEF_64"
786
Format = K_DARWIN64;
787
// We know that the symbol table is not an external file, but we still must
788
// check any Expected<> return value.
789
Expected<StringRef> BufOrErr = C->getBuffer();
790
if (!BufOrErr) {
791
Err = BufOrErr.takeError();
792
return;
793
}
794
SymbolTable = BufOrErr.get();
795
if (Increment())
796
return;
797
setFirstRegular(*C);
798
799
Err = Error::success();
800
return;
801
}
802
803
if (Name.starts_with("#1/")) {
804
Format = K_BSD;
805
// We know this is BSD, so getName will work since there is no string table.
806
Expected<StringRef> NameOrErr = C->getName();
807
if (!NameOrErr) {
808
Err = NameOrErr.takeError();
809
return;
810
}
811
Name = NameOrErr.get();
812
if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {
813
// We know that the symbol table is not an external file, but we still
814
// must check any Expected<> return value.
815
Expected<StringRef> BufOrErr = C->getBuffer();
816
if (!BufOrErr) {
817
Err = BufOrErr.takeError();
818
return;
819
}
820
SymbolTable = BufOrErr.get();
821
if (Increment())
822
return;
823
} else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {
824
Format = K_DARWIN64;
825
// We know that the symbol table is not an external file, but we still
826
// must check any Expected<> return value.
827
Expected<StringRef> BufOrErr = C->getBuffer();
828
if (!BufOrErr) {
829
Err = BufOrErr.takeError();
830
return;
831
}
832
SymbolTable = BufOrErr.get();
833
if (Increment())
834
return;
835
}
836
setFirstRegular(*C);
837
return;
838
}
839
840
// MIPS 64-bit ELF archives use a special format of a symbol table.
841
// This format is marked by `ar_name` field equals to "/SYM64/".
842
// For detailed description see page 96 in the following document:
843
// http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
844
845
bool has64SymTable = false;
846
if (Name == "/" || Name == "/SYM64/") {
847
// We know that the symbol table is not an external file, but we still
848
// must check any Expected<> return value.
849
Expected<StringRef> BufOrErr = C->getBuffer();
850
if (!BufOrErr) {
851
Err = BufOrErr.takeError();
852
return;
853
}
854
SymbolTable = BufOrErr.get();
855
if (Name == "/SYM64/")
856
has64SymTable = true;
857
858
if (Increment())
859
return;
860
if (I == E) {
861
Err = Error::success();
862
return;
863
}
864
Expected<StringRef> NameOrErr = C->getRawName();
865
if (!NameOrErr) {
866
Err = NameOrErr.takeError();
867
return;
868
}
869
Name = NameOrErr.get();
870
}
871
872
if (Name == "//") {
873
Format = has64SymTable ? K_GNU64 : K_GNU;
874
// The string table is never an external member, but we still
875
// must check any Expected<> return value.
876
Expected<StringRef> BufOrErr = C->getBuffer();
877
if (!BufOrErr) {
878
Err = BufOrErr.takeError();
879
return;
880
}
881
StringTable = BufOrErr.get();
882
if (Increment())
883
return;
884
setFirstRegular(*C);
885
Err = Error::success();
886
return;
887
}
888
889
if (Name[0] != '/') {
890
Format = has64SymTable ? K_GNU64 : K_GNU;
891
setFirstRegular(*C);
892
Err = Error::success();
893
return;
894
}
895
896
if (Name != "/") {
897
Err = errorCodeToError(object_error::parse_failed);
898
return;
899
}
900
901
Format = K_COFF;
902
// We know that the symbol table is not an external file, but we still
903
// must check any Expected<> return value.
904
Expected<StringRef> BufOrErr = C->getBuffer();
905
if (!BufOrErr) {
906
Err = BufOrErr.takeError();
907
return;
908
}
909
SymbolTable = BufOrErr.get();
910
911
if (Increment())
912
return;
913
914
if (I == E) {
915
setFirstRegular(*C);
916
Err = Error::success();
917
return;
918
}
919
920
NameOrErr = C->getRawName();
921
if (!NameOrErr) {
922
Err = NameOrErr.takeError();
923
return;
924
}
925
Name = NameOrErr.get();
926
927
if (Name == "//") {
928
// The string table is never an external member, but we still
929
// must check any Expected<> return value.
930
Expected<StringRef> BufOrErr = C->getBuffer();
931
if (!BufOrErr) {
932
Err = BufOrErr.takeError();
933
return;
934
}
935
StringTable = BufOrErr.get();
936
if (Increment())
937
return;
938
939
if (I == E) {
940
setFirstRegular(*C);
941
Err = Error::success();
942
return;
943
}
944
945
NameOrErr = C->getRawName();
946
if (!NameOrErr) {
947
Err = NameOrErr.takeError();
948
return;
949
}
950
Name = NameOrErr.get();
951
}
952
953
if (Name == "/<ECSYMBOLS>/") {
954
// ARM64EC-aware libraries contain an additional special member with
955
// an EC symbol map after the string table. Its format is similar to a
956
// regular symbol map, except it doesn't contain member offsets. Its indexes
957
// refer to member offsets from the regular symbol table instead.
958
Expected<StringRef> BufOrErr = C->getBuffer();
959
if (!BufOrErr) {
960
Err = BufOrErr.takeError();
961
return;
962
}
963
ECSymbolTable = BufOrErr.get();
964
if (Increment())
965
return;
966
}
967
968
setFirstRegular(*C);
969
Err = Error::success();
970
}
971
972
object::Archive::Kind Archive::getDefaultKindForTriple(Triple &T) {
973
if (T.isOSDarwin())
974
return object::Archive::K_DARWIN;
975
if (T.isOSAIX())
976
return object::Archive::K_AIXBIG;
977
if (T.isOSWindows())
978
return object::Archive::K_COFF;
979
return object::Archive::K_GNU;
980
}
981
982
object::Archive::Kind Archive::getDefaultKind() {
983
Triple HostTriple(sys::getDefaultTargetTriple());
984
return getDefaultKindForTriple(HostTriple);
985
}
986
987
Archive::child_iterator Archive::child_begin(Error &Err,
988
bool SkipInternal) const {
989
if (isEmpty())
990
return child_end();
991
992
if (SkipInternal)
993
return child_iterator::itr(
994
Child(this, FirstRegularData, FirstRegularStartOfFile), Err);
995
996
const char *Loc = Data.getBufferStart() + getFirstChildOffset();
997
Child C(this, Loc, &Err);
998
if (Err)
999
return child_end();
1000
return child_iterator::itr(C, Err);
1001
}
1002
1003
Archive::child_iterator Archive::child_end() const {
1004
return child_iterator::end(Child(nullptr, nullptr, nullptr));
1005
}
1006
1007
bool Archive::Symbol::isECSymbol() const {
1008
// Symbols use SymbolCount..SymbolCount+getNumberOfECSymbols() for EC symbol
1009
// indexes.
1010
uint32_t SymbolCount = Parent->getNumberOfSymbols();
1011
return SymbolCount <= SymbolIndex &&
1012
SymbolIndex < SymbolCount + Parent->getNumberOfECSymbols();
1013
}
1014
1015
StringRef Archive::Symbol::getName() const {
1016
if (isECSymbol())
1017
return Parent->ECSymbolTable.begin() + StringIndex;
1018
return Parent->getSymbolTable().begin() + StringIndex;
1019
}
1020
1021
Expected<Archive::Child> Archive::Symbol::getMember() const {
1022
const char *Buf = Parent->getSymbolTable().begin();
1023
const char *Offsets = Buf;
1024
if (Parent->kind() == K_GNU64 || Parent->kind() == K_DARWIN64 ||
1025
Parent->kind() == K_AIXBIG)
1026
Offsets += sizeof(uint64_t);
1027
else
1028
Offsets += sizeof(uint32_t);
1029
uint64_t Offset = 0;
1030
if (Parent->kind() == K_GNU) {
1031
Offset = read32be(Offsets + SymbolIndex * 4);
1032
} else if (Parent->kind() == K_GNU64 || Parent->kind() == K_AIXBIG) {
1033
Offset = read64be(Offsets + SymbolIndex * 8);
1034
} else if (Parent->kind() == K_BSD) {
1035
// The SymbolIndex is an index into the ranlib structs that start at
1036
// Offsets (the first uint32_t is the number of bytes of the ranlib
1037
// structs). The ranlib structs are a pair of uint32_t's the first
1038
// being a string table offset and the second being the offset into
1039
// the archive of the member that defines the symbol. Which is what
1040
// is needed here.
1041
Offset = read32le(Offsets + SymbolIndex * 8 + 4);
1042
} else if (Parent->kind() == K_DARWIN64) {
1043
// The SymbolIndex is an index into the ranlib_64 structs that start at
1044
// Offsets (the first uint64_t is the number of bytes of the ranlib_64
1045
// structs). The ranlib_64 structs are a pair of uint64_t's the first
1046
// being a string table offset and the second being the offset into
1047
// the archive of the member that defines the symbol. Which is what
1048
// is needed here.
1049
Offset = read64le(Offsets + SymbolIndex * 16 + 8);
1050
} else {
1051
// Skip offsets.
1052
uint32_t MemberCount = read32le(Buf);
1053
Buf += MemberCount * 4 + 4;
1054
1055
uint32_t SymbolCount = read32le(Buf);
1056
uint16_t OffsetIndex;
1057
if (SymbolIndex < SymbolCount) {
1058
// Skip SymbolCount to get to the indices table.
1059
const char *Indices = Buf + 4;
1060
1061
// Get the index of the offset in the file member offset table for this
1062
// symbol.
1063
OffsetIndex = read16le(Indices + SymbolIndex * 2);
1064
} else if (isECSymbol()) {
1065
// Skip SymbolCount to get to the indices table.
1066
const char *Indices = Parent->ECSymbolTable.begin() + 4;
1067
1068
// Get the index of the offset in the file member offset table for this
1069
// symbol.
1070
OffsetIndex = read16le(Indices + (SymbolIndex - SymbolCount) * 2);
1071
} else {
1072
return errorCodeToError(object_error::parse_failed);
1073
}
1074
// Subtract 1 since OffsetIndex is 1 based.
1075
--OffsetIndex;
1076
1077
if (OffsetIndex >= MemberCount)
1078
return errorCodeToError(object_error::parse_failed);
1079
1080
Offset = read32le(Offsets + OffsetIndex * 4);
1081
}
1082
1083
const char *Loc = Parent->getData().begin() + Offset;
1084
Error Err = Error::success();
1085
Child C(Parent, Loc, &Err);
1086
if (Err)
1087
return std::move(Err);
1088
return C;
1089
}
1090
1091
Archive::Symbol Archive::Symbol::getNext() const {
1092
Symbol t(*this);
1093
if (Parent->kind() == K_BSD) {
1094
// t.StringIndex is an offset from the start of the __.SYMDEF or
1095
// "__.SYMDEF SORTED" member into the string table for the ranlib
1096
// struct indexed by t.SymbolIndex . To change t.StringIndex to the
1097
// offset in the string table for t.SymbolIndex+1 we subtract the
1098
// its offset from the start of the string table for t.SymbolIndex
1099
// and add the offset of the string table for t.SymbolIndex+1.
1100
1101
// The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
1102
// which is the number of bytes of ranlib structs that follow. The ranlib
1103
// structs are a pair of uint32_t's the first being a string table offset
1104
// and the second being the offset into the archive of the member that
1105
// define the symbol. After that the next uint32_t is the byte count of
1106
// the string table followed by the string table.
1107
const char *Buf = Parent->getSymbolTable().begin();
1108
uint32_t RanlibCount = 0;
1109
RanlibCount = read32le(Buf) / 8;
1110
// If t.SymbolIndex + 1 will be past the count of symbols (the RanlibCount)
1111
// don't change the t.StringIndex as we don't want to reference a ranlib
1112
// past RanlibCount.
1113
if (t.SymbolIndex + 1 < RanlibCount) {
1114
const char *Ranlibs = Buf + 4;
1115
uint32_t CurRanStrx = 0;
1116
uint32_t NextRanStrx = 0;
1117
CurRanStrx = read32le(Ranlibs + t.SymbolIndex * 8);
1118
NextRanStrx = read32le(Ranlibs + (t.SymbolIndex + 1) * 8);
1119
t.StringIndex -= CurRanStrx;
1120
t.StringIndex += NextRanStrx;
1121
}
1122
} else if (t.isECSymbol()) {
1123
// Go to one past next null.
1124
t.StringIndex = Parent->ECSymbolTable.find('\0', t.StringIndex) + 1;
1125
} else {
1126
// Go to one past next null.
1127
t.StringIndex = Parent->getSymbolTable().find('\0', t.StringIndex) + 1;
1128
}
1129
++t.SymbolIndex;
1130
return t;
1131
}
1132
1133
Archive::symbol_iterator Archive::symbol_begin() const {
1134
if (!hasSymbolTable())
1135
return symbol_iterator(Symbol(this, 0, 0));
1136
1137
const char *buf = getSymbolTable().begin();
1138
if (kind() == K_GNU) {
1139
uint32_t symbol_count = 0;
1140
symbol_count = read32be(buf);
1141
buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
1142
} else if (kind() == K_GNU64) {
1143
uint64_t symbol_count = read64be(buf);
1144
buf += sizeof(uint64_t) + (symbol_count * (sizeof(uint64_t)));
1145
} else if (kind() == K_BSD) {
1146
// The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
1147
// which is the number of bytes of ranlib structs that follow. The ranlib
1148
// structs are a pair of uint32_t's the first being a string table offset
1149
// and the second being the offset into the archive of the member that
1150
// define the symbol. After that the next uint32_t is the byte count of
1151
// the string table followed by the string table.
1152
uint32_t ranlib_count = 0;
1153
ranlib_count = read32le(buf) / 8;
1154
const char *ranlibs = buf + 4;
1155
uint32_t ran_strx = 0;
1156
ran_strx = read32le(ranlibs);
1157
buf += sizeof(uint32_t) + (ranlib_count * (2 * (sizeof(uint32_t))));
1158
// Skip the byte count of the string table.
1159
buf += sizeof(uint32_t);
1160
buf += ran_strx;
1161
} else if (kind() == K_DARWIN64) {
1162
// The __.SYMDEF_64 or "__.SYMDEF_64 SORTED" member starts with a uint64_t
1163
// which is the number of bytes of ranlib_64 structs that follow. The
1164
// ranlib_64 structs are a pair of uint64_t's the first being a string
1165
// table offset and the second being the offset into the archive of the
1166
// member that define the symbol. After that the next uint64_t is the byte
1167
// count of the string table followed by the string table.
1168
uint64_t ranlib_count = 0;
1169
ranlib_count = read64le(buf) / 16;
1170
const char *ranlibs = buf + 8;
1171
uint64_t ran_strx = 0;
1172
ran_strx = read64le(ranlibs);
1173
buf += sizeof(uint64_t) + (ranlib_count * (2 * (sizeof(uint64_t))));
1174
// Skip the byte count of the string table.
1175
buf += sizeof(uint64_t);
1176
buf += ran_strx;
1177
} else if (kind() == K_AIXBIG) {
1178
buf = getStringTable().begin();
1179
} else {
1180
uint32_t member_count = 0;
1181
uint32_t symbol_count = 0;
1182
member_count = read32le(buf);
1183
buf += 4 + (member_count * 4); // Skip offsets.
1184
symbol_count = read32le(buf);
1185
buf += 4 + (symbol_count * 2); // Skip indices.
1186
}
1187
uint32_t string_start_offset = buf - getSymbolTable().begin();
1188
return symbol_iterator(Symbol(this, 0, string_start_offset));
1189
}
1190
1191
Archive::symbol_iterator Archive::symbol_end() const {
1192
return symbol_iterator(Symbol(this, getNumberOfSymbols(), 0));
1193
}
1194
1195
Expected<iterator_range<Archive::symbol_iterator>> Archive::ec_symbols() const {
1196
uint32_t Count = 0;
1197
1198
// Validate EC symbol table.
1199
if (!ECSymbolTable.empty()) {
1200
if (ECSymbolTable.size() < sizeof(uint32_t))
1201
return malformedError("invalid EC symbols size (" +
1202
Twine(ECSymbolTable.size()) + ")");
1203
if (SymbolTable.size() < sizeof(uint32_t))
1204
return malformedError("invalid symbols size (" +
1205
Twine(ECSymbolTable.size()) + ")");
1206
1207
Count = read32le(ECSymbolTable.begin());
1208
size_t StringIndex = sizeof(uint32_t) + Count * sizeof(uint16_t);
1209
if (ECSymbolTable.size() < StringIndex)
1210
return malformedError("invalid EC symbols size. Size was " +
1211
Twine(ECSymbolTable.size()) + ", but expected " +
1212
Twine(StringIndex));
1213
1214
uint32_t MemberCount = read32le(SymbolTable.begin());
1215
const char *Indexes = ECSymbolTable.begin() + sizeof(uint32_t);
1216
1217
for (uint32_t i = 0; i < Count; ++i) {
1218
uint16_t Index = read16le(Indexes + i * sizeof(uint16_t));
1219
if (!Index)
1220
return malformedError("invalid EC symbol index 0");
1221
if (Index > MemberCount)
1222
return malformedError("invalid EC symbol index " + Twine(Index) +
1223
" is larger than member count " +
1224
Twine(MemberCount));
1225
1226
StringIndex = ECSymbolTable.find('\0', StringIndex);
1227
if (StringIndex == StringRef::npos)
1228
return malformedError("malformed EC symbol names: not null-terminated");
1229
++StringIndex;
1230
}
1231
}
1232
1233
uint32_t SymbolCount = getNumberOfSymbols();
1234
return make_range(
1235
symbol_iterator(Symbol(this, SymbolCount,
1236
sizeof(uint32_t) + Count * sizeof(uint16_t))),
1237
symbol_iterator(Symbol(this, SymbolCount + Count, 0)));
1238
}
1239
1240
uint32_t Archive::getNumberOfSymbols() const {
1241
if (!hasSymbolTable())
1242
return 0;
1243
const char *buf = getSymbolTable().begin();
1244
if (kind() == K_GNU)
1245
return read32be(buf);
1246
if (kind() == K_GNU64 || kind() == K_AIXBIG)
1247
return read64be(buf);
1248
if (kind() == K_BSD)
1249
return read32le(buf) / 8;
1250
if (kind() == K_DARWIN64)
1251
return read64le(buf) / 16;
1252
uint32_t member_count = 0;
1253
member_count = read32le(buf);
1254
buf += 4 + (member_count * 4); // Skip offsets.
1255
return read32le(buf);
1256
}
1257
1258
uint32_t Archive::getNumberOfECSymbols() const {
1259
if (ECSymbolTable.size() < sizeof(uint32_t))
1260
return 0;
1261
return read32le(ECSymbolTable.begin());
1262
}
1263
1264
Expected<std::optional<Archive::Child>> Archive::findSym(StringRef name) const {
1265
Archive::symbol_iterator bs = symbol_begin();
1266
Archive::symbol_iterator es = symbol_end();
1267
1268
for (; bs != es; ++bs) {
1269
StringRef SymName = bs->getName();
1270
if (SymName == name) {
1271
if (auto MemberOrErr = bs->getMember())
1272
return Child(*MemberOrErr);
1273
else
1274
return MemberOrErr.takeError();
1275
}
1276
}
1277
return std::nullopt;
1278
}
1279
1280
// Returns true if archive file contains no member file.
1281
bool Archive::isEmpty() const {
1282
return Data.getBufferSize() == getArchiveMagicLen();
1283
}
1284
1285
bool Archive::hasSymbolTable() const { return !SymbolTable.empty(); }
1286
1287
static Error getGlobalSymtabLocAndSize(const MemoryBufferRef &Data,
1288
uint64_t GlobalSymtabOffset,
1289
const char *&GlobalSymtabLoc,
1290
uint64_t &Size, const char *BitMessage) {
1291
uint64_t BufferSize = Data.getBufferSize();
1292
uint64_t GlobalSymtabContentOffset =
1293
GlobalSymtabOffset + sizeof(BigArMemHdrType);
1294
if (GlobalSymtabContentOffset > BufferSize)
1295
return malformedError(
1296
Twine(BitMessage) + " global symbol table header at offset 0x" +
1297
Twine::utohexstr(GlobalSymtabOffset) + " and size 0x" +
1298
Twine::utohexstr(sizeof(BigArMemHdrType)) +
1299
" goes past the end of file");
1300
1301
GlobalSymtabLoc = Data.getBufferStart() + GlobalSymtabOffset;
1302
const BigArMemHdrType *GlobalSymHdr =
1303
reinterpret_cast<const BigArMemHdrType *>(GlobalSymtabLoc);
1304
StringRef RawOffset = getFieldRawString(GlobalSymHdr->Size);
1305
if (RawOffset.getAsInteger(10, Size))
1306
return malformedError(Twine(BitMessage) + " global symbol table size \"" +
1307
RawOffset + "\" is not a number");
1308
1309
if (GlobalSymtabContentOffset + Size > BufferSize)
1310
return malformedError(
1311
Twine(BitMessage) + " global symbol table content at offset 0x" +
1312
Twine::utohexstr(GlobalSymtabContentOffset) + " and size 0x" +
1313
Twine::utohexstr(Size) + " goes past the end of file");
1314
1315
return Error::success();
1316
}
1317
1318
struct GlobalSymtabInfo {
1319
uint64_t SymNum;
1320
StringRef SymbolTable;
1321
StringRef SymbolOffsetTable;
1322
StringRef StringTable;
1323
};
1324
1325
static void
1326
appendGlobalSymbolTableInfo(SmallVector<GlobalSymtabInfo> &SymtabInfos,
1327
const char *GlobalSymtabLoc, uint64_t Size) {
1328
// In a big archive, a global symbol table contains the following information:
1329
// - The number of symbols.
1330
// - The array of offsets into the archive file. The length is eight
1331
// times the number of symbols.
1332
// - The name-string table. The size is:
1333
// Size-(8*(the number of symbols + 1)).
1334
1335
StringRef SymbolTable =
1336
StringRef(GlobalSymtabLoc + sizeof(BigArMemHdrType), Size);
1337
uint64_t SymNum = read64be(GlobalSymtabLoc + sizeof(BigArMemHdrType));
1338
StringRef SymbolOffsetTable = StringRef(SymbolTable.data() + 8, 8 * SymNum);
1339
unsigned SymOffsetsSize = 8 * (SymNum + 1);
1340
uint64_t SymbolTableStringSize = Size - SymOffsetsSize;
1341
StringRef StringTable =
1342
StringRef(SymbolTable.data() + SymOffsetsSize, SymbolTableStringSize);
1343
SymtabInfos.push_back({SymNum, SymbolTable, SymbolOffsetTable, StringTable});
1344
}
1345
1346
BigArchive::BigArchive(MemoryBufferRef Source, Error &Err)
1347
: Archive(Source, Err) {
1348
ErrorAsOutParameter ErrAsOutParam(&Err);
1349
StringRef Buffer = Data.getBuffer();
1350
ArFixLenHdr = reinterpret_cast<const FixLenHdr *>(Buffer.data());
1351
uint64_t BufferSize = Data.getBufferSize();
1352
1353
if (BufferSize < sizeof(FixLenHdr)) {
1354
Err = malformedError("malformed AIX big archive: incomplete fixed length "
1355
"header, the archive is only" +
1356
Twine(BufferSize) + " byte(s)");
1357
return;
1358
}
1359
1360
StringRef RawOffset = getFieldRawString(ArFixLenHdr->FirstChildOffset);
1361
if (RawOffset.getAsInteger(10, FirstChildOffset))
1362
// TODO: Out-of-line.
1363
Err = malformedError("malformed AIX big archive: first member offset \"" +
1364
RawOffset + "\" is not a number");
1365
1366
RawOffset = getFieldRawString(ArFixLenHdr->LastChildOffset);
1367
if (RawOffset.getAsInteger(10, LastChildOffset))
1368
// TODO: Out-of-line.
1369
Err = malformedError("malformed AIX big archive: last member offset \"" +
1370
RawOffset + "\" is not a number");
1371
1372
uint64_t GlobSymtab32Offset = 0;
1373
RawOffset = getFieldRawString(ArFixLenHdr->GlobSymOffset);
1374
if (RawOffset.getAsInteger(10, GlobSymtab32Offset)) {
1375
Err = malformedError("global symbol table "
1376
"offset of 32-bit members \"" +
1377
RawOffset + "\" is not a number");
1378
return;
1379
}
1380
1381
uint64_t GlobSymtab64Offset = 0;
1382
RawOffset = getFieldRawString(ArFixLenHdr->GlobSym64Offset);
1383
if (RawOffset.getAsInteger(10, GlobSymtab64Offset)) {
1384
Err = malformedError("global symbol table "
1385
"offset of 64-bit members\"" +
1386
RawOffset + "\" is not a number");
1387
return;
1388
}
1389
1390
const char *GlobSymtab32Loc = nullptr;
1391
const char *GlobSymtab64Loc = nullptr;
1392
uint64_t GlobSymtab32Size = 0;
1393
uint64_t GlobSymtab64Size = 0;
1394
const MemoryBufferRef &MemBuffRef = getMemoryBufferRef();
1395
1396
if (GlobSymtab32Offset) {
1397
Err =
1398
getGlobalSymtabLocAndSize(MemBuffRef, GlobSymtab32Offset,
1399
GlobSymtab32Loc, GlobSymtab32Size, "32-bit");
1400
if (Err)
1401
return;
1402
1403
Has32BitGlobalSymtab = true;
1404
}
1405
1406
if (GlobSymtab64Offset) {
1407
Err =
1408
getGlobalSymtabLocAndSize(MemBuffRef, GlobSymtab64Offset,
1409
GlobSymtab64Loc, GlobSymtab64Size, "64-bit");
1410
if (Err)
1411
return;
1412
1413
Has64BitGlobalSymtab = true;
1414
}
1415
1416
SmallVector<GlobalSymtabInfo> SymtabInfos;
1417
1418
if (GlobSymtab32Offset)
1419
appendGlobalSymbolTableInfo(SymtabInfos, GlobSymtab32Loc, GlobSymtab32Size);
1420
if (GlobSymtab64Offset)
1421
appendGlobalSymbolTableInfo(SymtabInfos, GlobSymtab64Loc, GlobSymtab64Size);
1422
1423
if (SymtabInfos.size() == 1) {
1424
SymbolTable = SymtabInfos[0].SymbolTable;
1425
StringTable = SymtabInfos[0].StringTable;
1426
} else if (SymtabInfos.size() == 2) {
1427
// In order to let the Archive::Symbol::getNext() work for both 32-bit and
1428
// 64-bit global symbol tables, we need to merge them into a single table.
1429
raw_string_ostream Out(MergedGlobalSymtabBuf);
1430
uint64_t SymNum = SymtabInfos[0].SymNum + SymtabInfos[1].SymNum;
1431
write(Out, SymNum, llvm::endianness::big);
1432
// Merge symbol offset.
1433
Out << SymtabInfos[0].SymbolOffsetTable;
1434
Out << SymtabInfos[1].SymbolOffsetTable;
1435
// Merge string table.
1436
Out << SymtabInfos[0].StringTable;
1437
Out << SymtabInfos[1].StringTable;
1438
SymbolTable = MergedGlobalSymtabBuf;
1439
// The size of the symbol offset to the member file is 8 bytes.
1440
StringTable = StringRef(SymbolTable.begin() + (SymNum + 1) * 8,
1441
SymtabInfos[0].StringTable.size() +
1442
SymtabInfos[1].StringTable.size());
1443
}
1444
1445
child_iterator I = child_begin(Err, false);
1446
if (Err)
1447
return;
1448
child_iterator E = child_end();
1449
if (I == E) {
1450
Err = Error::success();
1451
return;
1452
}
1453
setFirstRegular(*I);
1454
Err = Error::success();
1455
}
1456
1457