Line data Source code
1 : //===- Archive.cpp - ar File Format implementation ------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the ArchiveObjectFile class.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "llvm/Object/Archive.h"
15 : #include "llvm/ADT/Optional.h"
16 : #include "llvm/ADT/SmallString.h"
17 : #include "llvm/ADT/StringRef.h"
18 : #include "llvm/ADT/Twine.h"
19 : #include "llvm/Object/Binary.h"
20 : #include "llvm/Object/Error.h"
21 : #include "llvm/Support/Chrono.h"
22 : #include "llvm/Support/Endian.h"
23 : #include "llvm/Support/Error.h"
24 : #include "llvm/Support/ErrorOr.h"
25 : #include "llvm/Support/FileSystem.h"
26 : #include "llvm/Support/MemoryBuffer.h"
27 : #include "llvm/Support/Path.h"
28 : #include "llvm/Support/raw_ostream.h"
29 : #include <algorithm>
30 : #include <cassert>
31 : #include <cstddef>
32 : #include <cstdint>
33 : #include <cstring>
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 : static const char *const Magic = "!<arch>\n";
43 : static const char *const ThinMagic = "!<thin>\n";
44 :
45 0 : void Archive::anchor() {}
46 :
47 : static Error
48 18 : malformedError(Twine Msg) {
49 36 : std::string StringMsg = "truncated or malformed archive (" + Msg.str() + ")";
50 : return make_error<GenericBinaryError>(std::move(StringMsg),
51 18 : object_error::parse_failed);
52 : }
53 :
54 3962 : ArchiveMemberHeader::ArchiveMemberHeader(const Archive *Parent,
55 : const char *RawHeaderPtr,
56 3962 : uint64_t Size, Error *Err)
57 : : Parent(Parent),
58 3962 : ArMemHdr(reinterpret_cast<const ArMemHdrType *>(RawHeaderPtr)) {
59 3962 : if (RawHeaderPtr == nullptr)
60 : return;
61 : ErrorAsOutParameter ErrAsOutParam(Err);
62 :
63 2672 : if (Size < sizeof(ArMemHdrType)) {
64 1 : if (Err) {
65 : std::string Msg("remaining size of archive too small for next archive "
66 1 : "member header ");
67 1 : Expected<StringRef> NameOrErr = getName(Size);
68 1 : if (!NameOrErr) {
69 0 : consumeError(NameOrErr.takeError());
70 0 : uint64_t Offset = RawHeaderPtr - Parent->getData().data();
71 0 : *Err = malformedError(Msg + "at offset " + Twine(Offset));
72 : } else
73 3 : *Err = malformedError(Msg + "for " + NameOrErr.get());
74 : }
75 1 : return;
76 : }
77 2671 : if (ArMemHdr->Terminator[0] != '`' || ArMemHdr->Terminator[1] != '\n') {
78 1 : if (Err) {
79 : std::string Buf;
80 1 : raw_string_ostream OS(Buf);
81 1 : OS.write_escaped(StringRef(ArMemHdr->Terminator,
82 1 : sizeof(ArMemHdr->Terminator)));
83 : OS.flush();
84 1 : std::string Msg("terminator characters in archive member \"" + Buf +
85 : "\" not the correct \"`\\n\" values for the archive "
86 1 : "member header ");
87 1 : Expected<StringRef> NameOrErr = getName(Size);
88 1 : if (!NameOrErr) {
89 0 : consumeError(NameOrErr.takeError());
90 0 : uint64_t Offset = RawHeaderPtr - Parent->getData().data();
91 0 : *Err = malformedError(Msg + "at offset " + Twine(Offset));
92 : } else
93 3 : *Err = malformedError(Msg + "for " + NameOrErr.get());
94 : }
95 1 : return;
96 : }
97 : }
98 :
99 : // This gets the raw name from the ArMemHdr->Name field and checks that it is
100 : // valid for the kind of archive. If it is not valid it returns an Error.
101 8856 : Expected<StringRef> ArchiveMemberHeader::getRawName() const {
102 : char EndCond;
103 8856 : auto Kind = Parent->kind();
104 8856 : if (Kind == Archive::K_BSD || Kind == Archive::K_DARWIN64) {
105 1207 : if (ArMemHdr->Name[0] == ' ') {
106 1 : uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
107 1 : Parent->getData().data();
108 1 : return malformedError("name contains a leading space for archive member "
109 1 : "header at offset " + Twine(Offset));
110 : }
111 : EndCond = ' ';
112 : }
113 7649 : else if (ArMemHdr->Name[0] == '/' || ArMemHdr->Name[0] == '#')
114 : EndCond = ' ';
115 : else
116 : EndCond = '/';
117 : StringRef::size_type end =
118 17710 : StringRef(ArMemHdr->Name, sizeof(ArMemHdr->Name)).find(EndCond);
119 8751 : if (end == StringRef::npos)
120 : end = sizeof(ArMemHdr->Name);
121 : assert(end <= sizeof(ArMemHdr->Name) && end > 0);
122 : // Don't include the EndCond if there is one.
123 : return StringRef(ArMemHdr->Name, end);
124 : }
125 :
126 : // This gets the name looking up long names. Size is the size of the archive
127 : // member including the header, so the size of any name following the header
128 : // is checked to make sure it does not overflow.
129 1626 : Expected<StringRef> ArchiveMemberHeader::getName(uint64_t Size) const {
130 :
131 : // This can be called from the ArchiveMemberHeader constructor when the
132 : // archive header is truncated to produce an error message with the name.
133 : // Make sure the name field is not truncated.
134 1626 : if (Size < offsetof(ArMemHdrType, Name) + sizeof(ArMemHdr->Name)) {
135 0 : uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
136 0 : Parent->getData().data();
137 0 : return malformedError("archive header truncated before the name field "
138 : "for archive member header at offset " +
139 0 : Twine(ArchiveOffset));
140 : }
141 :
142 : // The raw name itself can be invalid.
143 1626 : Expected<StringRef> NameOrErr = getRawName();
144 1626 : if (!NameOrErr)
145 : return NameOrErr.takeError();
146 1626 : StringRef Name = NameOrErr.get();
147 :
148 : // Check if it's a special name.
149 3252 : if (Name[0] == '/') {
150 687 : if (Name.size() == 1) // Linker member.
151 : return Name;
152 687 : if (Name.size() == 2 && Name[1] == '/') // String table.
153 : return Name;
154 : // It's a long name.
155 : // Get the string table offset.
156 : std::size_t StringOffset;
157 689 : if (Name.substr(1).rtrim(' ').getAsInteger(10, StringOffset)) {
158 : std::string Buf;
159 2 : raw_string_ostream OS(Buf);
160 2 : OS.write_escaped(Name.substr(1).rtrim(' '));
161 : OS.flush();
162 4 : uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
163 2 : Parent->getData().data();
164 2 : return malformedError("long name offset characters after the '/' are "
165 4 : "not all decimal numbers: '" + Buf + "' for "
166 : "archive member header at offset " +
167 2 : Twine(ArchiveOffset));
168 : }
169 :
170 : // Verify it.
171 685 : if (StringOffset >= Parent->getStringTable().size()) {
172 4 : uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
173 2 : Parent->getData().data();
174 2 : return malformedError("long name offset " + Twine(StringOffset) + " past "
175 : "the end of the string table for archive member "
176 2 : "header at offset " + Twine(ArchiveOffset));
177 : }
178 :
179 : // GNU long file names end with a "/\n".
180 683 : if (Parent->kind() == Archive::K_GNU ||
181 : Parent->kind() == Archive::K_GNU64) {
182 616 : size_t End = Parent->getStringTable().find('\n', /*From=*/StringOffset);
183 616 : if (End == StringRef::npos || End < 1 ||
184 : Parent->getStringTable()[End - 1] != '/') {
185 0 : return malformedError("string table at long name offset " +
186 0 : Twine(StringOffset) + "not terminated");
187 : }
188 1848 : return Parent->getStringTable().slice(StringOffset, End - 1);
189 : }
190 67 : return Parent->getStringTable().begin() + StringOffset;
191 : }
192 :
193 : if (Name.startswith("#1/")) {
194 : uint64_t NameLength;
195 477 : if (Name.substr(3).rtrim(' ').getAsInteger(10, NameLength)) {
196 : std::string Buf;
197 0 : raw_string_ostream OS(Buf);
198 0 : OS.write_escaped(Name.substr(3).rtrim(' '));
199 : OS.flush();
200 0 : uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
201 0 : Parent->getData().data();
202 0 : return malformedError("long name length characters after the #1/ are "
203 0 : "not all decimal numbers: '" + Buf + "' for "
204 : "archive member header at offset " +
205 0 : Twine(ArchiveOffset));
206 : }
207 477 : if (getSizeOf() + NameLength > Size) {
208 6 : uint64_t ArchiveOffset = reinterpret_cast<const char *>(ArMemHdr) -
209 3 : Parent->getData().data();
210 3 : return malformedError("long name length: " + Twine(NameLength) +
211 : " extends past the end of the member or archive "
212 3 : "for archive member header at offset " +
213 3 : Twine(ArchiveOffset));
214 : }
215 474 : return StringRef(reinterpret_cast<const char *>(ArMemHdr) + getSizeOf(),
216 474 : NameLength).rtrim('\0');
217 : }
218 :
219 : // It is not a long name so trim the blanks at the end of the name.
220 924 : if (Name[Name.size() - 1] != '/')
221 462 : return Name.rtrim(' ');
222 :
223 : // It's a simple name.
224 : return Name.drop_back(1);
225 : }
226 :
227 3975 : Expected<uint32_t> ArchiveMemberHeader::getSize() const {
228 : uint32_t Ret;
229 3975 : if (StringRef(ArMemHdr->Size,
230 7950 : sizeof(ArMemHdr->Size)).rtrim(" ").getAsInteger(10, Ret)) {
231 : std::string Buf;
232 2 : raw_string_ostream OS(Buf);
233 2 : OS.write_escaped(StringRef(ArMemHdr->Size,
234 2 : sizeof(ArMemHdr->Size)).rtrim(" "));
235 : OS.flush();
236 4 : uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
237 2 : Parent->getData().data();
238 2 : return malformedError("characters in size field in archive header are not "
239 4 : "all decimal numbers: '" + Buf + "' for archive "
240 2 : "member header at offset " + Twine(Offset));
241 : }
242 : return Ret;
243 : }
244 :
245 77 : Expected<sys::fs::perms> ArchiveMemberHeader::getAccessMode() const {
246 : unsigned Ret;
247 77 : if (StringRef(ArMemHdr->AccessMode,
248 154 : sizeof(ArMemHdr->AccessMode)).rtrim(' ').getAsInteger(8, Ret)) {
249 : std::string Buf;
250 1 : raw_string_ostream OS(Buf);
251 1 : OS.write_escaped(StringRef(ArMemHdr->AccessMode,
252 1 : sizeof(ArMemHdr->AccessMode)).rtrim(" "));
253 : OS.flush();
254 2 : uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
255 1 : Parent->getData().data();
256 1 : return malformedError("characters in AccessMode field in archive header "
257 2 : "are not all decimal numbers: '" + Buf + "' for the "
258 1 : "archive member header at offset " + Twine(Offset));
259 : }
260 : return static_cast<sys::fs::perms>(Ret);
261 : }
262 :
263 : Expected<sys::TimePoint<std::chrono::seconds>>
264 100 : ArchiveMemberHeader::getLastModified() const {
265 : unsigned Seconds;
266 100 : if (StringRef(ArMemHdr->LastModified,
267 100 : sizeof(ArMemHdr->LastModified)).rtrim(' ')
268 1 : .getAsInteger(10, Seconds)) {
269 : std::string Buf;
270 1 : raw_string_ostream OS(Buf);
271 1 : OS.write_escaped(StringRef(ArMemHdr->LastModified,
272 1 : sizeof(ArMemHdr->LastModified)).rtrim(" "));
273 : OS.flush();
274 2 : uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
275 1 : Parent->getData().data();
276 1 : return malformedError("characters in LastModified field in archive header "
277 2 : "are not all decimal numbers: '" + Buf + "' for the "
278 1 : "archive member header at offset " + Twine(Offset));
279 : }
280 :
281 99 : return sys::toTimePoint(Seconds);
282 : }
283 :
284 68 : Expected<unsigned> ArchiveMemberHeader::getUID() const {
285 : unsigned Ret;
286 136 : StringRef User = StringRef(ArMemHdr->UID, sizeof(ArMemHdr->UID)).rtrim(' ');
287 68 : if (User.empty())
288 : return 0;
289 67 : if (User.getAsInteger(10, Ret)) {
290 : std::string Buf;
291 1 : raw_string_ostream OS(Buf);
292 1 : OS.write_escaped(User);
293 : OS.flush();
294 2 : uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
295 1 : Parent->getData().data();
296 1 : return malformedError("characters in UID field in archive header "
297 2 : "are not all decimal numbers: '" + Buf + "' for the "
298 1 : "archive member header at offset " + Twine(Offset));
299 : }
300 : return Ret;
301 : }
302 :
303 67 : Expected<unsigned> ArchiveMemberHeader::getGID() const {
304 : unsigned Ret;
305 134 : StringRef Group = StringRef(ArMemHdr->GID, sizeof(ArMemHdr->GID)).rtrim(' ');
306 67 : if (Group.empty())
307 : return 0;
308 66 : if (Group.getAsInteger(10, Ret)) {
309 : std::string Buf;
310 1 : raw_string_ostream OS(Buf);
311 1 : OS.write_escaped(Group);
312 : OS.flush();
313 2 : uint64_t Offset = reinterpret_cast<const char *>(ArMemHdr) -
314 1 : Parent->getData().data();
315 1 : return malformedError("characters in GID field in archive header "
316 2 : "are not all decimal numbers: '" + Buf + "' for the "
317 1 : "archive member header at offset " + Twine(Offset));
318 : }
319 : return Ret;
320 : }
321 :
322 353 : Archive::Child::Child(const Archive *Parent, StringRef Data,
323 353 : uint16_t StartOfFile)
324 : : Parent(Parent), Header(Parent, Data.data(), Data.size(), nullptr),
325 706 : Data(Data), StartOfFile(StartOfFile) {
326 353 : }
327 :
328 3609 : Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
329 : : Parent(Parent),
330 : Header(Parent, Start,
331 : Parent
332 5929 : ? Parent->getData().size() - (Start - Parent->getData().data())
333 5929 : : 0, Err) {
334 3609 : if (!Start)
335 1295 : return;
336 :
337 : // If we are pointed to real data, Start is not a nullptr, then there must be
338 : // a non-null Err pointer available to report malformed data on. Only in
339 : // the case sentinel value is being constructed is Err is permitted to be a
340 : // nullptr.
341 : assert(Err && "Err can't be nullptr if Start is not a nullptr");
342 :
343 : ErrorAsOutParameter ErrAsOutParam(Err);
344 :
345 : // If there was an error in the construction of the Header
346 : // then just return with the error now set.
347 2320 : if (*Err)
348 : return;
349 :
350 : uint64_t Size = Header.getSizeOf();
351 2318 : Data = StringRef(Start, Size);
352 2318 : Expected<bool> isThinOrErr = isThinMember();
353 2318 : if (!isThinOrErr) {
354 : *Err = isThinOrErr.takeError();
355 1 : return;
356 : }
357 2317 : bool isThin = isThinOrErr.get();
358 2317 : if (!isThin) {
359 2274 : Expected<uint64_t> MemberSize = getRawSize();
360 2274 : if (!MemberSize) {
361 : *Err = MemberSize.takeError();
362 : return;
363 : }
364 2272 : Size += MemberSize.get();
365 2272 : Data = StringRef(Start, Size);
366 : }
367 :
368 : // Setup StartOfFile and PaddingBytes.
369 2315 : StartOfFile = Header.getSizeOf();
370 : // Don't include attached name.
371 : Expected<StringRef> NameOrErr = getRawName();
372 2315 : if (!NameOrErr){
373 : *Err = NameOrErr.takeError();
374 0 : return;
375 : }
376 2315 : StringRef Name = NameOrErr.get();
377 : if (Name.startswith("#1/")) {
378 : uint64_t NameSize;
379 368 : if (Name.substr(3).rtrim(' ').getAsInteger(10, NameSize)) {
380 : std::string Buf;
381 1 : raw_string_ostream OS(Buf);
382 1 : OS.write_escaped(Name.substr(3).rtrim(' '));
383 : OS.flush();
384 1 : uint64_t Offset = Start - Parent->getData().data();
385 1 : *Err = malformedError("long name length characters after the #1/ are "
386 2 : "not all decimal numbers: '" + Buf + "' for "
387 : "archive member header at offset " +
388 1 : Twine(Offset));
389 : return;
390 : }
391 366 : StartOfFile += NameSize;
392 : }
393 : }
394 :
395 1607 : Expected<uint64_t> Archive::Child::getSize() const {
396 1607 : if (Parent->IsThin) {
397 40 : Expected<uint32_t> Size = Header.getSize();
398 40 : if (!Size)
399 : return Size.takeError();
400 : return Size.get();
401 : }
402 1567 : return Data.size() - StartOfFile;
403 : }
404 :
405 3935 : Expected<uint64_t> Archive::Child::getRawSize() const {
406 3935 : return Header.getSize();
407 : }
408 :
409 3947 : Expected<bool> Archive::Child::isThinMember() const {
410 3947 : Expected<StringRef> NameOrErr = Header.getRawName();
411 3947 : if (!NameOrErr)
412 : return NameOrErr.takeError();
413 3946 : StringRef Name = NameOrErr.get();
414 3946 : return Parent->IsThin && Name != "/" && Name != "//";
415 : }
416 :
417 26 : Expected<std::string> Archive::Child::getFullName() const {
418 26 : Expected<bool> isThin = isThinMember();
419 26 : if (!isThin)
420 : return isThin.takeError();
421 : assert(isThin.get());
422 26 : Expected<StringRef> NameOrErr = getName();
423 26 : if (!NameOrErr)
424 : return NameOrErr.takeError();
425 26 : StringRef Name = *NameOrErr;
426 26 : if (sys::path::is_absolute(Name))
427 12 : return Name;
428 :
429 : SmallString<128> FullName = sys::path::parent_path(
430 28 : Parent->getMemoryBufferRef().getBufferIdentifier());
431 14 : sys::path::append(FullName, Name);
432 14 : return StringRef(FullName);
433 : }
434 :
435 1603 : Expected<StringRef> Archive::Child::getBuffer() const {
436 1603 : Expected<bool> isThinOrErr = isThinMember();
437 1603 : if (!isThinOrErr)
438 : return isThinOrErr.takeError();
439 1603 : bool isThin = isThinOrErr.get();
440 1603 : if (!isThin) {
441 1579 : Expected<uint32_t> Size = getSize();
442 1579 : if (!Size)
443 : return Size.takeError();
444 3158 : return StringRef(Data.data() + StartOfFile, Size.get());
445 : }
446 48 : Expected<std::string> FullNameOrErr = getFullName();
447 24 : if (!FullNameOrErr)
448 : return FullNameOrErr.takeError();
449 : const std::string &FullName = *FullNameOrErr;
450 24 : ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(FullName);
451 24 : if (std::error_code EC = Buf.getError())
452 1 : return errorCodeToError(EC);
453 23 : Parent->ThinBuffers.push_back(std::move(*Buf));
454 23 : return Parent->ThinBuffers.back()->getBuffer();
455 : }
456 :
457 1724 : Expected<Archive::Child> Archive::Child::getNext() const {
458 : size_t SpaceToSkip = Data.size();
459 : // If it's odd, add 1 to make it even.
460 1724 : if (SpaceToSkip & 1)
461 225 : ++SpaceToSkip;
462 :
463 1724 : const char *NextLoc = Data.data() + SpaceToSkip;
464 :
465 : // Check to see if this is at the end of the archive.
466 3448 : if (NextLoc == Parent->Data.getBufferEnd())
467 346 : return Child(nullptr, nullptr, nullptr);
468 :
469 : // Check to see if this is past the end of the archive.
470 1378 : if (NextLoc > Parent->Data.getBufferEnd()) {
471 : std::string Msg("offset to next archive member past the end of the archive "
472 1 : "after member ");
473 1 : Expected<StringRef> NameOrErr = getName();
474 1 : if (!NameOrErr) {
475 0 : consumeError(NameOrErr.takeError());
476 0 : uint64_t Offset = Data.data() - Parent->getData().data();
477 0 : return malformedError(Msg + "at offset " + Twine(Offset));
478 : } else
479 1 : return malformedError(Msg + NameOrErr.get());
480 : }
481 :
482 : Error Err = Error::success();
483 1377 : Child Ret(Parent, NextLoc, &Err);
484 1377 : if (Err)
485 : return std::move(Err);
486 : return Ret;
487 : }
488 :
489 336 : uint64_t Archive::Child::getChildOffset() const {
490 336 : const char *a = Parent->Data.getBuffer().data();
491 : const char *c = Data.data();
492 336 : uint64_t offset = c - a;
493 336 : return offset;
494 : }
495 :
496 1624 : Expected<StringRef> Archive::Child::getName() const {
497 1624 : Expected<uint64_t> RawSizeOrErr = getRawSize();
498 1624 : if (!RawSizeOrErr)
499 : return RawSizeOrErr.takeError();
500 1624 : uint64_t RawSize = RawSizeOrErr.get();
501 1624 : Expected<StringRef> NameOrErr = Header.getName(Header.getSizeOf() + RawSize);
502 1624 : if (!NameOrErr)
503 : return NameOrErr.takeError();
504 1617 : StringRef Name = NameOrErr.get();
505 : return Name;
506 : }
507 :
508 749 : Expected<MemoryBufferRef> Archive::Child::getMemoryBufferRef() const {
509 749 : Expected<StringRef> NameOrErr = getName();
510 749 : if (!NameOrErr)
511 : return NameOrErr.takeError();
512 746 : StringRef Name = NameOrErr.get();
513 746 : Expected<StringRef> Buf = getBuffer();
514 746 : if (!Buf)
515 : return Buf.takeError();
516 : return MemoryBufferRef(*Buf, Name);
517 : }
518 :
519 : Expected<std::unique_ptr<Binary>>
520 314 : Archive::Child::getAsBinary(LLVMContext *Context) const {
521 314 : Expected<MemoryBufferRef> BuffOrErr = getMemoryBufferRef();
522 314 : if (!BuffOrErr)
523 : return BuffOrErr.takeError();
524 :
525 622 : auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);
526 311 : if (BinaryOrErr)
527 : return std::move(*BinaryOrErr);
528 : return BinaryOrErr.takeError();
529 : }
530 :
531 439 : Expected<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) {
532 : Error Err = Error::success();
533 439 : std::unique_ptr<Archive> Ret(new Archive(Source, Err));
534 439 : if (Err)
535 : return std::move(Err);
536 : return std::move(Ret);
537 : }
538 :
539 555 : void Archive::setFirstRegular(const Child &C) {
540 555 : FirstRegularData = C.Data;
541 555 : FirstRegularStartOfFile = C.StartOfFile;
542 555 : }
543 :
544 565 : Archive::Archive(MemoryBufferRef Source, Error &Err)
545 565 : : Binary(Binary::ID_Archive, Source) {
546 : ErrorAsOutParameter ErrAsOutParam(&Err);
547 : StringRef Buffer = Data.getBuffer();
548 : // Check for sufficient magic.
549 : if (Buffer.startswith(ThinMagic)) {
550 20 : IsThin = true;
551 : } else if (Buffer.startswith(Magic)) {
552 544 : IsThin = false;
553 : } else {
554 : Err = make_error<GenericBinaryError>("File too small to be an archive",
555 : object_error::invalid_file_type);
556 1 : return;
557 : }
558 :
559 : // Make sure Format is initialized before any call to
560 : // ArchiveMemberHeader::getName() is made. This could be a valid empty
561 : // archive which is the same in all formats. So claiming it to be gnu to is
562 : // fine if not totally correct before we look for a string table or table of
563 : // contents.
564 564 : Format = K_GNU;
565 :
566 : // Get the special members.
567 564 : child_iterator I = child_begin(Err, false);
568 564 : if (Err)
569 : return;
570 561 : child_iterator E = child_end();
571 :
572 : // See if this is a valid empty archive and if so return.
573 561 : if (I == E) {
574 : Err = Error::success();
575 4 : return;
576 : }
577 557 : const Child *C = &*I;
578 :
579 : auto Increment = [&]() {
580 : ++I;
581 : if (Err)
582 : return true;
583 : C = &*I;
584 : return false;
585 557 : };
586 :
587 : Expected<StringRef> NameOrErr = C->getRawName();
588 557 : if (!NameOrErr) {
589 : Err = NameOrErr.takeError();
590 0 : return;
591 : }
592 557 : StringRef Name = NameOrErr.get();
593 :
594 : // Below is the pattern that is used to figure out the archive format
595 : // GNU archive format
596 : // First member : / (may exist, if it exists, points to the symbol table )
597 : // Second member : // (may exist, if it exists, points to the string table)
598 : // Note : The string table is used if the filename exceeds 15 characters
599 : // BSD archive format
600 : // First member : __.SYMDEF or "__.SYMDEF SORTED" (the symbol table)
601 : // There is no string table, if the filename exceeds 15 characters or has a
602 : // embedded space, the filename has #1/<size>, The size represents the size
603 : // of the filename that needs to be read after the archive header
604 : // COFF archive format
605 : // First member : /
606 : // Second member : / (provides a directory of symbols)
607 : // Third member : // (may exist, if it exists, contains the string table)
608 : // Note: Microsoft PE/COFF Spec 8.3 says that the third member is present
609 : // even if the string table is empty. However, lib.exe does not in fact
610 : // seem to create the third member if there's no member whose filename
611 : // exceeds 15 characters. So the third member is optional.
612 :
613 : if (Name == "__.SYMDEF" || Name == "__.SYMDEF_64") {
614 : if (Name == "__.SYMDEF")
615 0 : Format = K_BSD;
616 : else // Name == "__.SYMDEF_64"
617 0 : Format = K_DARWIN64;
618 : // We know that the symbol table is not an external file, but we still must
619 : // check any Expected<> return value.
620 0 : Expected<StringRef> BufOrErr = C->getBuffer();
621 0 : if (!BufOrErr) {
622 : Err = BufOrErr.takeError();
623 0 : return;
624 : }
625 0 : SymbolTable = BufOrErr.get();
626 0 : if (Increment())
627 : return;
628 0 : setFirstRegular(*C);
629 :
630 : Err = Error::success();
631 0 : return;
632 : }
633 :
634 : if (Name.startswith("#1/")) {
635 127 : Format = K_BSD;
636 : // We know this is BSD, so getName will work since there is no string table.
637 127 : Expected<StringRef> NameOrErr = C->getName();
638 127 : if (!NameOrErr) {
639 : Err = NameOrErr.takeError();
640 0 : return;
641 : }
642 127 : Name = NameOrErr.get();
643 : if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {
644 : // We know that the symbol table is not an external file, but we still
645 : // must check any Expected<> return value.
646 122 : Expected<StringRef> BufOrErr = C->getBuffer();
647 122 : if (!BufOrErr) {
648 : Err = BufOrErr.takeError();
649 0 : return;
650 : }
651 122 : SymbolTable = BufOrErr.get();
652 122 : if (Increment())
653 : return;
654 : }
655 : else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {
656 2 : Format = K_DARWIN64;
657 : // We know that the symbol table is not an external file, but we still
658 : // must check any Expected<> return value.
659 2 : Expected<StringRef> BufOrErr = C->getBuffer();
660 2 : if (!BufOrErr) {
661 : Err = BufOrErr.takeError();
662 0 : return;
663 : }
664 2 : SymbolTable = BufOrErr.get();
665 2 : if (Increment())
666 : return;
667 : }
668 126 : setFirstRegular(*C);
669 126 : return;
670 : }
671 :
672 : // MIPS 64-bit ELF archives use a special format of a symbol table.
673 : // This format is marked by `ar_name` field equals to "/SYM64/".
674 : // For detailed description see page 96 in the following document:
675 : // http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
676 :
677 : bool has64SymTable = false;
678 : if (Name == "/" || Name == "/SYM64/") {
679 : // We know that the symbol table is not an external file, but we still
680 : // must check any Expected<> return value.
681 360 : Expected<StringRef> BufOrErr = C->getBuffer();
682 360 : if (!BufOrErr) {
683 : Err = BufOrErr.takeError();
684 0 : return;
685 : }
686 360 : SymbolTable = BufOrErr.get();
687 : if (Name == "/SYM64/")
688 : has64SymTable = true;
689 :
690 360 : if (Increment())
691 : return;
692 360 : if (I == E) {
693 : Err = Error::success();
694 1 : return;
695 : }
696 359 : Expected<StringRef> NameOrErr = C->getRawName();
697 359 : if (!NameOrErr) {
698 : Err = NameOrErr.takeError();
699 : return;
700 : }
701 359 : Name = NameOrErr.get();
702 : }
703 :
704 : if (Name == "//") {
705 284 : Format = has64SymTable ? K_GNU64 : K_GNU;
706 : // The string table is never an external member, but we still
707 : // must check any Expected<> return value.
708 284 : Expected<StringRef> BufOrErr = C->getBuffer();
709 284 : if (!BufOrErr) {
710 : Err = BufOrErr.takeError();
711 0 : return;
712 : }
713 284 : StringTable = BufOrErr.get();
714 284 : if (Increment())
715 : return;
716 284 : setFirstRegular(*C);
717 : Err = Error::success();
718 284 : return;
719 : }
720 :
721 145 : if (Name[0] != '/') {
722 98 : Format = has64SymTable ? K_GNU64 : K_GNU;
723 98 : setFirstRegular(*C);
724 : Err = Error::success();
725 98 : return;
726 : }
727 :
728 : if (Name != "/") {
729 0 : Err = errorCodeToError(object_error::parse_failed);
730 0 : return;
731 : }
732 :
733 47 : Format = K_COFF;
734 : // We know that the symbol table is not an external file, but we still
735 : // must check any Expected<> return value.
736 47 : Expected<StringRef> BufOrErr = C->getBuffer();
737 47 : if (!BufOrErr) {
738 : Err = BufOrErr.takeError();
739 0 : return;
740 : }
741 47 : SymbolTable = BufOrErr.get();
742 :
743 47 : if (Increment())
744 : return;
745 :
746 47 : if (I == E) {
747 0 : setFirstRegular(*C);
748 : Err = Error::success();
749 0 : return;
750 : }
751 :
752 94 : NameOrErr = C->getRawName();
753 47 : if (!NameOrErr) {
754 : Err = NameOrErr.takeError();
755 0 : return;
756 : }
757 47 : Name = NameOrErr.get();
758 :
759 : if (Name == "//") {
760 : // The string table is never an external member, but we still
761 : // must check any Expected<> return value.
762 7 : Expected<StringRef> BufOrErr = C->getBuffer();
763 7 : if (!BufOrErr) {
764 : Err = BufOrErr.takeError();
765 0 : return;
766 : }
767 7 : StringTable = BufOrErr.get();
768 7 : if (Increment())
769 : return;
770 : }
771 :
772 47 : setFirstRegular(*C);
773 : Err = Error::success();
774 : }
775 :
776 933 : Archive::child_iterator Archive::child_begin(Error &Err,
777 : bool SkipInternal) const {
778 933 : if (isEmpty())
779 6 : return child_end();
780 :
781 927 : if (SkipInternal)
782 353 : return child_iterator(Child(this, FirstRegularData,
783 353 : FirstRegularStartOfFile),
784 : &Err);
785 :
786 574 : const char *Loc = Data.getBufferStart() + strlen(Magic);
787 574 : Child C(this, Loc, &Err);
788 574 : if (Err)
789 3 : return child_end();
790 : return child_iterator(C, &Err);
791 : }
792 :
793 943 : Archive::child_iterator Archive::child_end() const {
794 943 : return child_iterator(Child(nullptr, nullptr, nullptr), nullptr);
795 : }
796 :
797 1371 : StringRef Archive::Symbol::getName() const {
798 1371 : return Parent->getSymbolTable().begin() + StringIndex;
799 : }
800 :
801 369 : Expected<Archive::Child> Archive::Symbol::getMember() const {
802 369 : const char *Buf = Parent->getSymbolTable().begin();
803 : const char *Offsets = Buf;
804 369 : if (Parent->kind() == K_GNU64 || Parent->kind() == K_DARWIN64)
805 8 : Offsets += sizeof(uint64_t);
806 : else
807 361 : Offsets += sizeof(uint32_t);
808 : uint64_t Offset = 0;
809 369 : if (Parent->kind() == K_GNU) {
810 418 : Offset = read32be(Offsets + SymbolIndex * 4);
811 160 : } else if (Parent->kind() == K_GNU64) {
812 3 : Offset = read64be(Offsets + SymbolIndex * 8);
813 157 : } else if (Parent->kind() == K_BSD) {
814 : // The SymbolIndex is an index into the ranlib structs that start at
815 : // Offsets (the first uint32_t is the number of bytes of the ranlib
816 : // structs). The ranlib structs are a pair of uint32_t's the first
817 : // being a string table offset and the second being the offset into
818 : // the archive of the member that defines the symbol. Which is what
819 : // is needed here.
820 32 : Offset = read32le(Offsets + SymbolIndex * 8 + 4);
821 141 : } else if (Parent->kind() == K_DARWIN64) {
822 : // The SymbolIndex is an index into the ranlib_64 structs that start at
823 : // Offsets (the first uint64_t is the number of bytes of the ranlib_64
824 : // structs). The ranlib_64 structs are a pair of uint64_t's the first
825 : // being a string table offset and the second being the offset into
826 : // the archive of the member that defines the symbol. Which is what
827 : // is needed here.
828 5 : Offset = read64le(Offsets + SymbolIndex * 16 + 8);
829 : } else {
830 : // Skip offsets.
831 : uint32_t MemberCount = read32le(Buf);
832 136 : Buf += MemberCount * 4 + 4;
833 :
834 : uint32_t SymbolCount = read32le(Buf);
835 136 : if (SymbolIndex >= SymbolCount)
836 0 : return errorCodeToError(object_error::parse_failed);
837 :
838 : // Skip SymbolCount to get to the indices table.
839 : const char *Indices = Buf + 4;
840 :
841 : // Get the index of the offset in the file member offset table for this
842 : // symbol.
843 136 : uint16_t OffsetIndex = read16le(Indices + SymbolIndex * 2);
844 : // Subtract 1 since OffsetIndex is 1 based.
845 136 : --OffsetIndex;
846 :
847 136 : if (OffsetIndex >= MemberCount)
848 0 : return errorCodeToError(object_error::parse_failed);
849 :
850 272 : Offset = read32le(Offsets + OffsetIndex * 4);
851 : }
852 :
853 369 : const char *Loc = Parent->getData().begin() + Offset;
854 : Error Err = Error::success();
855 369 : Child C(Parent, Loc, &Err);
856 369 : if (Err)
857 : return std::move(Err);
858 : return C;
859 : }
860 :
861 807 : Archive::Symbol Archive::Symbol::getNext() const {
862 807 : Symbol t(*this);
863 807 : if (Parent->kind() == K_BSD) {
864 : // t.StringIndex is an offset from the start of the __.SYMDEF or
865 : // "__.SYMDEF SORTED" member into the string table for the ranlib
866 : // struct indexed by t.SymbolIndex . To change t.StringIndex to the
867 : // offset in the string table for t.SymbolIndex+1 we subtract the
868 : // its offset from the start of the string table for t.SymbolIndex
869 : // and add the offset of the string table for t.SymbolIndex+1.
870 :
871 : // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
872 : // which is the number of bytes of ranlib structs that follow. The ranlib
873 : // structs are a pair of uint32_t's the first being a string table offset
874 : // and the second being the offset into the archive of the member that
875 : // define the symbol. After that the next uint32_t is the byte count of
876 : // the string table followed by the string table.
877 : const char *Buf = Parent->getSymbolTable().begin();
878 : uint32_t RanlibCount = 0;
879 16 : RanlibCount = read32le(Buf) / 8;
880 : // If t.SymbolIndex + 1 will be past the count of symbols (the RanlibCount)
881 : // don't change the t.StringIndex as we don't want to reference a ranlib
882 : // past RanlibCount.
883 16 : if (t.SymbolIndex + 1 < RanlibCount) {
884 4 : const char *Ranlibs = Buf + 4;
885 : uint32_t CurRanStrx = 0;
886 : uint32_t NextRanStrx = 0;
887 4 : CurRanStrx = read32le(Ranlibs + t.SymbolIndex * 8);
888 4 : NextRanStrx = read32le(Ranlibs + (t.SymbolIndex + 1) * 8);
889 4 : t.StringIndex -= CurRanStrx;
890 4 : t.StringIndex += NextRanStrx;
891 : }
892 : } else {
893 : // Go to one past next null.
894 1582 : t.StringIndex = Parent->getSymbolTable().find('\0', t.StringIndex) + 1;
895 : }
896 807 : ++t.SymbolIndex;
897 807 : return t;
898 : }
899 :
900 240 : Archive::symbol_iterator Archive::symbol_begin() const {
901 240 : if (!hasSymbolTable())
902 7 : return symbol_iterator(Symbol(this, 0, 0));
903 :
904 : const char *buf = getSymbolTable().begin();
905 233 : if (kind() == K_GNU) {
906 : uint32_t symbol_count = 0;
907 : symbol_count = read32be(buf);
908 180 : buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
909 53 : } else if (kind() == K_GNU64) {
910 : uint64_t symbol_count = read64be(buf);
911 1 : buf += sizeof(uint64_t) + (symbol_count * (sizeof(uint64_t)));
912 52 : } else if (kind() == K_BSD) {
913 : // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
914 : // which is the number of bytes of ranlib structs that follow. The ranlib
915 : // structs are a pair of uint32_t's the first being a string table offset
916 : // and the second being the offset into the archive of the member that
917 : // define the symbol. After that the next uint32_t is the byte count of
918 : // the string table followed by the string table.
919 : uint32_t ranlib_count = 0;
920 12 : ranlib_count = read32le(buf) / 8;
921 : const char *ranlibs = buf + 4;
922 : uint32_t ran_strx = 0;
923 : ran_strx = read32le(ranlibs);
924 12 : buf += sizeof(uint32_t) + (ranlib_count * (2 * (sizeof(uint32_t))));
925 : // Skip the byte count of the string table.
926 : buf += sizeof(uint32_t);
927 12 : buf += ran_strx;
928 40 : } else if (kind() == K_DARWIN64) {
929 : // The __.SYMDEF_64 or "__.SYMDEF_64 SORTED" member starts with a uint64_t
930 : // which is the number of bytes of ranlib_64 structs that follow. The
931 : // ranlib_64 structs are a pair of uint64_t's the first being a string
932 : // table offset and the second being the offset into the archive of the
933 : // member that define the symbol. After that the next uint64_t is the byte
934 : // count of the string table followed by the string table.
935 : uint64_t ranlib_count = 0;
936 : ranlib_count = read64le(buf) / 16;
937 : const char *ranlibs = buf + 8;
938 : uint64_t ran_strx = 0;
939 : ran_strx = read64le(ranlibs);
940 2 : buf += sizeof(uint64_t) + (ranlib_count * (2 * (sizeof(uint64_t))));
941 : // Skip the byte count of the string table.
942 : buf += sizeof(uint64_t);
943 2 : buf += ran_strx;
944 : } else {
945 : uint32_t member_count = 0;
946 : uint32_t symbol_count = 0;
947 : member_count = read32le(buf);
948 38 : buf += 4 + (member_count * 4); // Skip offsets.
949 : symbol_count = read32le(buf);
950 38 : buf += 4 + (symbol_count * 2); // Skip indices.
951 : }
952 233 : uint32_t string_start_offset = buf - getSymbolTable().begin();
953 233 : return symbol_iterator(Symbol(this, 0, string_start_offset));
954 : }
955 :
956 240 : Archive::symbol_iterator Archive::symbol_end() const {
957 240 : return symbol_iterator(Symbol(this, getNumberOfSymbols(), 0));
958 : }
959 :
960 240 : uint32_t Archive::getNumberOfSymbols() const {
961 240 : if (!hasSymbolTable())
962 : return 0;
963 : const char *buf = getSymbolTable().begin();
964 233 : if (kind() == K_GNU)
965 180 : return read32be(buf);
966 53 : if (kind() == K_GNU64)
967 1 : return read64be(buf);
968 52 : if (kind() == K_BSD)
969 12 : return read32le(buf) / 8;
970 40 : if (kind() == K_DARWIN64)
971 2 : return read64le(buf) / 16;
972 : uint32_t member_count = 0;
973 : member_count = read32le(buf);
974 38 : buf += 4 + (member_count * 4); // Skip offsets.
975 38 : return read32le(buf);
976 : }
977 :
978 5 : Expected<Optional<Archive::Child>> Archive::findSym(StringRef name) const {
979 5 : Archive::symbol_iterator bs = symbol_begin();
980 5 : Archive::symbol_iterator es = symbol_end();
981 :
982 : for (; bs != es; ++bs) {
983 8 : StringRef SymName = bs->getName();
984 : if (SymName == name) {
985 4 : if (auto MemberOrErr = bs->getMember())
986 4 : return Child(*MemberOrErr);
987 : else
988 : return MemberOrErr.takeError();
989 : }
990 : }
991 : return Optional<Child>();
992 : }
993 :
994 : // Returns true if archive file contains no member file.
995 2080 : bool Archive::isEmpty() const { return Data.getBufferSize() == 8; }
996 :
997 1198 : bool Archive::hasSymbolTable() const { return !SymbolTable.empty(); }
|