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