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