1 //===- Archive.cpp - ar File Format implementation ------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the ArchiveObjectFile class.
11 //===----------------------------------------------------------------------===//
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"
36 #include <system_error>
39 using namespace object
;
40 using namespace llvm::support::endian
;
42 void Archive::anchor() {}
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
);
51 createMemberHeaderParseError(const AbstractArchiveMemberHeader
*ArMemHeader
,
52 const char *RawHeaderPtr
, uint64_t Size
) {
53 StringRef
Msg("remaining size of archive too small for next archive "
56 Expected
<StringRef
> NameOrErr
= ArMemHeader
->getName(Size
);
58 return malformedError(Msg
+ "for " + *NameOrErr
);
60 consumeError(NameOrErr
.takeError());
61 uint64_t Offset
= RawHeaderPtr
- ArMemHeader
->Parent
->getData().data();
62 return malformedError(Msg
+ "at offset " + Twine(Offset
));
65 template <class T
, std::size_t N
>
66 StringRef
getFieldRawString(const T (&Field
)[N
]) {
67 return StringRef(Field
, N
).rtrim(" ");
71 StringRef CommonArchiveMemberHeader
<T
>::getRawAccessMode() const {
72 return getFieldRawString(ArMemHdr
->AccessMode
);
76 StringRef CommonArchiveMemberHeader
<T
>::getRawLastModified() const {
77 return getFieldRawString(ArMemHdr
->LastModified
);
80 template <class T
> StringRef CommonArchiveMemberHeader
<T
>::getRawUID() const {
81 return getFieldRawString(ArMemHdr
->UID
);
84 template <class T
> StringRef CommonArchiveMemberHeader
<T
>::getRawGID() const {
85 return getFieldRawString(ArMemHdr
->GID
);
88 template <class T
> uint64_t CommonArchiveMemberHeader
<T
>::getOffset() const {
89 return reinterpret_cast<const char *>(ArMemHdr
) - Parent
->getData().data();
92 template class object::CommonArchiveMemberHeader
<UnixArMemHdrType
>;
93 template class object::CommonArchiveMemberHeader
<BigArMemHdrType
>;
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)
102 ErrorAsOutParameter
ErrAsOutParam(Err
);
104 if (Size
< getSizeOf()) {
105 *Err
= createMemberHeaderParseError(this, RawHeaderPtr
, Size
);
108 if (ArMemHdr
->Terminator
[0] != '`' || ArMemHdr
->Terminator
[1] != '\n') {
111 raw_string_ostream
OS(Buf
);
113 StringRef(ArMemHdr
->Terminator
, sizeof(ArMemHdr
->Terminator
)));
115 std::string
Msg("terminator characters in archive member \"" + Buf
+
116 "\" not the correct \"`\\n\" values for the archive "
118 Expected
<StringRef
> NameOrErr
= getName(Size
);
120 consumeError(NameOrErr
.takeError());
121 uint64_t Offset
= RawHeaderPtr
- Parent
->getData().data();
122 *Err
= malformedError(Msg
+ "at offset " + Twine(Offset
));
124 *Err
= malformedError(Msg
+ "for " + NameOrErr
.get());
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)
137 ErrorAsOutParameter
ErrAsOutParam(Err
);
139 if (RawHeaderPtr
+ getSizeOf() >= Parent
->getData().end()) {
141 *Err
= malformedError("malformed AIX big archive: remaining buffer is "
142 "unable to contain next archive member");
146 if (Size
< getSizeOf()) {
147 Error SubErr
= createMemberHeaderParseError(this, RawHeaderPtr
, Size
);
149 *Err
= std::move(SubErr
);
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 {
157 auto Kind
= Parent
->kind();
158 if (Kind
== Archive::K_BSD
|| Kind
== Archive::K_DARWIN64
) {
159 if (ArMemHdr
->Name
[0] == ' ') {
161 reinterpret_cast<const char *>(ArMemHdr
) - Parent
->getData().data();
162 return malformedError("name contains a leading space for archive member "
163 "header at offset " +
167 } else if (ArMemHdr
->Name
[0] == '/' || ArMemHdr
->Name
[0] == '#')
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
);
181 getArchiveMemberDecField(Twine FieldName
, const StringRef RawField
,
182 const Archive
*Parent
,
183 const AbstractArchiveMemberHeader
*MemHeader
) {
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: '" +
192 "member header at offset " +
199 getArchiveMemberOctField(Twine FieldName
, const StringRef RawField
,
200 const Archive
*Parent
,
201 const AbstractArchiveMemberHeader
*MemHeader
) {
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: '" +
210 "member header at offset " +
216 Expected
<StringRef
> BigArchiveMemberHeader::getRawName() const {
217 Expected
<uint64_t> NameLenOrErr
= getArchiveMemberDecField(
218 "NameLen", getFieldRawString(ArMemHdr
->NameLen
), Parent
, this);
220 // TODO: Out-of-line.
221 return NameLenOrErr
.takeError();
222 uint64_t NameLen
= NameLenOrErr
.get();
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
)) {
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 " +
240 return StringRef(ArMemHdr
->Name
, NameLen
);
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 {
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
));
258 // The raw name itself can be invalid.
259 Expected
<StringRef
> NameOrErr
= getRawName();
261 return NameOrErr
.takeError();
262 StringRef Name
= NameOrErr
.get();
264 // Check if it's a special name.
265 if (Name
[0] == '/') {
266 if (Name
.size() == 1) // Linker member.
268 if (Name
.size() == 2 && Name
[1] == '/') // String table.
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>/")
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>/")
279 // Get the string table offset.
280 std::size_t StringOffset
;
281 if (Name
.substr(1).rtrim(' ').getAsInteger(10, StringOffset
)) {
283 raw_string_ostream
OS(Buf
);
284 OS
.write_escaped(Name
.substr(1).rtrim(' '));
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
));
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
));
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");
313 return Parent
->getStringTable().slice(StringOffset
, End
- 1);
315 return Parent
->getStringTable().begin() + StringOffset
;
318 if (Name
.starts_with("#1/")) {
320 if (Name
.substr(3).rtrim(' ').getAsInteger(10, NameLength
)) {
322 raw_string_ostream
OS(Buf
);
323 OS
.write_escaped(Name
.substr(3).rtrim(' '));
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
));
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
));
340 return StringRef(reinterpret_cast<const char *>(ArMemHdr
) + getSizeOf(),
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(' ');
349 // It's a simple name.
350 return Name
.drop_back(1);
353 Expected
<StringRef
> BigArchiveMemberHeader::getName(uint64_t Size
) const {
357 Expected
<uint64_t> ArchiveMemberHeader::getSize() const {
358 return getArchiveMemberDecField("size", getFieldRawString(ArMemHdr
->Size
),
362 Expected
<uint64_t> BigArchiveMemberHeader::getSize() const {
363 Expected
<uint64_t> SizeOrErr
= getArchiveMemberDecField(
364 "size", getFieldRawString(ArMemHdr
->Size
), Parent
, this);
366 return SizeOrErr
.takeError();
368 Expected
<uint64_t> NameLenOrErr
= getRawNameSize();
370 return NameLenOrErr
.takeError();
372 return *SizeOrErr
+ alignTo(*NameLenOrErr
, 2);
375 Expected
<uint64_t> BigArchiveMemberHeader::getRawNameSize() const {
376 return getArchiveMemberDecField(
377 "NameLen", getFieldRawString(ArMemHdr
->NameLen
), Parent
, this);
380 Expected
<uint64_t> BigArchiveMemberHeader::getNextOffset() const {
381 return getArchiveMemberDecField(
382 "NextOffset", getFieldRawString(ArMemHdr
->NextOffset
), Parent
, this);
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
);
393 Expected
<sys::TimePoint
<std::chrono::seconds
>>
394 AbstractArchiveMemberHeader::getLastModified() const {
395 Expected
<uint64_t> SecondsOrErr
= getArchiveMemberDecField(
396 "LastModified", getRawLastModified(), Parent
, this);
399 return SecondsOrErr
.takeError();
401 return sys::toTimePoint(*SecondsOrErr
);
404 Expected
<unsigned> AbstractArchiveMemberHeader::getUID() const {
405 StringRef User
= getRawUID();
408 return getArchiveMemberDecField("UID", User
, Parent
, this);
411 Expected
<unsigned> AbstractArchiveMemberHeader::getGID() const {
412 StringRef Group
= getRawGID();
415 return getArchiveMemberDecField("GID", Group
, Parent
, this);
418 Expected
<bool> ArchiveMemberHeader::isThin() const {
419 Expected
<StringRef
> NameOrErr
= getRawName();
421 return NameOrErr
.takeError();
422 StringRef Name
= NameOrErr
.get();
423 return Parent
->isThin() && Name
!= "/" && Name
!= "//" && Name
!= "/SYM64/";
426 Expected
<const char *> ArchiveMemberHeader::getNextChildLoc() const {
427 uint64_t Size
= getSizeOf();
428 Expected
<bool> isThinOrErr
= isThin();
430 return isThinOrErr
.takeError();
432 bool isThin
= isThinOrErr
.get();
434 Expected
<uint64_t> MemberSize
= getSize();
436 return MemberSize
.takeError();
438 Size
+= MemberSize
.get();
441 // If Size is odd, add 1 to make it even.
442 const char *NextLoc
=
443 reinterpret_cast<const char *>(ArMemHdr
) + alignTo(Size
, 2);
445 if (NextLoc
== Parent
->getMemoryBufferRef().getBufferEnd())
451 Expected
<const char *> BigArchiveMemberHeader::getNextChildLoc() const {
453 static_cast<const BigArchive
*>(Parent
)->getLastChildOffset())
456 Expected
<uint64_t> NextOffsetOrErr
= getNextOffset();
457 if (!NextOffsetOrErr
)
458 return NextOffsetOrErr
.takeError();
459 return Parent
->getData().data() + NextOffsetOrErr
.get();
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);
468 Archive::Child::Child(const Archive
*Parent
, const char *Start
, Error
*Err
)
476 Header
= Parent
->createArchiveMemberHeader(
478 Parent
? Parent
->getData().size() - (Start
- Parent
->getData().data())
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
486 assert(Err
&& "Err can't be nullptr if Start is not a nullptr");
488 ErrorAsOutParameter
ErrAsOutParam(Err
);
490 // If there was an error in the construction of the Header
491 // then just return with the error now set.
495 uint64_t Size
= Header
->getSizeOf();
496 Data
= StringRef(Start
, Size
);
497 Expected
<bool> isThinOrErr
= isThinMember();
499 *Err
= isThinOrErr
.takeError();
502 bool isThin
= isThinOrErr
.get();
504 Expected
<uint64_t> MemberSize
= getRawSize();
506 *Err
= MemberSize
.takeError();
509 Size
+= MemberSize
.get();
510 Data
= StringRef(Start
, Size
);
513 // Setup StartOfFile and PaddingBytes.
514 StartOfFile
= Header
->getSizeOf();
515 // Don't include attached name.
516 Expected
<StringRef
> NameOrErr
= getRawName();
518 *Err
= NameOrErr
.takeError();
521 StringRef Name
= NameOrErr
.get();
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/")) {
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: '" +
535 "' for archive member header at offset " +
539 StartOfFile
+= NameSize
;
543 Expected
<uint64_t> Archive::Child::getSize() const {
545 return Header
->getSize();
546 return Data
.size() - StartOfFile
;
549 Expected
<uint64_t> Archive::Child::getRawSize() const {
550 return Header
->getSize();
553 Expected
<bool> Archive::Child::isThinMember() const { return Header
->isThin(); }
555 Expected
<std::string
> Archive::Child::getFullName() const {
556 Expected
<bool> isThin
= isThinMember();
558 return isThin
.takeError();
559 assert(isThin
.get());
560 Expected
<StringRef
> NameOrErr
= getName();
562 return NameOrErr
.takeError();
563 StringRef Name
= *NameOrErr
;
564 if (sys::path::is_absolute(Name
))
565 return std::string(Name
);
567 SmallString
<128> FullName
= sys::path::parent_path(
568 Parent
->getMemoryBufferRef().getBufferIdentifier());
569 sys::path::append(FullName
, Name
);
570 return std::string(FullName
);
573 Expected
<StringRef
> Archive::Child::getBuffer() const {
574 Expected
<bool> isThinOrErr
= isThinMember();
576 return isThinOrErr
.takeError();
577 bool isThin
= isThinOrErr
.get();
579 Expected
<uint64_t> Size
= getSize();
581 return Size
.takeError();
582 return StringRef(Data
.data() + StartOfFile
, Size
.get());
584 Expected
<std::string
> FullNameOrErr
= getFullName();
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();
595 Expected
<Archive::Child
> Archive::Child::getNext() const {
596 Expected
<const char *> NextLocOrErr
= Header
->getNextChildLoc();
598 return NextLocOrErr
.takeError();
600 const char *NextLoc
= *NextLocOrErr
;
602 // Check to see if this is at the end of the archive.
603 if (NextLoc
== nullptr)
604 return Child(nullptr, nullptr, nullptr);
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 "
610 Expected
<StringRef
> NameOrErr
= getName();
612 consumeError(NameOrErr
.takeError());
613 uint64_t Offset
= Data
.data() - Parent
->getData().data();
614 return malformedError(Msg
+ "at offset " + Twine(Offset
));
616 return malformedError(Msg
+ NameOrErr
.get());
619 Error Err
= Error::success();
620 Child
Ret(Parent
, NextLoc
, &Err
);
622 return std::move(Err
);
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
;
633 Expected
<StringRef
> Archive::Child::getName() const {
634 Expected
<uint64_t> RawSizeOrErr
= getRawSize();
636 return RawSizeOrErr
.takeError();
637 uint64_t RawSize
= RawSizeOrErr
.get();
638 Expected
<StringRef
> NameOrErr
=
639 Header
->getName(Header
->getSizeOf() + RawSize
);
641 return NameOrErr
.takeError();
642 StringRef Name
= NameOrErr
.get();
646 Expected
<MemoryBufferRef
> Archive::Child::getMemoryBufferRef() const {
647 Expected
<StringRef
> NameOrErr
= getName();
649 return NameOrErr
.takeError();
650 StringRef Name
= NameOrErr
.get();
651 Expected
<StringRef
> Buf
= getBuffer();
653 return createFileError(Name
, Buf
.takeError());
654 return MemoryBufferRef(*Buf
, Name
);
657 Expected
<std::unique_ptr
<Binary
>>
658 Archive::Child::getAsBinary(LLVMContext
*Context
) const {
659 Expected
<MemoryBufferRef
> BuffOrErr
= getMemoryBufferRef();
661 return BuffOrErr
.takeError();
663 auto BinaryOrErr
= createBinary(BuffOrErr
.get(), Context
);
665 return std::move(*BinaryOrErr
);
666 return BinaryOrErr
.takeError();
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();
674 if (Buffer
.starts_with(BigArchiveMagic
))
675 Ret
= std::make_unique
<BigArchive
>(Source
, Err
);
677 Ret
= std::make_unique
<Archive
>(Source
, Err
);
680 return std::move(Err
);
681 return std::move(Ret
);
684 std::unique_ptr
<AbstractArchiveMemberHeader
>
685 Archive::createArchiveMemberHeader(const char *RawHeaderPtr
, uint64_t Size
,
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
,
694 uint64_t Archive::getArchiveMagicLen() const {
696 return sizeof(ThinArchiveMagic
) - 1;
698 if (Kind() == K_AIXBIG
)
699 return sizeof(BigArchiveMagic
) - 1;
701 return sizeof(ArchiveMagic
) - 1;
704 void Archive::setFirstRegular(const Child
&C
) {
705 FirstRegularData
= C
.Data
;
706 FirstRegularStartOfFile
= C
.StartOfFile
;
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
)) {
716 } else if (Buffer
.starts_with(ArchiveMagic
)) {
718 } else if (Buffer
.starts_with(BigArchiveMagic
)) {
723 Err
= make_error
<GenericBinaryError
>("file too small to be an archive",
724 object_error::invalid_file_type
);
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
735 // Get the special members.
736 child_iterator I
= child_begin(Err
, false);
739 child_iterator E
= child_end();
741 // See if this is a valid empty archive and if so return.
743 Err
= Error::success();
746 const Child
*C
= &*I
;
748 auto Increment
= [&]() {
756 Expected
<StringRef
> NameOrErr
= C
->getRawName();
758 Err
= NameOrErr
.takeError();
761 StringRef Name
= NameOrErr
.get();
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
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.
782 if (Name
== "__.SYMDEF" || Name
== "__.SYMDEF_64") {
783 if (Name
== "__.SYMDEF")
785 else // Name == "__.SYMDEF_64"
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();
791 Err
= BufOrErr
.takeError();
794 SymbolTable
= BufOrErr
.get();
799 Err
= Error::success();
803 if (Name
.starts_with("#1/")) {
805 // We know this is BSD, so getName will work since there is no string table.
806 Expected
<StringRef
> NameOrErr
= C
->getName();
808 Err
= NameOrErr
.takeError();
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();
817 Err
= BufOrErr
.takeError();
820 SymbolTable
= BufOrErr
.get();
823 } else if (Name
== "__.SYMDEF_64 SORTED" || Name
== "__.SYMDEF_64") {
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();
829 Err
= BufOrErr
.takeError();
832 SymbolTable
= BufOrErr
.get();
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
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();
851 Err
= BufOrErr
.takeError();
854 SymbolTable
= BufOrErr
.get();
855 if (Name
== "/SYM64/")
856 has64SymTable
= true;
861 Err
= Error::success();
864 Expected
<StringRef
> NameOrErr
= C
->getRawName();
866 Err
= NameOrErr
.takeError();
869 Name
= NameOrErr
.get();
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();
878 Err
= BufOrErr
.takeError();
881 StringTable
= BufOrErr
.get();
885 Err
= Error::success();
889 if (Name
[0] != '/') {
890 Format
= has64SymTable
? K_GNU64
: K_GNU
;
892 Err
= Error::success();
897 Err
= errorCodeToError(object_error::parse_failed
);
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();
906 Err
= BufOrErr
.takeError();
909 SymbolTable
= BufOrErr
.get();
916 Err
= Error::success();
920 NameOrErr
= C
->getRawName();
922 Err
= NameOrErr
.takeError();
925 Name
= NameOrErr
.get();
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();
932 Err
= BufOrErr
.takeError();
935 StringTable
= BufOrErr
.get();
941 Err
= Error::success();
945 NameOrErr
= C
->getRawName();
947 Err
= NameOrErr
.takeError();
950 Name
= NameOrErr
.get();
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();
960 Err
= BufOrErr
.takeError();
963 ECSymbolTable
= BufOrErr
.get();
969 Err
= Error::success();
972 object::Archive::Kind
Archive::getDefaultKindForTriple(Triple
&T
) {
974 return object::Archive::K_DARWIN
;
976 return object::Archive::K_AIXBIG
;
978 return object::Archive::K_COFF
;
979 return object::Archive::K_GNU
;
982 object::Archive::Kind
Archive::getDefaultKind() {
983 Triple
HostTriple(sys::getDefaultTargetTriple());
984 return getDefaultKindForTriple(HostTriple
);
987 Archive::child_iterator
Archive::child_begin(Error
&Err
,
988 bool SkipInternal
) const {
993 return child_iterator::itr(
994 Child(this, FirstRegularData
, FirstRegularStartOfFile
), Err
);
996 const char *Loc
= Data
.getBufferStart() + getFirstChildOffset();
997 Child
C(this, Loc
, &Err
);
1000 return child_iterator::itr(C
, Err
);
1003 Archive::child_iterator
Archive::child_end() const {
1004 return child_iterator::end(Child(nullptr, nullptr, nullptr));
1007 bool Archive::Symbol::isECSymbol() const {
1008 // Symbols use SymbolCount..SymbolCount+getNumberOfECSymbols() for EC symbol
1010 uint32_t SymbolCount
= Parent
->getNumberOfSymbols();
1011 return SymbolCount
<= SymbolIndex
&&
1012 SymbolIndex
< SymbolCount
+ Parent
->getNumberOfECSymbols();
1015 StringRef
Archive::Symbol::getName() const {
1017 return Parent
->ECSymbolTable
.begin() + StringIndex
;
1018 return Parent
->getSymbolTable().begin() + StringIndex
;
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);
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
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
1049 Offset
= read64le(Offsets
+ SymbolIndex
* 16 + 8);
1052 uint32_t MemberCount
= read32le(Buf
);
1053 Buf
+= MemberCount
* 4 + 4;
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;
1061 // Get the index of the offset in the file member offset table for this
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;
1068 // Get the index of the offset in the file member offset table for this
1070 OffsetIndex
= read16le(Indices
+ (SymbolIndex
- SymbolCount
) * 2);
1072 return errorCodeToError(object_error::parse_failed
);
1074 // Subtract 1 since OffsetIndex is 1 based.
1077 if (OffsetIndex
>= MemberCount
)
1078 return errorCodeToError(object_error::parse_failed
);
1080 Offset
= read32le(Offsets
+ OffsetIndex
* 4);
1083 const char *Loc
= Parent
->getData().begin() + Offset
;
1084 Error Err
= Error::success();
1085 Child
C(Parent
, Loc
, &Err
);
1087 return std::move(Err
);
1091 Archive::Symbol
Archive::Symbol::getNext() const {
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.
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
;
1122 } else if (t
.isECSymbol()) {
1123 // Go to one past next null.
1124 t
.StringIndex
= Parent
->ECSymbolTable
.find('\0', t
.StringIndex
) + 1;
1126 // Go to one past next null.
1127 t
.StringIndex
= Parent
->getSymbolTable().find('\0', t
.StringIndex
) + 1;
1133 Archive::symbol_iterator
Archive::symbol_begin() const {
1134 if (!hasSymbolTable())
1135 return symbol_iterator(Symbol(this, 0, 0));
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);
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);
1177 } else if (kind() == K_AIXBIG
) {
1178 buf
= getStringTable().begin();
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.
1187 uint32_t string_start_offset
= buf
- getSymbolTable().begin();
1188 return symbol_iterator(Symbol(this, 0, string_start_offset
));
1191 Archive::symbol_iterator
Archive::symbol_end() const {
1192 return symbol_iterator(Symbol(this, getNumberOfSymbols(), 0));
1195 Expected
<iterator_range
<Archive::symbol_iterator
>> Archive::ec_symbols() const {
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()) + ")");
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
));
1214 uint32_t MemberCount
= read32le(SymbolTable
.begin());
1215 const char *Indexes
= ECSymbolTable
.begin() + sizeof(uint32_t);
1217 for (uint32_t i
= 0; i
< Count
; ++i
) {
1218 uint16_t Index
= read16le(Indexes
+ i
* sizeof(uint16_t));
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
));
1226 StringIndex
= ECSymbolTable
.find('\0', StringIndex
);
1227 if (StringIndex
== StringRef::npos
)
1228 return malformedError("malformed EC symbol names: not null-terminated");
1233 uint32_t SymbolCount
= getNumberOfSymbols();
1235 symbol_iterator(Symbol(this, SymbolCount
,
1236 sizeof(uint32_t) + Count
* sizeof(uint16_t))),
1237 symbol_iterator(Symbol(this, SymbolCount
+ Count
, 0)));
1240 uint32_t Archive::getNumberOfSymbols() const {
1241 if (!hasSymbolTable())
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
);
1258 uint32_t Archive::getNumberOfECSymbols() const {
1259 if (ECSymbolTable
.size() < sizeof(uint32_t))
1261 return read32le(ECSymbolTable
.begin());
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();
1268 for (; bs
!= es
; ++bs
) {
1269 StringRef SymName
= bs
->getName();
1270 if (SymName
== name
) {
1271 if (auto MemberOrErr
= bs
->getMember())
1272 return Child(*MemberOrErr
);
1274 return MemberOrErr
.takeError();
1277 return std::nullopt
;
1280 // Returns true if archive file contains no member file.
1281 bool Archive::isEmpty() const {
1282 return Data
.getBufferSize() == getArchiveMagicLen();
1285 bool Archive::hasSymbolTable() const { return !SymbolTable
.empty(); }
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");
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");
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");
1315 return Error::success();
1318 struct GlobalSymtabInfo
{
1320 StringRef SymbolTable
;
1321 StringRef SymbolOffsetTable
;
1322 StringRef StringTable
;
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)).
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
});
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();
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)");
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");
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");
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");
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");
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();
1396 if (GlobSymtab32Offset
) {
1398 getGlobalSymtabLocAndSize(MemBuffRef
, GlobSymtab32Offset
,
1399 GlobSymtab32Loc
, GlobSymtab32Size
, "32-bit");
1403 Has32BitGlobalSymtab
= true;
1406 if (GlobSymtab64Offset
) {
1408 getGlobalSymtabLocAndSize(MemBuffRef
, GlobSymtab64Offset
,
1409 GlobSymtab64Loc
, GlobSymtab64Size
, "64-bit");
1413 Has64BitGlobalSymtab
= true;
1416 SmallVector
<GlobalSymtabInfo
> SymtabInfos
;
1418 if (GlobSymtab32Offset
)
1419 appendGlobalSymbolTableInfo(SymtabInfos
, GlobSymtab32Loc
, GlobSymtab32Size
);
1420 if (GlobSymtab64Offset
)
1421 appendGlobalSymbolTableInfo(SymtabInfos
, GlobSymtab64Loc
, GlobSymtab64Size
);
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());
1445 child_iterator I
= child_begin(Err
, false);
1448 child_iterator E
= child_end();
1450 Err
= Error::success();
1453 setFirstRegular(*I
);
1454 Err
= Error::success();