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/Optional.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/Object/Binary.h"
19 #include "llvm/Object/Error.h"
20 #include "llvm/Support/Chrono.h"
21 #include "llvm/Support/Endian.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/ErrorOr.h"
24 #include "llvm/Support/FileSystem.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Support/Path.h"
27 #include "llvm/Support/raw_ostream.h"
35 #include <system_error>
38 using namespace object
;
39 using namespace llvm::support::endian
;
41 static const char *const Magic
= "!<arch>\n";
42 static const char *const ThinMagic
= "!<thin>\n";
44 void Archive::anchor() {}
47 malformedError(Twine Msg
) {
48 std::string StringMsg
= "truncated or malformed archive (" + Msg
.str() + ")";
49 return make_error
<GenericBinaryError
>(std::move(StringMsg
),
50 object_error::parse_failed
);
53 ArchiveMemberHeader::ArchiveMemberHeader(const Archive
*Parent
,
54 const char *RawHeaderPtr
,
55 uint64_t Size
, Error
*Err
)
57 ArMemHdr(reinterpret_cast<const ArMemHdrType
*>(RawHeaderPtr
)) {
58 if (RawHeaderPtr
== nullptr)
60 ErrorAsOutParameter
ErrAsOutParam(Err
);
62 if (Size
< sizeof(ArMemHdrType
)) {
64 std::string
Msg("remaining size of archive too small for next archive "
66 Expected
<StringRef
> NameOrErr
= getName(Size
);
68 consumeError(NameOrErr
.takeError());
69 uint64_t Offset
= RawHeaderPtr
- Parent
->getData().data();
70 *Err
= malformedError(Msg
+ "at offset " + Twine(Offset
));
72 *Err
= malformedError(Msg
+ "for " + NameOrErr
.get());
76 if (ArMemHdr
->Terminator
[0] != '`' || ArMemHdr
->Terminator
[1] != '\n') {
79 raw_string_ostream
OS(Buf
);
80 OS
.write_escaped(StringRef(ArMemHdr
->Terminator
,
81 sizeof(ArMemHdr
->Terminator
)));
83 std::string
Msg("terminator characters in archive member \"" + Buf
+
84 "\" not the correct \"`\\n\" values for the archive "
86 Expected
<StringRef
> NameOrErr
= getName(Size
);
88 consumeError(NameOrErr
.takeError());
89 uint64_t Offset
= RawHeaderPtr
- Parent
->getData().data();
90 *Err
= malformedError(Msg
+ "at offset " + Twine(Offset
));
92 *Err
= malformedError(Msg
+ "for " + NameOrErr
.get());
98 // This gets the raw name from the ArMemHdr->Name field and checks that it is
99 // valid for the kind of archive. If it is not valid it returns an Error.
100 Expected
<StringRef
> ArchiveMemberHeader::getRawName() const {
102 auto Kind
= Parent
->kind();
103 if (Kind
== Archive::K_BSD
|| Kind
== Archive::K_DARWIN64
) {
104 if (ArMemHdr
->Name
[0] == ' ') {
105 uint64_t Offset
= reinterpret_cast<const char *>(ArMemHdr
) -
106 Parent
->getData().data();
107 return malformedError("name contains a leading space for archive member "
108 "header at offset " + Twine(Offset
));
112 else if (ArMemHdr
->Name
[0] == '/' || ArMemHdr
->Name
[0] == '#')
116 StringRef::size_type end
=
117 StringRef(ArMemHdr
->Name
, sizeof(ArMemHdr
->Name
)).find(EndCond
);
118 if (end
== StringRef::npos
)
119 end
= sizeof(ArMemHdr
->Name
);
120 assert(end
<= sizeof(ArMemHdr
->Name
) && end
> 0);
121 // Don't include the EndCond if there is one.
122 return StringRef(ArMemHdr
->Name
, end
);
125 // This gets the name looking up long names. Size is the size of the archive
126 // member including the header, so the size of any name following the header
127 // is checked to make sure it does not overflow.
128 Expected
<StringRef
> ArchiveMemberHeader::getName(uint64_t Size
) const {
130 // This can be called from the ArchiveMemberHeader constructor when the
131 // archive header is truncated to produce an error message with the name.
132 // Make sure the name field is not truncated.
133 if (Size
< offsetof(ArMemHdrType
, Name
) + sizeof(ArMemHdr
->Name
)) {
134 uint64_t ArchiveOffset
= reinterpret_cast<const char *>(ArMemHdr
) -
135 Parent
->getData().data();
136 return malformedError("archive header truncated before the name field "
137 "for archive member header at offset " +
138 Twine(ArchiveOffset
));
141 // The raw name itself can be invalid.
142 Expected
<StringRef
> NameOrErr
= getRawName();
144 return NameOrErr
.takeError();
145 StringRef Name
= NameOrErr
.get();
147 // Check if it's a special name.
148 if (Name
[0] == '/') {
149 if (Name
.size() == 1) // Linker member.
151 if (Name
.size() == 2 && Name
[1] == '/') // String table.
154 // Get the string table offset.
155 std::size_t StringOffset
;
156 if (Name
.substr(1).rtrim(' ').getAsInteger(10, StringOffset
)) {
158 raw_string_ostream
OS(Buf
);
159 OS
.write_escaped(Name
.substr(1).rtrim(' '));
161 uint64_t ArchiveOffset
= reinterpret_cast<const char *>(ArMemHdr
) -
162 Parent
->getData().data();
163 return malformedError("long name offset characters after the '/' are "
164 "not all decimal numbers: '" + Buf
+ "' for "
165 "archive member header at offset " +
166 Twine(ArchiveOffset
));
170 if (StringOffset
>= Parent
->getStringTable().size()) {
171 uint64_t ArchiveOffset
= reinterpret_cast<const char *>(ArMemHdr
) -
172 Parent
->getData().data();
173 return malformedError("long name offset " + Twine(StringOffset
) + " past "
174 "the end of the string table for archive member "
175 "header at offset " + Twine(ArchiveOffset
));
178 // GNU long file names end with a "/\n".
179 if (Parent
->kind() == Archive::K_GNU
||
180 Parent
->kind() == Archive::K_GNU64
) {
181 size_t End
= Parent
->getStringTable().find('\n', /*From=*/StringOffset
);
182 if (End
== StringRef::npos
|| End
< 1 ||
183 Parent
->getStringTable()[End
- 1] != '/') {
184 return malformedError("string table at long name offset " +
185 Twine(StringOffset
) + "not terminated");
187 return Parent
->getStringTable().slice(StringOffset
, End
- 1);
189 return Parent
->getStringTable().begin() + StringOffset
;
192 if (Name
.startswith("#1/")) {
194 if (Name
.substr(3).rtrim(' ').getAsInteger(10, NameLength
)) {
196 raw_string_ostream
OS(Buf
);
197 OS
.write_escaped(Name
.substr(3).rtrim(' '));
199 uint64_t ArchiveOffset
= reinterpret_cast<const char *>(ArMemHdr
) -
200 Parent
->getData().data();
201 return malformedError("long name length characters after the #1/ are "
202 "not all decimal numbers: '" + Buf
+ "' for "
203 "archive member header at offset " +
204 Twine(ArchiveOffset
));
206 if (getSizeOf() + NameLength
> Size
) {
207 uint64_t ArchiveOffset
= reinterpret_cast<const char *>(ArMemHdr
) -
208 Parent
->getData().data();
209 return malformedError("long name length: " + Twine(NameLength
) +
210 " extends past the end of the member or archive "
211 "for archive member header at offset " +
212 Twine(ArchiveOffset
));
214 return StringRef(reinterpret_cast<const char *>(ArMemHdr
) + getSizeOf(),
215 NameLength
).rtrim('\0');
218 // It is not a long name so trim the blanks at the end of the name.
219 if (Name
[Name
.size() - 1] != '/')
220 return Name
.rtrim(' ');
222 // It's a simple name.
223 return Name
.drop_back(1);
226 Expected
<uint64_t> ArchiveMemberHeader::getSize() const {
228 if (StringRef(ArMemHdr
->Size
,
229 sizeof(ArMemHdr
->Size
)).rtrim(" ").getAsInteger(10, Ret
)) {
231 raw_string_ostream
OS(Buf
);
232 OS
.write_escaped(StringRef(ArMemHdr
->Size
,
233 sizeof(ArMemHdr
->Size
)).rtrim(" "));
235 uint64_t Offset
= reinterpret_cast<const char *>(ArMemHdr
) -
236 Parent
->getData().data();
237 return malformedError("characters in size field in archive header are not "
238 "all decimal numbers: '" + Buf
+ "' for archive "
239 "member header at offset " + Twine(Offset
));
244 Expected
<sys::fs::perms
> ArchiveMemberHeader::getAccessMode() const {
246 if (StringRef(ArMemHdr
->AccessMode
,
247 sizeof(ArMemHdr
->AccessMode
)).rtrim(' ').getAsInteger(8, Ret
)) {
249 raw_string_ostream
OS(Buf
);
250 OS
.write_escaped(StringRef(ArMemHdr
->AccessMode
,
251 sizeof(ArMemHdr
->AccessMode
)).rtrim(" "));
253 uint64_t Offset
= reinterpret_cast<const char *>(ArMemHdr
) -
254 Parent
->getData().data();
255 return malformedError("characters in AccessMode field in archive header "
256 "are not all decimal numbers: '" + Buf
+ "' for the "
257 "archive member header at offset " + Twine(Offset
));
259 return static_cast<sys::fs::perms
>(Ret
);
262 Expected
<sys::TimePoint
<std::chrono::seconds
>>
263 ArchiveMemberHeader::getLastModified() const {
265 if (StringRef(ArMemHdr
->LastModified
,
266 sizeof(ArMemHdr
->LastModified
)).rtrim(' ')
267 .getAsInteger(10, Seconds
)) {
269 raw_string_ostream
OS(Buf
);
270 OS
.write_escaped(StringRef(ArMemHdr
->LastModified
,
271 sizeof(ArMemHdr
->LastModified
)).rtrim(" "));
273 uint64_t Offset
= reinterpret_cast<const char *>(ArMemHdr
) -
274 Parent
->getData().data();
275 return malformedError("characters in LastModified field in archive header "
276 "are not all decimal numbers: '" + Buf
+ "' for the "
277 "archive member header at offset " + Twine(Offset
));
280 return sys::toTimePoint(Seconds
);
283 Expected
<unsigned> ArchiveMemberHeader::getUID() const {
285 StringRef User
= StringRef(ArMemHdr
->UID
, sizeof(ArMemHdr
->UID
)).rtrim(' ');
288 if (User
.getAsInteger(10, Ret
)) {
290 raw_string_ostream
OS(Buf
);
291 OS
.write_escaped(User
);
293 uint64_t Offset
= reinterpret_cast<const char *>(ArMemHdr
) -
294 Parent
->getData().data();
295 return malformedError("characters in UID field in archive header "
296 "are not all decimal numbers: '" + Buf
+ "' for the "
297 "archive member header at offset " + Twine(Offset
));
302 Expected
<unsigned> ArchiveMemberHeader::getGID() const {
304 StringRef Group
= StringRef(ArMemHdr
->GID
, sizeof(ArMemHdr
->GID
)).rtrim(' ');
307 if (Group
.getAsInteger(10, Ret
)) {
309 raw_string_ostream
OS(Buf
);
310 OS
.write_escaped(Group
);
312 uint64_t Offset
= reinterpret_cast<const char *>(ArMemHdr
) -
313 Parent
->getData().data();
314 return malformedError("characters in GID field in archive header "
315 "are not all decimal numbers: '" + Buf
+ "' for the "
316 "archive member header at offset " + Twine(Offset
));
321 Archive::Child::Child(const Archive
*Parent
, StringRef Data
,
322 uint16_t StartOfFile
)
323 : Parent(Parent
), Header(Parent
, Data
.data(), Data
.size(), nullptr),
324 Data(Data
), StartOfFile(StartOfFile
) {
327 Archive::Child::Child(const Archive
*Parent
, const char *Start
, Error
*Err
)
329 Header(Parent
, Start
,
331 ? Parent
->getData().size() - (Start
- Parent
->getData().data())
336 // If we are pointed to real data, Start is not a nullptr, then there must be
337 // a non-null Err pointer available to report malformed data on. Only in
338 // the case sentinel value is being constructed is Err is permitted to be a
340 assert(Err
&& "Err can't be nullptr if Start is not a nullptr");
342 ErrorAsOutParameter
ErrAsOutParam(Err
);
344 // If there was an error in the construction of the Header
345 // then just return with the error now set.
349 uint64_t Size
= Header
.getSizeOf();
350 Data
= StringRef(Start
, Size
);
351 Expected
<bool> isThinOrErr
= isThinMember();
353 *Err
= isThinOrErr
.takeError();
356 bool isThin
= isThinOrErr
.get();
358 Expected
<uint64_t> MemberSize
= getRawSize();
360 *Err
= MemberSize
.takeError();
363 Size
+= MemberSize
.get();
364 Data
= StringRef(Start
, Size
);
367 // Setup StartOfFile and PaddingBytes.
368 StartOfFile
= Header
.getSizeOf();
369 // Don't include attached name.
370 Expected
<StringRef
> NameOrErr
= getRawName();
372 *Err
= NameOrErr
.takeError();
375 StringRef Name
= NameOrErr
.get();
376 if (Name
.startswith("#1/")) {
378 if (Name
.substr(3).rtrim(' ').getAsInteger(10, NameSize
)) {
380 raw_string_ostream
OS(Buf
);
381 OS
.write_escaped(Name
.substr(3).rtrim(' '));
383 uint64_t Offset
= Start
- Parent
->getData().data();
384 *Err
= malformedError("long name length characters after the #1/ are "
385 "not all decimal numbers: '" + Buf
+ "' for "
386 "archive member header at offset " +
390 StartOfFile
+= NameSize
;
394 Expected
<uint64_t> Archive::Child::getSize() const {
395 if (Parent
->IsThin
) {
396 Expected
<uint32_t> Size
= Header
.getSize();
398 return Size
.takeError();
401 return Data
.size() - StartOfFile
;
404 Expected
<uint64_t> Archive::Child::getRawSize() const {
405 return Header
.getSize();
408 Expected
<bool> Archive::Child::isThinMember() const {
409 Expected
<StringRef
> NameOrErr
= Header
.getRawName();
411 return NameOrErr
.takeError();
412 StringRef Name
= NameOrErr
.get();
413 return Parent
->IsThin
&& Name
!= "/" && Name
!= "//";
416 Expected
<std::string
> Archive::Child::getFullName() const {
417 Expected
<bool> isThin
= isThinMember();
419 return isThin
.takeError();
420 assert(isThin
.get());
421 Expected
<StringRef
> NameOrErr
= getName();
423 return NameOrErr
.takeError();
424 StringRef Name
= *NameOrErr
;
425 if (sys::path::is_absolute(Name
))
428 SmallString
<128> FullName
= sys::path::parent_path(
429 Parent
->getMemoryBufferRef().getBufferIdentifier());
430 sys::path::append(FullName
, Name
);
431 return StringRef(FullName
);
434 Expected
<StringRef
> Archive::Child::getBuffer() const {
435 Expected
<bool> isThinOrErr
= isThinMember();
437 return isThinOrErr
.takeError();
438 bool isThin
= isThinOrErr
.get();
440 Expected
<uint32_t> Size
= getSize();
442 return Size
.takeError();
443 return StringRef(Data
.data() + StartOfFile
, Size
.get());
445 Expected
<std::string
> FullNameOrErr
= getFullName();
447 return FullNameOrErr
.takeError();
448 const std::string
&FullName
= *FullNameOrErr
;
449 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> Buf
= MemoryBuffer::getFile(FullName
);
450 if (std::error_code EC
= Buf
.getError())
451 return errorCodeToError(EC
);
452 Parent
->ThinBuffers
.push_back(std::move(*Buf
));
453 return Parent
->ThinBuffers
.back()->getBuffer();
456 Expected
<Archive::Child
> Archive::Child::getNext() const {
457 size_t SpaceToSkip
= Data
.size();
458 // If it's odd, add 1 to make it even.
462 const char *NextLoc
= Data
.data() + SpaceToSkip
;
464 // Check to see if this is at the end of the archive.
465 if (NextLoc
== Parent
->Data
.getBufferEnd())
466 return Child(nullptr, nullptr, nullptr);
468 // Check to see if this is past the end of the archive.
469 if (NextLoc
> Parent
->Data
.getBufferEnd()) {
470 std::string
Msg("offset to next archive member past the end of the archive "
472 Expected
<StringRef
> NameOrErr
= getName();
474 consumeError(NameOrErr
.takeError());
475 uint64_t Offset
= Data
.data() - Parent
->getData().data();
476 return malformedError(Msg
+ "at offset " + Twine(Offset
));
478 return malformedError(Msg
+ NameOrErr
.get());
481 Error Err
= Error::success();
482 Child
Ret(Parent
, NextLoc
, &Err
);
484 return std::move(Err
);
488 uint64_t Archive::Child::getChildOffset() const {
489 const char *a
= Parent
->Data
.getBuffer().data();
490 const char *c
= Data
.data();
491 uint64_t offset
= c
- a
;
495 Expected
<StringRef
> Archive::Child::getName() const {
496 Expected
<uint64_t> RawSizeOrErr
= getRawSize();
498 return RawSizeOrErr
.takeError();
499 uint64_t RawSize
= RawSizeOrErr
.get();
500 Expected
<StringRef
> NameOrErr
= Header
.getName(Header
.getSizeOf() + RawSize
);
502 return NameOrErr
.takeError();
503 StringRef Name
= NameOrErr
.get();
507 Expected
<MemoryBufferRef
> Archive::Child::getMemoryBufferRef() const {
508 Expected
<StringRef
> NameOrErr
= getName();
510 return NameOrErr
.takeError();
511 StringRef Name
= NameOrErr
.get();
512 Expected
<StringRef
> Buf
= getBuffer();
514 return createFileError(Name
, Buf
.takeError());
515 return MemoryBufferRef(*Buf
, Name
);
518 Expected
<std::unique_ptr
<Binary
>>
519 Archive::Child::getAsBinary(LLVMContext
*Context
) const {
520 Expected
<MemoryBufferRef
> BuffOrErr
= getMemoryBufferRef();
522 return BuffOrErr
.takeError();
524 auto BinaryOrErr
= createBinary(BuffOrErr
.get(), Context
);
526 return std::move(*BinaryOrErr
);
527 return BinaryOrErr
.takeError();
530 Expected
<std::unique_ptr
<Archive
>> Archive::create(MemoryBufferRef Source
) {
531 Error Err
= Error::success();
532 std::unique_ptr
<Archive
> Ret(new Archive(Source
, Err
));
534 return std::move(Err
);
535 return std::move(Ret
);
538 void Archive::setFirstRegular(const Child
&C
) {
539 FirstRegularData
= C
.Data
;
540 FirstRegularStartOfFile
= C
.StartOfFile
;
543 Archive::Archive(MemoryBufferRef Source
, Error
&Err
)
544 : Binary(Binary::ID_Archive
, Source
) {
545 ErrorAsOutParameter
ErrAsOutParam(&Err
);
546 StringRef Buffer
= Data
.getBuffer();
547 // Check for sufficient magic.
548 if (Buffer
.startswith(ThinMagic
)) {
550 } else if (Buffer
.startswith(Magic
)) {
553 Err
= make_error
<GenericBinaryError
>("file too small to be an archive",
554 object_error::invalid_file_type
);
558 // Make sure Format is initialized before any call to
559 // ArchiveMemberHeader::getName() is made. This could be a valid empty
560 // archive which is the same in all formats. So claiming it to be gnu to is
561 // fine if not totally correct before we look for a string table or table of
565 // Get the special members.
566 child_iterator I
= child_begin(Err
, false);
569 child_iterator E
= child_end();
571 // See if this is a valid empty archive and if so return.
573 Err
= Error::success();
576 const Child
*C
= &*I
;
578 auto Increment
= [&]() {
586 Expected
<StringRef
> NameOrErr
= C
->getRawName();
588 Err
= NameOrErr
.takeError();
591 StringRef Name
= NameOrErr
.get();
593 // Below is the pattern that is used to figure out the archive format
594 // GNU archive format
595 // First member : / (may exist, if it exists, points to the symbol table )
596 // Second member : // (may exist, if it exists, points to the string table)
597 // Note : The string table is used if the filename exceeds 15 characters
598 // BSD archive format
599 // First member : __.SYMDEF or "__.SYMDEF SORTED" (the symbol table)
600 // There is no string table, if the filename exceeds 15 characters or has a
601 // embedded space, the filename has #1/<size>, The size represents the size
602 // of the filename that needs to be read after the archive header
603 // COFF archive format
605 // Second member : / (provides a directory of symbols)
606 // Third member : // (may exist, if it exists, contains the string table)
607 // Note: Microsoft PE/COFF Spec 8.3 says that the third member is present
608 // even if the string table is empty. However, lib.exe does not in fact
609 // seem to create the third member if there's no member whose filename
610 // exceeds 15 characters. So the third member is optional.
612 if (Name
== "__.SYMDEF" || Name
== "__.SYMDEF_64") {
613 if (Name
== "__.SYMDEF")
615 else // Name == "__.SYMDEF_64"
617 // We know that the symbol table is not an external file, but we still must
618 // check any Expected<> return value.
619 Expected
<StringRef
> BufOrErr
= C
->getBuffer();
621 Err
= BufOrErr
.takeError();
624 SymbolTable
= BufOrErr
.get();
629 Err
= Error::success();
633 if (Name
.startswith("#1/")) {
635 // We know this is BSD, so getName will work since there is no string table.
636 Expected
<StringRef
> NameOrErr
= C
->getName();
638 Err
= NameOrErr
.takeError();
641 Name
= NameOrErr
.get();
642 if (Name
== "__.SYMDEF SORTED" || Name
== "__.SYMDEF") {
643 // We know that the symbol table is not an external file, but we still
644 // must check any Expected<> return value.
645 Expected
<StringRef
> BufOrErr
= C
->getBuffer();
647 Err
= BufOrErr
.takeError();
650 SymbolTable
= BufOrErr
.get();
654 else if (Name
== "__.SYMDEF_64 SORTED" || Name
== "__.SYMDEF_64") {
656 // We know that the symbol table is not an external file, but we still
657 // must check any Expected<> return value.
658 Expected
<StringRef
> BufOrErr
= C
->getBuffer();
660 Err
= BufOrErr
.takeError();
663 SymbolTable
= BufOrErr
.get();
671 // MIPS 64-bit ELF archives use a special format of a symbol table.
672 // This format is marked by `ar_name` field equals to "/SYM64/".
673 // For detailed description see page 96 in the following document:
674 // http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
676 bool has64SymTable
= false;
677 if (Name
== "/" || Name
== "/SYM64/") {
678 // We know that the symbol table is not an external file, but we still
679 // must check any Expected<> return value.
680 Expected
<StringRef
> BufOrErr
= C
->getBuffer();
682 Err
= BufOrErr
.takeError();
685 SymbolTable
= BufOrErr
.get();
686 if (Name
== "/SYM64/")
687 has64SymTable
= true;
692 Err
= Error::success();
695 Expected
<StringRef
> NameOrErr
= C
->getRawName();
697 Err
= NameOrErr
.takeError();
700 Name
= NameOrErr
.get();
704 Format
= has64SymTable
? K_GNU64
: K_GNU
;
705 // The string table is never an external member, but we still
706 // must check any Expected<> return value.
707 Expected
<StringRef
> BufOrErr
= C
->getBuffer();
709 Err
= BufOrErr
.takeError();
712 StringTable
= BufOrErr
.get();
716 Err
= Error::success();
720 if (Name
[0] != '/') {
721 Format
= has64SymTable
? K_GNU64
: K_GNU
;
723 Err
= Error::success();
728 Err
= errorCodeToError(object_error::parse_failed
);
733 // We know that the symbol table is not an external file, but we still
734 // must check any Expected<> return value.
735 Expected
<StringRef
> BufOrErr
= C
->getBuffer();
737 Err
= BufOrErr
.takeError();
740 SymbolTable
= BufOrErr
.get();
747 Err
= Error::success();
751 NameOrErr
= C
->getRawName();
753 Err
= NameOrErr
.takeError();
756 Name
= NameOrErr
.get();
759 // The string table is never an external member, but we still
760 // must check any Expected<> return value.
761 Expected
<StringRef
> BufOrErr
= C
->getBuffer();
763 Err
= BufOrErr
.takeError();
766 StringTable
= BufOrErr
.get();
772 Err
= Error::success();
775 Archive::child_iterator
Archive::child_begin(Error
&Err
,
776 bool SkipInternal
) const {
781 return child_iterator::itr(
782 Child(this, FirstRegularData
, FirstRegularStartOfFile
), Err
);
784 const char *Loc
= Data
.getBufferStart() + strlen(Magic
);
785 Child
C(this, Loc
, &Err
);
788 return child_iterator::itr(C
, Err
);
791 Archive::child_iterator
Archive::child_end() const {
792 return child_iterator::end(Child(nullptr, nullptr, nullptr));
795 StringRef
Archive::Symbol::getName() const {
796 return Parent
->getSymbolTable().begin() + StringIndex
;
799 Expected
<Archive::Child
> Archive::Symbol::getMember() const {
800 const char *Buf
= Parent
->getSymbolTable().begin();
801 const char *Offsets
= Buf
;
802 if (Parent
->kind() == K_GNU64
|| Parent
->kind() == K_DARWIN64
)
803 Offsets
+= sizeof(uint64_t);
805 Offsets
+= sizeof(uint32_t);
807 if (Parent
->kind() == K_GNU
) {
808 Offset
= read32be(Offsets
+ SymbolIndex
* 4);
809 } else if (Parent
->kind() == K_GNU64
) {
810 Offset
= read64be(Offsets
+ SymbolIndex
* 8);
811 } else if (Parent
->kind() == K_BSD
) {
812 // The SymbolIndex is an index into the ranlib structs that start at
813 // Offsets (the first uint32_t is the number of bytes of the ranlib
814 // structs). The ranlib structs are a pair of uint32_t's the first
815 // being a string table offset and the second being the offset into
816 // the archive of the member that defines the symbol. Which is what
818 Offset
= read32le(Offsets
+ SymbolIndex
* 8 + 4);
819 } else if (Parent
->kind() == K_DARWIN64
) {
820 // The SymbolIndex is an index into the ranlib_64 structs that start at
821 // Offsets (the first uint64_t is the number of bytes of the ranlib_64
822 // structs). The ranlib_64 structs are a pair of uint64_t's the first
823 // being a string table offset and the second being the offset into
824 // the archive of the member that defines the symbol. Which is what
826 Offset
= read64le(Offsets
+ SymbolIndex
* 16 + 8);
829 uint32_t MemberCount
= read32le(Buf
);
830 Buf
+= MemberCount
* 4 + 4;
832 uint32_t SymbolCount
= read32le(Buf
);
833 if (SymbolIndex
>= SymbolCount
)
834 return errorCodeToError(object_error::parse_failed
);
836 // Skip SymbolCount to get to the indices table.
837 const char *Indices
= Buf
+ 4;
839 // Get the index of the offset in the file member offset table for this
841 uint16_t OffsetIndex
= read16le(Indices
+ SymbolIndex
* 2);
842 // Subtract 1 since OffsetIndex is 1 based.
845 if (OffsetIndex
>= MemberCount
)
846 return errorCodeToError(object_error::parse_failed
);
848 Offset
= read32le(Offsets
+ OffsetIndex
* 4);
851 const char *Loc
= Parent
->getData().begin() + Offset
;
852 Error Err
= Error::success();
853 Child
C(Parent
, Loc
, &Err
);
855 return std::move(Err
);
859 Archive::Symbol
Archive::Symbol::getNext() const {
861 if (Parent
->kind() == K_BSD
) {
862 // t.StringIndex is an offset from the start of the __.SYMDEF or
863 // "__.SYMDEF SORTED" member into the string table for the ranlib
864 // struct indexed by t.SymbolIndex . To change t.StringIndex to the
865 // offset in the string table for t.SymbolIndex+1 we subtract the
866 // its offset from the start of the string table for t.SymbolIndex
867 // and add the offset of the string table for t.SymbolIndex+1.
869 // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
870 // which is the number of bytes of ranlib structs that follow. The ranlib
871 // structs are a pair of uint32_t's the first being a string table offset
872 // and the second being the offset into the archive of the member that
873 // define the symbol. After that the next uint32_t is the byte count of
874 // the string table followed by the string table.
875 const char *Buf
= Parent
->getSymbolTable().begin();
876 uint32_t RanlibCount
= 0;
877 RanlibCount
= read32le(Buf
) / 8;
878 // If t.SymbolIndex + 1 will be past the count of symbols (the RanlibCount)
879 // don't change the t.StringIndex as we don't want to reference a ranlib
881 if (t
.SymbolIndex
+ 1 < RanlibCount
) {
882 const char *Ranlibs
= Buf
+ 4;
883 uint32_t CurRanStrx
= 0;
884 uint32_t NextRanStrx
= 0;
885 CurRanStrx
= read32le(Ranlibs
+ t
.SymbolIndex
* 8);
886 NextRanStrx
= read32le(Ranlibs
+ (t
.SymbolIndex
+ 1) * 8);
887 t
.StringIndex
-= CurRanStrx
;
888 t
.StringIndex
+= NextRanStrx
;
891 // Go to one past next null.
892 t
.StringIndex
= Parent
->getSymbolTable().find('\0', t
.StringIndex
) + 1;
898 Archive::symbol_iterator
Archive::symbol_begin() const {
899 if (!hasSymbolTable())
900 return symbol_iterator(Symbol(this, 0, 0));
902 const char *buf
= getSymbolTable().begin();
903 if (kind() == K_GNU
) {
904 uint32_t symbol_count
= 0;
905 symbol_count
= read32be(buf
);
906 buf
+= sizeof(uint32_t) + (symbol_count
* (sizeof(uint32_t)));
907 } else if (kind() == K_GNU64
) {
908 uint64_t symbol_count
= read64be(buf
);
909 buf
+= sizeof(uint64_t) + (symbol_count
* (sizeof(uint64_t)));
910 } else if (kind() == K_BSD
) {
911 // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
912 // which is the number of bytes of ranlib structs that follow. The ranlib
913 // structs are a pair of uint32_t's the first being a string table offset
914 // and the second being the offset into the archive of the member that
915 // define the symbol. After that the next uint32_t is the byte count of
916 // the string table followed by the string table.
917 uint32_t ranlib_count
= 0;
918 ranlib_count
= read32le(buf
) / 8;
919 const char *ranlibs
= buf
+ 4;
920 uint32_t ran_strx
= 0;
921 ran_strx
= read32le(ranlibs
);
922 buf
+= sizeof(uint32_t) + (ranlib_count
* (2 * (sizeof(uint32_t))));
923 // Skip the byte count of the string table.
924 buf
+= sizeof(uint32_t);
926 } else if (kind() == K_DARWIN64
) {
927 // The __.SYMDEF_64 or "__.SYMDEF_64 SORTED" member starts with a uint64_t
928 // which is the number of bytes of ranlib_64 structs that follow. The
929 // ranlib_64 structs are a pair of uint64_t's the first being a string
930 // table offset and the second being the offset into the archive of the
931 // member that define the symbol. After that the next uint64_t is the byte
932 // count of the string table followed by the string table.
933 uint64_t ranlib_count
= 0;
934 ranlib_count
= read64le(buf
) / 16;
935 const char *ranlibs
= buf
+ 8;
936 uint64_t ran_strx
= 0;
937 ran_strx
= read64le(ranlibs
);
938 buf
+= sizeof(uint64_t) + (ranlib_count
* (2 * (sizeof(uint64_t))));
939 // Skip the byte count of the string table.
940 buf
+= sizeof(uint64_t);
943 uint32_t member_count
= 0;
944 uint32_t symbol_count
= 0;
945 member_count
= read32le(buf
);
946 buf
+= 4 + (member_count
* 4); // Skip offsets.
947 symbol_count
= read32le(buf
);
948 buf
+= 4 + (symbol_count
* 2); // Skip indices.
950 uint32_t string_start_offset
= buf
- getSymbolTable().begin();
951 return symbol_iterator(Symbol(this, 0, string_start_offset
));
954 Archive::symbol_iterator
Archive::symbol_end() const {
955 return symbol_iterator(Symbol(this, getNumberOfSymbols(), 0));
958 uint32_t Archive::getNumberOfSymbols() const {
959 if (!hasSymbolTable())
961 const char *buf
= getSymbolTable().begin();
963 return read32be(buf
);
964 if (kind() == K_GNU64
)
965 return read64be(buf
);
967 return read32le(buf
) / 8;
968 if (kind() == K_DARWIN64
)
969 return read64le(buf
) / 16;
970 uint32_t member_count
= 0;
971 member_count
= read32le(buf
);
972 buf
+= 4 + (member_count
* 4); // Skip offsets.
973 return read32le(buf
);
976 Expected
<Optional
<Archive::Child
>> Archive::findSym(StringRef name
) const {
977 Archive::symbol_iterator bs
= symbol_begin();
978 Archive::symbol_iterator es
= symbol_end();
980 for (; bs
!= es
; ++bs
) {
981 StringRef SymName
= bs
->getName();
982 if (SymName
== name
) {
983 if (auto MemberOrErr
= bs
->getMember())
984 return Child(*MemberOrErr
);
986 return MemberOrErr
.takeError();
989 return Optional
<Child
>();
992 // Returns true if archive file contains no member file.
993 bool Archive::isEmpty() const { return Data
.getBufferSize() == 8; }
995 bool Archive::hasSymbolTable() const { return !SymbolTable
.empty(); }