LLVM  15.0.0git
Archive.cpp
Go to the documentation of this file.
1 //===- Archive.cpp - ar File Format implementation ------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the ArchiveObjectFile class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/Object/Archive.h"
14 #include "llvm/ADT/Optional.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/Object/Binary.h"
19 #include "llvm/Object/Error.h"
20 #include "llvm/Support/Chrono.h"
21 #include "llvm/Support/Endian.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/ErrorOr.h"
25 #include "llvm/Support/Host.h"
28 #include "llvm/Support/Path.h"
30 #include <algorithm>
31 #include <cassert>
32 #include <cstddef>
33 #include <cstdint>
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 void Archive::anchor() {}
43 
45  std::string StringMsg = "truncated or malformed archive (" + Msg.str() + ")";
46  return make_error<GenericBinaryError>(std::move(StringMsg),
48 }
49 
50 static Error
51 createMemberHeaderParseError(const AbstractArchiveMemberHeader *ArMemHeader,
52  const char *RawHeaderPtr, uint64_t Size) {
53  StringRef Msg("remaining size of archive too small for next archive "
54  "member header ");
55 
56  Expected<StringRef> NameOrErr = ArMemHeader->getName(Size);
57  if (NameOrErr)
58  return malformedError(Msg + "for " + *NameOrErr);
59 
60  consumeError(NameOrErr.takeError());
61  uint64_t Offset = RawHeaderPtr - ArMemHeader->Parent->getData().data();
62  return malformedError(Msg + "at offset " + Twine(Offset));
63 }
64 
65 template <class T, std::size_t N>
67  return StringRef(Field, N).rtrim(" ");
68 }
69 
70 template <class T>
72  return getFieldRawString(ArMemHdr->AccessMode);
73 }
74 
75 template <class T>
77  return getFieldRawString(ArMemHdr->LastModified);
78 }
79 
81  return getFieldRawString(ArMemHdr->UID);
82 }
83 
85  return getFieldRawString(ArMemHdr->GID);
86 }
87 
89  return reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
90 }
91 
94 
96  const char *RawHeaderPtr,
97  uint64_t Size, Error *Err)
99  Parent, reinterpret_cast<const UnixArMemHdrType *>(RawHeaderPtr)) {
100  if (RawHeaderPtr == nullptr)
101  return;
102  ErrorAsOutParameter ErrAsOutParam(Err);
103 
104  if (Size < getSizeOf()) {
105  *Err = createMemberHeaderParseError(this, RawHeaderPtr, Size);
106  return;
107  }
108  if (ArMemHdr->Terminator[0] != '`' || ArMemHdr->Terminator[1] != '\n') {
109  if (Err) {
110  std::string Buf;
111  raw_string_ostream OS(Buf);
112  OS.write_escaped(
114  OS.flush();
115  std::string Msg("terminator characters in archive member \"" + Buf +
116  "\" not the correct \"`\\n\" values for the archive "
117  "member header ");
118  Expected<StringRef> NameOrErr = getName(Size);
119  if (!NameOrErr) {
120  consumeError(NameOrErr.takeError());
121  uint64_t Offset = RawHeaderPtr - Parent->getData().data();
122  *Err = malformedError(Msg + "at offset " + Twine(Offset));
123  } else
124  *Err = malformedError(Msg + "for " + NameOrErr.get());
125  }
126  return;
127  }
128 }
129 
131  const char *RawHeaderPtr,
132  uint64_t Size, Error *Err)
134  Parent, reinterpret_cast<const BigArMemHdrType *>(RawHeaderPtr)) {
135  if (RawHeaderPtr == nullptr)
136  return;
137  ErrorAsOutParameter ErrAsOutParam(Err);
138 
139  if (Size < getSizeOf())
140  *Err = createMemberHeaderParseError(this, RawHeaderPtr, Size);
141 }
142 
143 // This gets the raw name from the ArMemHdr->Name field and checks that it is
144 // valid for the kind of archive. If it is not valid it returns an Error.
146  char EndCond;
147  auto Kind = Parent->kind();
149  if (ArMemHdr->Name[0] == ' ') {
150  uint64_t Offset =
151  reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
152  return malformedError("name contains a leading space for archive member "
153  "header at offset " +
154  Twine(Offset));
155  }
156  EndCond = ' ';
157  } else if (ArMemHdr->Name[0] == '/' || ArMemHdr->Name[0] == '#')
158  EndCond = ' ';
159  else
160  EndCond = '/';
162  StringRef(ArMemHdr->Name, sizeof(ArMemHdr->Name)).find(EndCond);
163  if (end == StringRef::npos)
164  end = sizeof(ArMemHdr->Name);
165  assert(end <= sizeof(ArMemHdr->Name) && end > 0);
166  // Don't include the EndCond if there is one.
167  return StringRef(ArMemHdr->Name, end);
168 }
169 
171 getArchiveMemberDecField(Twine FieldName, const StringRef RawField,
172  const Archive *Parent,
173  const AbstractArchiveMemberHeader *MemHeader) {
174  uint64_t Value;
175  if (RawField.getAsInteger(10, Value)) {
176  uint64_t Offset = MemHeader->getOffset();
177  return malformedError("characters in " + FieldName +
178  " field in archive member header are not "
179  "all decimal numbers: '" +
180  RawField +
181  "' for the archive "
182  "member header at offset " +
183  Twine(Offset));
184  }
185  return Value;
186 }
187 
189 getArchiveMemberOctField(Twine FieldName, const StringRef RawField,
190  const Archive *Parent,
191  const AbstractArchiveMemberHeader *MemHeader) {
192  uint64_t Value;
193  if (RawField.getAsInteger(8, Value)) {
194  uint64_t Offset = MemHeader->getOffset();
195  return malformedError("characters in " + FieldName +
196  " field in archive member header are not "
197  "all octal numbers: '" +
198  RawField +
199  "' for the archive "
200  "member header at offset " +
201  Twine(Offset));
202  }
203  return Value;
204 }
205 
208  "NameLen", getFieldRawString(ArMemHdr->NameLen), Parent, this);
209  if (!NameLenOrErr)
210  // TODO: Out-of-line.
211  return NameLenOrErr.takeError();
212  uint64_t NameLen = NameLenOrErr.get();
213 
214  // If the name length is odd, pad with '\0' to get an even length. After
215  // padding, there is the name terminator "`\n".
216  uint64_t NameLenWithPadding = alignTo(NameLen, 2);
217  StringRef NameTerminator = "`\n";
218  StringRef NameStringWithNameTerminator =
219  StringRef(ArMemHdr->Name, NameLenWithPadding + NameTerminator.size());
220  if (!NameStringWithNameTerminator.endswith(NameTerminator)) {
221  uint64_t Offset =
222  reinterpret_cast<const char *>(ArMemHdr->Name + NameLenWithPadding) -
223  Parent->getData().data();
224  // TODO: Out-of-line.
225  return malformedError(
226  "name does not have name terminator \"`\\n\" for archive member"
227  "header at offset " +
228  Twine(Offset));
229  }
230  return StringRef(ArMemHdr->Name, NameLen);
231 }
232 
233 // member including the header, so the size of any name following the header
234 // is checked to make sure it does not overflow.
236 
237  // This can be called from the ArchiveMemberHeader constructor when the
238  // archive header is truncated to produce an error message with the name.
239  // Make sure the name field is not truncated.
240  if (Size < offsetof(UnixArMemHdrType, Name) + sizeof(ArMemHdr->Name)) {
241  uint64_t ArchiveOffset =
242  reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
243  return malformedError("archive header truncated before the name field "
244  "for archive member header at offset " +
245  Twine(ArchiveOffset));
246  }
247 
248  // The raw name itself can be invalid.
249  Expected<StringRef> NameOrErr = getRawName();
250  if (!NameOrErr)
251  return NameOrErr.takeError();
252  StringRef Name = NameOrErr.get();
253 
254  // Check if it's a special name.
255  if (Name[0] == '/') {
256  if (Name.size() == 1) // Linker member.
257  return Name;
258  if (Name.size() == 2 && Name[1] == '/') // String table.
259  return Name;
260  // System libraries from the Windows SDK for Windows 11 contain this symbol.
261  // It looks like a CFG guard: we just skip it for now.
262  if (Name.equals("/<XFGHASHMAP>/"))
263  return Name;
264  // Some libraries (e.g., arm64rt.lib) from the Windows WDK
265  // (version 10.0.22000.0) contain this undocumented special member.
266  if (Name.equals("/<ECSYMBOLS>/"))
267  return Name;
268  // It's a long name.
269  // Get the string table offset.
270  std::size_t StringOffset;
271  if (Name.substr(1).rtrim(' ').getAsInteger(10, StringOffset)) {
272  std::string Buf;
273  raw_string_ostream OS(Buf);
274  OS.write_escaped(Name.substr(1).rtrim(' '));
275  OS.flush();
276  uint64_t ArchiveOffset =
277  reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
278  return malformedError("long name offset characters after the '/' are "
279  "not all decimal numbers: '" +
280  Buf + "' for archive member header at offset " +
281  Twine(ArchiveOffset));
282  }
283 
284  // Verify it.
285  if (StringOffset >= Parent->getStringTable().size()) {
286  uint64_t ArchiveOffset =
287  reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
288  return malformedError("long name offset " + Twine(StringOffset) +
289  " past the end of the string table for archive "
290  "member header at offset " +
291  Twine(ArchiveOffset));
292  }
293 
294  // GNU long file names end with a "/\n".
295  if (Parent->kind() == Archive::K_GNU ||
296  Parent->kind() == Archive::K_GNU64) {
297  size_t End = Parent->getStringTable().find('\n', /*From=*/StringOffset);
298  if (End == StringRef::npos || End < 1 ||
299  Parent->getStringTable()[End - 1] != '/') {
300  return malformedError("string table at long name offset " +
301  Twine(StringOffset) + "not terminated");
302  }
303  return Parent->getStringTable().slice(StringOffset, End - 1);
304  }
305  return Parent->getStringTable().begin() + StringOffset;
306  }
307 
308  if (Name.startswith("#1/")) {
310  if (Name.substr(3).rtrim(' ').getAsInteger(10, NameLength)) {
311  std::string Buf;
312  raw_string_ostream OS(Buf);
313  OS.write_escaped(Name.substr(3).rtrim(' '));
314  OS.flush();
315  uint64_t ArchiveOffset =
316  reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
317  return malformedError("long name length characters after the #1/ are "
318  "not all decimal numbers: '" +
319  Buf + "' for archive member header at offset " +
320  Twine(ArchiveOffset));
321  }
322  if (getSizeOf() + NameLength > Size) {
323  uint64_t ArchiveOffset =
324  reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
325  return malformedError("long name length: " + Twine(NameLength) +
326  " extends past the end of the member or archive "
327  "for archive member header at offset " +
328  Twine(ArchiveOffset));
329  }
330  return StringRef(reinterpret_cast<const char *>(ArMemHdr) + getSizeOf(),
331  NameLength)
332  .rtrim('\0');
333  }
334 
335  // It is not a long name so trim the blanks at the end of the name.
336  if (Name[Name.size() - 1] != '/')
337  return Name.rtrim(' ');
338 
339  // It's a simple name.
340  return Name.drop_back(1);
341 }
342 
344  return getRawName();
345 }
346 
349  Parent, this);
350 }
351 
354  "size", getFieldRawString(ArMemHdr->Size), Parent, this);
355  if (!SizeOrErr)
356  return SizeOrErr.takeError();
357 
358  Expected<uint64_t> NameLenOrErr = getRawNameSize();
359  if (!NameLenOrErr)
360  return NameLenOrErr.takeError();
361 
362  return *SizeOrErr + alignTo(*NameLenOrErr, 2);
363 }
364 
367  "NameLen", getFieldRawString(ArMemHdr->NameLen), Parent, this);
368 }
369 
372  "NextOffset", getFieldRawString(ArMemHdr->NextOffset), Parent, this);
373 }
374 
376  Expected<uint64_t> AccessModeOrErr =
377  getArchiveMemberOctField("AccessMode", getRawAccessMode(), Parent, this);
378  if (!AccessModeOrErr)
379  return AccessModeOrErr.takeError();
380  return static_cast<sys::fs::perms>(*AccessModeOrErr);
381 }
382 
386  "LastModified", getRawLastModified(), Parent, this);
387 
388  if (!SecondsOrErr)
389  return SecondsOrErr.takeError();
390 
391  return sys::toTimePoint(*SecondsOrErr);
392 }
393 
396  if (User.empty())
397  return 0;
398  return getArchiveMemberDecField("UID", User, Parent, this);
399 }
400 
402  StringRef Group = getRawGID();
403  if (Group.empty())
404  return 0;
405  return getArchiveMemberDecField("GID", Group, Parent, this);
406 }
407 
409  Expected<StringRef> NameOrErr = getRawName();
410  if (!NameOrErr)
411  return NameOrErr.takeError();
412  StringRef Name = NameOrErr.get();
413  return Parent->isThin() && Name != "/" && Name != "//" && Name != "/SYM64/";
414 }
415 
417  uint64_t Size = getSizeOf();
418  Expected<bool> isThinOrErr = isThin();
419  if (!isThinOrErr)
420  return isThinOrErr.takeError();
421 
422  bool isThin = isThinOrErr.get();
423  if (!isThin) {
424  Expected<uint64_t> MemberSize = getSize();
425  if (!MemberSize)
426  return MemberSize.takeError();
427 
428  Size += MemberSize.get();
429  }
430 
431  // If Size is odd, add 1 to make it even.
432  const char *NextLoc =
433  reinterpret_cast<const char *>(ArMemHdr) + alignTo(Size, 2);
434 
435  if (NextLoc == Parent->getMemoryBufferRef().getBufferEnd())
436  return nullptr;
437 
438  return NextLoc;
439 }
440 
442  if (getOffset() ==
443  static_cast<const BigArchive *>(Parent)->getLastChildOffset())
444  return nullptr;
445 
446  Expected<uint64_t> NextOffsetOrErr = getNextOffset();
447  if (!NextOffsetOrErr)
448  return NextOffsetOrErr.takeError();
449  return Parent->getData().data() + NextOffsetOrErr.get();
450 }
451 
453  uint16_t StartOfFile)
454  : Parent(Parent), Data(Data), StartOfFile(StartOfFile) {
455  Header = Parent->createArchiveMemberHeader(Data.data(), Data.size(), nullptr);
456 }
457 
458 Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
459  : Parent(Parent) {
460  if (!Start) {
461  Header = nullptr;
462  return;
463  }
464 
465  Header = Parent->createArchiveMemberHeader(
466  Start,
467  Parent ? Parent->getData().size() - (Start - Parent->getData().data())
468  : 0,
469  Err);
470 
471  // If we are pointed to real data, Start is not a nullptr, then there must be
472  // a non-null Err pointer available to report malformed data on. Only in
473  // the case sentinel value is being constructed is Err is permitted to be a
474  // nullptr.
475  assert(Err && "Err can't be nullptr if Start is not a nullptr");
476 
477  ErrorAsOutParameter ErrAsOutParam(Err);
478 
479  // If there was an error in the construction of the Header
480  // then just return with the error now set.
481  if (*Err)
482  return;
483 
484  uint64_t Size = Header->getSizeOf();
485  Data = StringRef(Start, Size);
486  Expected<bool> isThinOrErr = isThinMember();
487  if (!isThinOrErr) {
488  *Err = isThinOrErr.takeError();
489  return;
490  }
491  bool isThin = isThinOrErr.get();
492  if (!isThin) {
493  Expected<uint64_t> MemberSize = getRawSize();
494  if (!MemberSize) {
495  *Err = MemberSize.takeError();
496  return;
497  }
498  Size += MemberSize.get();
499  Data = StringRef(Start, Size);
500  }
501 
502  // Setup StartOfFile and PaddingBytes.
503  StartOfFile = Header->getSizeOf();
504  // Don't include attached name.
505  Expected<StringRef> NameOrErr = getRawName();
506  if (!NameOrErr) {
507  *Err = NameOrErr.takeError();
508  return;
509  }
510  StringRef Name = NameOrErr.get();
511 
512  if (Parent->kind() == Archive::K_AIXBIG) {
513  // The actual start of the file is after the name and any necessary
514  // even-alignment padding.
515  StartOfFile += ((Name.size() + 1) >> 1) << 1;
516  } else if (Name.startswith("#1/")) {
518  StringRef RawNameSize = Name.substr(3).rtrim(' ');
519  if (RawNameSize.getAsInteger(10, NameSize)) {
520  uint64_t Offset = Start - Parent->getData().data();
521  *Err = malformedError("long name length characters after the #1/ are "
522  "not all decimal numbers: '" +
523  RawNameSize +
524  "' for archive member header at offset " +
525  Twine(Offset));
526  return;
527  }
528  StartOfFile += NameSize;
529  }
530 }
531 
533  if (Parent->IsThin)
534  return Header->getSize();
535  return Data.size() - StartOfFile;
536 }
537 
539  return Header->getSize();
540 }
541 
542 Expected<bool> Archive::Child::isThinMember() const { return Header->isThin(); }
543 
545  Expected<bool> isThin = isThinMember();
546  if (!isThin)
547  return isThin.takeError();
548  assert(isThin.get());
549  Expected<StringRef> NameOrErr = getName();
550  if (!NameOrErr)
551  return NameOrErr.takeError();
552  StringRef Name = *NameOrErr;
554  return std::string(Name);
555 
557  Parent->getMemoryBufferRef().getBufferIdentifier());
558  sys::path::append(FullName, Name);
559  return std::string(FullName.str());
560 }
561 
563  Expected<bool> isThinOrErr = isThinMember();
564  if (!isThinOrErr)
565  return isThinOrErr.takeError();
566  bool isThin = isThinOrErr.get();
567  if (!isThin) {
568  Expected<uint64_t> Size = getSize();
569  if (!Size)
570  return Size.takeError();
571  return StringRef(Data.data() + StartOfFile, Size.get());
572  }
573  Expected<std::string> FullNameOrErr = getFullName();
574  if (!FullNameOrErr)
575  return FullNameOrErr.takeError();
576  const std::string &FullName = *FullNameOrErr;
578  if (std::error_code EC = Buf.getError())
579  return errorCodeToError(EC);
580  Parent->ThinBuffers.push_back(std::move(*Buf));
581  return Parent->ThinBuffers.back()->getBuffer();
582 }
583 
585  Expected<const char *> NextLocOrErr = Header->getNextChildLoc();
586  if (!NextLocOrErr)
587  return NextLocOrErr.takeError();
588 
589  const char *NextLoc = *NextLocOrErr;
590 
591  // Check to see if this is at the end of the archive.
592  if (NextLoc == nullptr)
593  return Child(nullptr, nullptr, nullptr);
594 
595  // Check to see if this is past the end of the archive.
596  if (NextLoc > Parent->Data.getBufferEnd()) {
597  std::string Msg("offset to next archive member past the end of the archive "
598  "after member ");
599  Expected<StringRef> NameOrErr = getName();
600  if (!NameOrErr) {
601  consumeError(NameOrErr.takeError());
602  uint64_t Offset = Data.data() - Parent->getData().data();
603  return malformedError(Msg + "at offset " + Twine(Offset));
604  } else
605  return malformedError(Msg + NameOrErr.get());
606  }
607 
608  Error Err = Error::success();
609  Child Ret(Parent, NextLoc, &Err);
610  if (Err)
611  return std::move(Err);
612  return Ret;
613 }
614 
616  const char *a = Parent->Data.getBuffer().data();
617  const char *c = Data.data();
618  uint64_t offset = c - a;
619  return offset;
620 }
621 
623  Expected<uint64_t> RawSizeOrErr = getRawSize();
624  if (!RawSizeOrErr)
625  return RawSizeOrErr.takeError();
626  uint64_t RawSize = RawSizeOrErr.get();
627  Expected<StringRef> NameOrErr =
628  Header->getName(Header->getSizeOf() + RawSize);
629  if (!NameOrErr)
630  return NameOrErr.takeError();
631  StringRef Name = NameOrErr.get();
632  return Name;
633 }
634 
636  Expected<StringRef> NameOrErr = getName();
637  if (!NameOrErr)
638  return NameOrErr.takeError();
639  StringRef Name = NameOrErr.get();
640  Expected<StringRef> Buf = getBuffer();
641  if (!Buf)
642  return createFileError(Name, Buf.takeError());
643  return MemoryBufferRef(*Buf, Name);
644 }
645 
649  if (!BuffOrErr)
650  return BuffOrErr.takeError();
651 
652  auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);
653  if (BinaryOrErr)
654  return std::move(*BinaryOrErr);
655  return BinaryOrErr.takeError();
656 }
657 
659  Error Err = Error::success();
660  std::unique_ptr<Archive> Ret;
661  StringRef Buffer = Source.getBuffer();
662 
663  if (Buffer.startswith(BigArchiveMagic))
664  Ret = std::make_unique<BigArchive>(Source, Err);
665  else
666  Ret = std::make_unique<Archive>(Source, Err);
667 
668  if (Err)
669  return std::move(Err);
670  return std::move(Ret);
671 }
672 
673 std::unique_ptr<AbstractArchiveMemberHeader>
674 Archive::createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size,
675  Error *Err) const {
676  ErrorAsOutParameter ErrAsOutParam(Err);
677  if (kind() != K_AIXBIG)
678  return std::make_unique<ArchiveMemberHeader>(this, RawHeaderPtr, Size, Err);
679  return std::make_unique<BigArchiveMemberHeader>(this, RawHeaderPtr, Size,
680  Err);
681 }
682 
684  if (isThin())
685  return sizeof(ThinArchiveMagic) - 1;
686 
687  if (Kind() == K_AIXBIG)
688  return sizeof(BigArchiveMagic) - 1;
689 
690  return sizeof(ArchiveMagic) - 1;
691 }
692 
694  FirstRegularData = C.Data;
695  FirstRegularStartOfFile = C.StartOfFile;
696 }
697 
700  ErrorAsOutParameter ErrAsOutParam(&Err);
701  StringRef Buffer = Data.getBuffer();
702  // Check for sufficient magic.
703  if (Buffer.startswith(ThinArchiveMagic)) {
704  IsThin = true;
705  } else if (Buffer.startswith(ArchiveMagic)) {
706  IsThin = false;
707  } else if (Buffer.startswith(BigArchiveMagic)) {
708  Format = K_AIXBIG;
709  IsThin = false;
710  return;
711  } else {
712  Err = make_error<GenericBinaryError>("file too small to be an archive",
714  return;
715  }
716 
717  // Make sure Format is initialized before any call to
718  // ArchiveMemberHeader::getName() is made. This could be a valid empty
719  // archive which is the same in all formats. So claiming it to be gnu to is
720  // fine if not totally correct before we look for a string table or table of
721  // contents.
722  Format = K_GNU;
723 
724  // Get the special members.
725  child_iterator I = child_begin(Err, false);
726  if (Err)
727  return;
729 
730  // See if this is a valid empty archive and if so return.
731  if (I == E) {
732  Err = Error::success();
733  return;
734  }
735  const Child *C = &*I;
736 
737  auto Increment = [&]() {
738  ++I;
739  if (Err)
740  return true;
741  C = &*I;
742  return false;
743  };
744 
745  Expected<StringRef> NameOrErr = C->getRawName();
746  if (!NameOrErr) {
747  Err = NameOrErr.takeError();
748  return;
749  }
750  StringRef Name = NameOrErr.get();
751 
752  // Below is the pattern that is used to figure out the archive format
753  // GNU archive format
754  // First member : / (may exist, if it exists, points to the symbol table )
755  // Second member : // (may exist, if it exists, points to the string table)
756  // Note : The string table is used if the filename exceeds 15 characters
757  // BSD archive format
758  // First member : __.SYMDEF or "__.SYMDEF SORTED" (the symbol table)
759  // There is no string table, if the filename exceeds 15 characters or has a
760  // embedded space, the filename has #1/<size>, The size represents the size
761  // of the filename that needs to be read after the archive header
762  // COFF archive format
763  // First member : /
764  // Second member : / (provides a directory of symbols)
765  // Third member : // (may exist, if it exists, contains the string table)
766  // Note: Microsoft PE/COFF Spec 8.3 says that the third member is present
767  // even if the string table is empty. However, lib.exe does not in fact
768  // seem to create the third member if there's no member whose filename
769  // exceeds 15 characters. So the third member is optional.
770 
771  if (Name == "__.SYMDEF" || Name == "__.SYMDEF_64") {
772  if (Name == "__.SYMDEF")
773  Format = K_BSD;
774  else // Name == "__.SYMDEF_64"
775  Format = K_DARWIN64;
776  // We know that the symbol table is not an external file, but we still must
777  // check any Expected<> return value.
778  Expected<StringRef> BufOrErr = C->getBuffer();
779  if (!BufOrErr) {
780  Err = BufOrErr.takeError();
781  return;
782  }
783  SymbolTable = BufOrErr.get();
784  if (Increment())
785  return;
786  setFirstRegular(*C);
787 
788  Err = Error::success();
789  return;
790  }
791 
792  if (Name.startswith("#1/")) {
793  Format = K_BSD;
794  // We know this is BSD, so getName will work since there is no string table.
795  Expected<StringRef> NameOrErr = C->getName();
796  if (!NameOrErr) {
797  Err = NameOrErr.takeError();
798  return;
799  }
800  Name = NameOrErr.get();
801  if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {
802  // We know that the symbol table is not an external file, but we still
803  // must check any Expected<> return value.
804  Expected<StringRef> BufOrErr = C->getBuffer();
805  if (!BufOrErr) {
806  Err = BufOrErr.takeError();
807  return;
808  }
809  SymbolTable = BufOrErr.get();
810  if (Increment())
811  return;
812  } else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {
813  Format = K_DARWIN64;
814  // We know that the symbol table is not an external file, but we still
815  // must check any Expected<> return value.
816  Expected<StringRef> BufOrErr = C->getBuffer();
817  if (!BufOrErr) {
818  Err = BufOrErr.takeError();
819  return;
820  }
821  SymbolTable = BufOrErr.get();
822  if (Increment())
823  return;
824  }
825  setFirstRegular(*C);
826  return;
827  }
828 
829  // MIPS 64-bit ELF archives use a special format of a symbol table.
830  // This format is marked by `ar_name` field equals to "/SYM64/".
831  // For detailed description see page 96 in the following document:
832  // http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
833 
834  bool has64SymTable = false;
835  if (Name == "/" || Name == "/SYM64/") {
836  // We know that the symbol table is not an external file, but we still
837  // must check any Expected<> return value.
838  Expected<StringRef> BufOrErr = C->getBuffer();
839  if (!BufOrErr) {
840  Err = BufOrErr.takeError();
841  return;
842  }
843  SymbolTable = BufOrErr.get();
844  if (Name == "/SYM64/")
845  has64SymTable = true;
846 
847  if (Increment())
848  return;
849  if (I == E) {
850  Err = Error::success();
851  return;
852  }
853  Expected<StringRef> NameOrErr = C->getRawName();
854  if (!NameOrErr) {
855  Err = NameOrErr.takeError();
856  return;
857  }
858  Name = NameOrErr.get();
859  }
860 
861  if (Name == "//") {
862  Format = has64SymTable ? K_GNU64 : K_GNU;
863  // The string table is never an external member, but we still
864  // must check any Expected<> return value.
865  Expected<StringRef> BufOrErr = C->getBuffer();
866  if (!BufOrErr) {
867  Err = BufOrErr.takeError();
868  return;
869  }
870  StringTable = BufOrErr.get();
871  if (Increment())
872  return;
873  setFirstRegular(*C);
874  Err = Error::success();
875  return;
876  }
877 
878  if (Name[0] != '/') {
879  Format = has64SymTable ? K_GNU64 : K_GNU;
880  setFirstRegular(*C);
881  Err = Error::success();
882  return;
883  }
884 
885  if (Name != "/") {
887  return;
888  }
889 
890  Format = K_COFF;
891  // We know that the symbol table is not an external file, but we still
892  // must check any Expected<> return value.
893  Expected<StringRef> BufOrErr = C->getBuffer();
894  if (!BufOrErr) {
895  Err = BufOrErr.takeError();
896  return;
897  }
898  SymbolTable = BufOrErr.get();
899 
900  if (Increment())
901  return;
902 
903  if (I == E) {
904  setFirstRegular(*C);
905  Err = Error::success();
906  return;
907  }
908 
909  NameOrErr = C->getRawName();
910  if (!NameOrErr) {
911  Err = NameOrErr.takeError();
912  return;
913  }
914  Name = NameOrErr.get();
915 
916  if (Name == "//") {
917  // The string table is never an external member, but we still
918  // must check any Expected<> return value.
919  Expected<StringRef> BufOrErr = C->getBuffer();
920  if (!BufOrErr) {
921  Err = BufOrErr.takeError();
922  return;
923  }
924  StringTable = BufOrErr.get();
925  if (Increment())
926  return;
927  }
928 
929  setFirstRegular(*C);
930  Err = Error::success();
931 }
932 
934  Triple HostTriple(sys::getProcessTriple());
935  return HostTriple.isOSDarwin()
937  : (HostTriple.isOSAIX() ? object::Archive::K_AIXBIG
939 }
940 
942  bool SkipInternal) const {
943  if (isEmpty())
944  return child_end();
945 
946  if (SkipInternal)
947  return child_iterator::itr(
948  Child(this, FirstRegularData, FirstRegularStartOfFile), Err);
949 
950  const char *Loc = Data.getBufferStart() + getFirstChildOffset();
951  Child C(this, Loc, &Err);
952  if (Err)
953  return child_end();
954  return child_iterator::itr(C, Err);
955 }
956 
958  return child_iterator::end(Child(nullptr, nullptr, nullptr));
959 }
960 
962  return Parent->getSymbolTable().begin() + StringIndex;
963 }
964 
966  const char *Buf = Parent->getSymbolTable().begin();
967  const char *Offsets = Buf;
968  if (Parent->kind() == K_GNU64 || Parent->kind() == K_DARWIN64)
969  Offsets += sizeof(uint64_t);
970  else
971  Offsets += sizeof(uint32_t);
972  uint64_t Offset = 0;
973  if (Parent->kind() == K_GNU) {
974  Offset = read32be(Offsets + SymbolIndex * 4);
975  } else if (Parent->kind() == K_GNU64) {
976  Offset = read64be(Offsets + SymbolIndex * 8);
977  } else if (Parent->kind() == K_BSD) {
978  // The SymbolIndex is an index into the ranlib structs that start at
979  // Offsets (the first uint32_t is the number of bytes of the ranlib
980  // structs). The ranlib structs are a pair of uint32_t's the first
981  // being a string table offset and the second being the offset into
982  // the archive of the member that defines the symbol. Which is what
983  // is needed here.
984  Offset = read32le(Offsets + SymbolIndex * 8 + 4);
985  } else if (Parent->kind() == K_DARWIN64) {
986  // The SymbolIndex is an index into the ranlib_64 structs that start at
987  // Offsets (the first uint64_t is the number of bytes of the ranlib_64
988  // structs). The ranlib_64 structs are a pair of uint64_t's the first
989  // being a string table offset and the second being the offset into
990  // the archive of the member that defines the symbol. Which is what
991  // is needed here.
992  Offset = read64le(Offsets + SymbolIndex * 16 + 8);
993  } else {
994  // Skip offsets.
995  uint32_t MemberCount = read32le(Buf);
996  Buf += MemberCount * 4 + 4;
997 
998  uint32_t SymbolCount = read32le(Buf);
999  if (SymbolIndex >= SymbolCount)
1001 
1002  // Skip SymbolCount to get to the indices table.
1003  const char *Indices = Buf + 4;
1004 
1005  // Get the index of the offset in the file member offset table for this
1006  // symbol.
1007  uint16_t OffsetIndex = read16le(Indices + SymbolIndex * 2);
1008  // Subtract 1 since OffsetIndex is 1 based.
1009  --OffsetIndex;
1010 
1011  if (OffsetIndex >= MemberCount)
1013 
1014  Offset = read32le(Offsets + OffsetIndex * 4);
1015  }
1016 
1017  const char *Loc = Parent->getData().begin() + Offset;
1018  Error Err = Error::success();
1019  Child C(Parent, Loc, &Err);
1020  if (Err)
1021  return std::move(Err);
1022  return C;
1023 }
1024 
1026  Symbol t(*this);
1027  if (Parent->kind() == K_BSD) {
1028  // t.StringIndex is an offset from the start of the __.SYMDEF or
1029  // "__.SYMDEF SORTED" member into the string table for the ranlib
1030  // struct indexed by t.SymbolIndex . To change t.StringIndex to the
1031  // offset in the string table for t.SymbolIndex+1 we subtract the
1032  // its offset from the start of the string table for t.SymbolIndex
1033  // and add the offset of the string table for t.SymbolIndex+1.
1034 
1035  // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
1036  // which is the number of bytes of ranlib structs that follow. The ranlib
1037  // structs are a pair of uint32_t's the first being a string table offset
1038  // and the second being the offset into the archive of the member that
1039  // define the symbol. After that the next uint32_t is the byte count of
1040  // the string table followed by the string table.
1041  const char *Buf = Parent->getSymbolTable().begin();
1042  uint32_t RanlibCount = 0;
1043  RanlibCount = read32le(Buf) / 8;
1044  // If t.SymbolIndex + 1 will be past the count of symbols (the RanlibCount)
1045  // don't change the t.StringIndex as we don't want to reference a ranlib
1046  // past RanlibCount.
1047  if (t.SymbolIndex + 1 < RanlibCount) {
1048  const char *Ranlibs = Buf + 4;
1049  uint32_t CurRanStrx = 0;
1050  uint32_t NextRanStrx = 0;
1051  CurRanStrx = read32le(Ranlibs + t.SymbolIndex * 8);
1052  NextRanStrx = read32le(Ranlibs + (t.SymbolIndex + 1) * 8);
1053  t.StringIndex -= CurRanStrx;
1054  t.StringIndex += NextRanStrx;
1055  }
1056  } else {
1057  // Go to one past next null.
1058  t.StringIndex = Parent->getSymbolTable().find('\0', t.StringIndex) + 1;
1059  }
1060  ++t.SymbolIndex;
1061  return t;
1062 }
1063 
1065  if (!hasSymbolTable())
1066  return symbol_iterator(Symbol(this, 0, 0));
1067 
1068  const char *buf = getSymbolTable().begin();
1069  if (kind() == K_GNU) {
1070  uint32_t symbol_count = 0;
1071  symbol_count = read32be(buf);
1072  buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
1073  } else if (kind() == K_GNU64) {
1074  uint64_t symbol_count = read64be(buf);
1075  buf += sizeof(uint64_t) + (symbol_count * (sizeof(uint64_t)));
1076  } else if (kind() == K_BSD) {
1077  // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
1078  // which is the number of bytes of ranlib structs that follow. The ranlib
1079  // structs are a pair of uint32_t's the first being a string table offset
1080  // and the second being the offset into the archive of the member that
1081  // define the symbol. After that the next uint32_t is the byte count of
1082  // the string table followed by the string table.
1083  uint32_t ranlib_count = 0;
1084  ranlib_count = read32le(buf) / 8;
1085  const char *ranlibs = buf + 4;
1086  uint32_t ran_strx = 0;
1087  ran_strx = read32le(ranlibs);
1088  buf += sizeof(uint32_t) + (ranlib_count * (2 * (sizeof(uint32_t))));
1089  // Skip the byte count of the string table.
1090  buf += sizeof(uint32_t);
1091  buf += ran_strx;
1092  } else if (kind() == K_DARWIN64) {
1093  // The __.SYMDEF_64 or "__.SYMDEF_64 SORTED" member starts with a uint64_t
1094  // which is the number of bytes of ranlib_64 structs that follow. The
1095  // ranlib_64 structs are a pair of uint64_t's the first being a string
1096  // table offset and the second being the offset into the archive of the
1097  // member that define the symbol. After that the next uint64_t is the byte
1098  // count of the string table followed by the string table.
1099  uint64_t ranlib_count = 0;
1100  ranlib_count = read64le(buf) / 16;
1101  const char *ranlibs = buf + 8;
1102  uint64_t ran_strx = 0;
1103  ran_strx = read64le(ranlibs);
1104  buf += sizeof(uint64_t) + (ranlib_count * (2 * (sizeof(uint64_t))));
1105  // Skip the byte count of the string table.
1106  buf += sizeof(uint64_t);
1107  buf += ran_strx;
1108  } else {
1109  uint32_t member_count = 0;
1110  uint32_t symbol_count = 0;
1111  member_count = read32le(buf);
1112  buf += 4 + (member_count * 4); // Skip offsets.
1113  symbol_count = read32le(buf);
1114  buf += 4 + (symbol_count * 2); // Skip indices.
1115  }
1116  uint32_t string_start_offset = buf - getSymbolTable().begin();
1117  return symbol_iterator(Symbol(this, 0, string_start_offset));
1118 }
1119 
1121  return symbol_iterator(Symbol(this, getNumberOfSymbols(), 0));
1122 }
1123 
1125  if (!hasSymbolTable())
1126  return 0;
1127  const char *buf = getSymbolTable().begin();
1128  if (kind() == K_GNU)
1129  return read32be(buf);
1130  if (kind() == K_GNU64)
1131  return read64be(buf);
1132  if (kind() == K_BSD)
1133  return read32le(buf) / 8;
1134  if (kind() == K_DARWIN64)
1135  return read64le(buf) / 16;
1136  uint32_t member_count = 0;
1137  member_count = read32le(buf);
1138  buf += 4 + (member_count * 4); // Skip offsets.
1139  return read32le(buf);
1140 }
1141 
1145 
1146  for (; bs != es; ++bs) {
1147  StringRef SymName = bs->getName();
1148  if (SymName == name) {
1149  if (auto MemberOrErr = bs->getMember())
1150  return Child(*MemberOrErr);
1151  else
1152  return MemberOrErr.takeError();
1153  }
1154  }
1155  return Optional<Child>();
1156 }
1157 
1158 // Returns true if archive file contains no member file.
1159 bool Archive::isEmpty() const {
1160  return Data.getBufferSize() == getArchiveMagicLen();
1161 }
1162 
1163 bool Archive::hasSymbolTable() const { return !SymbolTable.empty(); }
1164 
1166  : Archive(Source, Err) {
1167  ErrorAsOutParameter ErrAsOutParam(&Err);
1168  StringRef Buffer = Data.getBuffer();
1169  ArFixLenHdr = reinterpret_cast<const FixLenHdr *>(Buffer.data());
1170 
1172  if (RawOffset.getAsInteger(10, FirstChildOffset))
1173  // TODO: Out-of-line.
1174  Err = malformedError("malformed AIX big archive: first member offset \"" +
1175  RawOffset + "\" is not a number");
1176 
1178  if (RawOffset.getAsInteger(10, LastChildOffset))
1179  // TODO: Out-of-line.
1180  Err = malformedError("malformed AIX big archive: last member offset \"" +
1181  RawOffset + "\" is not a number");
1182 
1183  child_iterator I = child_begin(Err, false);
1184  if (Err)
1185  return;
1187  if (I == E) {
1188  Err = Error::success();
1189  return;
1190  }
1191  setFirstRegular(*I);
1192  Err = Error::success();
1193 }
llvm::object::CommonArchiveMemberHeader::getRawLastModified
StringRef getRawLastModified() const override
Definition: Archive.cpp:76
MemoryBuffer.h
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:156
llvm::object::Archive::K_GNU64
@ K_GNU64
Definition: Archive.h:339
llvm::object::CommonArchiveMemberHeader::getRawUID
StringRef getRawUID() const override
Definition: Archive.cpp:80
llvm::object::Archive::K_COFF
@ K_COFF
Definition: Archive.h:339
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:290
llvm::object::Archive::Kind
Kind
Definition: Archive.h:339
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm::MemoryBufferRef::getBufferStart
const char * getBufferStart() const
Definition: MemoryBufferRef.h:35
MathExtras.h
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::object::Archive::K_BSD
@ K_BSD
Definition: Archive.h:339
Optional.h
llvm::object::BigArMemHdrType::Name
char Name[2]
Definition: Archive.h:133
llvm::object::Archive::Child::getAsBinary
Expected< std::unique_ptr< Binary > > getAsBinary(LLVMContext *Context=nullptr) const
Definition: Archive.cpp:647
llvm::object::Archive::Child::getNext
Expected< Child > getNext() const
Definition: Archive.cpp:584
FileSystem.h
llvm::object::Archive::child_end
child_iterator child_end() const
Definition: Archive.cpp:957
llvm::object::Archive::Archive
Archive(MemoryBufferRef Source, Error &Err)
Definition: Archive.cpp:698
llvm::StringRef::rtrim
LLVM_NODISCARD StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:860
createMemberHeaderParseError
static Error createMemberHeaderParseError(const AbstractArchiveMemberHeader *ArMemHeader, const char *RawHeaderPtr, uint64_t Size)
Definition: Archive.cpp:51
llvm::object::Archive::Child::Child
Child(const Archive *Parent, const char *Start, Error *Err)
Definition: Archive.cpp:458
llvm::StringRef::endswith
LLVM_NODISCARD bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:301
T
StringRef.h
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:632
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:60
Host.h
offsetof
#define offsetof(TYPE, MEMBER)
Definition: AMDHSAKernelDescriptor.h:23
llvm::StringRef::find
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:319
llvm::support::endian::read16le
uint16_t read16le(const void *P)
Definition: Endian.h:380
Path.h
llvm::sys::path::is_absolute
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:671
llvm::object::Archive::setFirstRegular
void setFirstRegular(const Child &C)
Definition: Archive.cpp:693
llvm::object::Archive::Child::getFullName
Expected< std::string > getFullName() const
Definition: Archive.cpp:544
llvm::object::ArchiveMemberHeader::getRawName
Expected< StringRef > getRawName() const override
Get the name without looking up long names.
Definition: Archive.cpp:145
llvm::raw_ostream::write_escaped
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
Definition: raw_ostream.cpp:162
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::object::Archive::getStringTable
StringRef getStringTable() const
Definition: Archive.h:366
Error.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::object::Archive::K_GNU
@ K_GNU
Definition: Archive.h:339
llvm::object::AbstractArchiveMemberHeader::Parent
const Archive * Parent
Definition: Archive.h:76
llvm::object::Archive::getNumberOfSymbols
uint32_t getNumberOfSymbols() const
Definition: Archive.cpp:1124
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
llvm::Optional
Definition: APInt.h:33
llvm::object::Archive::symbol_begin
symbol_iterator symbol_begin() const
Definition: Archive.cpp:1064
llvm::MemoryBufferRef::getBufferSize
size_t getBufferSize() const
Definition: MemoryBufferRef.h:37
llvm::object::CommonArchiveMemberHeader::getRawGID
StringRef getRawGID() const override
Definition: Archive.cpp:84
llvm::object::BigArchiveMemberHeader::getRawNameSize
Expected< uint64_t > getRawNameSize() const
Definition: Archive.cpp:365
llvm::object::Archive::Symbol
Definition: Archive.h:292
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::support::endian::read32be
uint32_t read32be(const void *P)
Definition: Endian.h:384
llvm::StringRef::slice
LLVM_NODISCARD StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:736
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::support::endian::read64be
uint64_t read64be(const void *P)
Definition: Endian.h:385
size_t
llvm::object::Archive::Symbol::getName
StringRef getName() const
Definition: Archive.cpp:961
a
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
Definition: README.txt:489
llvm::object::Archive::symbol_iterator
Definition: Archive.h:310
Chrono.h
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::object::AbstractArchiveMemberHeader::getRawUID
virtual StringRef getRawUID() const =0
llvm::support::endian
Definition: Endian.h:42
llvm::object::CommonArchiveMemberHeader< UnixArMemHdrType >::getSizeOf
uint64_t getSizeOf() const override
Definition: Archive.h:90
llvm::object::ArchiveMagic
const char ArchiveMagic[]
Definition: Archive.h:36
llvm::MemoryBuffer::getFile
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Definition: MemoryBuffer.cpp:239
llvm::object::Archive
Definition: Archive.h:159
llvm::object::AbstractArchiveMemberHeader::getLastModified
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition: Archive.cpp:384
llvm::object::ThinArchiveMagic
const char ThinArchiveMagic[]
Definition: Archive.h:37
llvm::object::BigArchive::FixLenHdr::FirstChildOffset
char FirstChildOffset[20]
Offset to first archive member.
Definition: Archive.h:403
Error.h
llvm::object::Binary::getMemoryBufferRef
MemoryBufferRef getMemoryBufferRef() const
Definition: Binary.cpp:43
llvm::object::BigArchiveMemberHeader::getName
Expected< StringRef > getName(uint64_t Size) const override
Get the name looking up long names.
Definition: Archive.cpp:343
llvm::object::Archive::getArchiveMagicLen
uint64_t getArchiveMagicLen() const
Definition: Archive.cpp:683
SmallString.h
llvm::createFileError
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition: Error.h:1320
llvm::object::BigArchiveMagic
const char BigArchiveMagic[]
Definition: Archive.h:38
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::Triple::isOSDarwin
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or DriverKit).
Definition: Triple.h:508
llvm::object::Archive::isEmpty
virtual bool isEmpty() const
Definition: Archive.cpp:1159
llvm::User
Definition: User.h:44
llvm::COFF::NameSize
@ NameSize
Definition: COFF.h:57
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
Twine.h
llvm::object::BigArchive
Definition: Archive.h:394
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:90
t
bitcast float %x to i32 %s=and i32 %t, 2147483647 %d=bitcast i32 %s to float ret float %d } declare float @fabsf(float %n) define float @bar(float %x) nounwind { %d=call float @fabsf(float %x) ret float %d } This IR(from PR6194):target datalayout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple="x86_64-apple-darwin10.0.0" %0=type { double, double } %struct.float3=type { float, float, float } define void @test(%0, %struct.float3 *nocapture %res) nounwind noinline ssp { entry:%tmp18=extractvalue %0 %0, 0 t
Definition: README-SSE.txt:788
llvm::object::Archive::getFirstChildOffset
virtual uint64_t getFirstChildOffset() const
Definition: Archive.h:368
llvm::fallible_iterator::end
static fallible_iterator end(Underlying I)
Construct a fallible iterator that can be used as an end-of-range value.
Definition: fallible_iterator.h:94
llvm::object::UnixArMemHdrType
Definition: Archive.h:95
llvm::ErrorOr::getError
std::error_code getError() const
Definition: ErrorOr.h:153
llvm::object::AbstractArchiveMemberHeader::getGID
Expected< unsigned > getGID() const
Definition: Archive.cpp:401
getFieldRawString
StringRef getFieldRawString(const T(&Field)[N])
Definition: Archive.cpp:66
llvm::object::Archive::getSymbolTable
StringRef getSymbolTable() const
Definition: Archive.h:365
llvm::object::ArchiveMemberHeader::getSize
Expected< uint64_t > getSize() const override
Definition: Archive.cpp:347
llvm::object::Archive::Child::getBuffer
Expected< StringRef > getBuffer() const
Definition: Archive.cpp:562
llvm::object::CommonArchiveMemberHeader< UnixArMemHdrType >
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1097
llvm::raw_ostream::flush
void flush()
Definition: raw_ostream.h:187
llvm::object::BigArMemHdrType
Definition: Archive.h:123
llvm::object::object_error::parse_failed
@ parse_failed
llvm::object::object_error::invalid_file_type
@ invalid_file_type
llvm::object::Archive::isThin
bool isThin() const
Definition: Archive.h:342
llvm::Triple::isOSAIX
bool isOSAIX() const
Tests whether the OS is AIX.
Definition: Triple.h:651
c
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
Definition: README.txt:418
llvm::StringRef::getAsInteger
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:514
llvm::object::UnixArMemHdrType::Terminator
char Terminator[2]
Definition: Archive.h:102
llvm::object::Binary::ID_Archive
@ ID_Archive
Definition: Binary.h:42
llvm::SmallString< 128 >
llvm::object::Archive::Child::getRawName
Expected< StringRef > getRawName() const
Definition: Archive.h:228
llvm::fallible_iterator::itr
static fallible_iterator itr(Underlying I, Error &Err)
Construct a fallible iterator that cannot be used as an end-of-range value.
Definition: fallible_iterator.h:84
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::object::Archive::K_DARWIN64
@ K_DARWIN64
Definition: Archive.h:339
uint64_t
llvm::object::CommonArchiveMemberHeader::getOffset
uint64_t getOffset() const override
Definition: Archive.cpp:88
llvm::MemoryBufferRef::getBufferEnd
const char * getBufferEnd() const
Definition: MemoryBufferRef.h:36
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
malformedError
static Error malformedError(Twine Msg)
Definition: Archive.cpp:44
llvm::object::Archive::symbol_end
symbol_iterator symbol_end() const
Definition: Archive.cpp:1120
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::object::BigArchiveMemberHeader::getRawName
Expected< StringRef > getRawName() const override
Get the name without looking up long names.
Definition: Archive.cpp:206
ErrorOr.h
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::object::BigArchiveMemberHeader::getNextChildLoc
Expected< const char * > getNextChildLoc() const override
Get next file member location.
Definition: Archive.cpp:441
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::sys::path::parent_path
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
Definition: Path.cpp:467
llvm::object::BigArMemHdrType::NameLen
char NameLen[4]
Definition: Archive.h:131
llvm::object::Archive::hasSymbolTable
bool hasSymbolTable() const
Definition: Archive.cpp:1163
llvm::object::AbstractArchiveMemberHeader::getRawLastModified
virtual StringRef getRawLastModified() const =0
llvm::MemoryBufferRef::getBuffer
StringRef getBuffer() const
Definition: MemoryBufferRef.h:32
llvm::object::Archive::child_begin
child_iterator child_begin(Error &Err, bool SkipInternal=true) const
Definition: Archive.cpp:941
llvm::fallible_iterator
A wrapper class for fallible iterators.
Definition: fallible_iterator.h:68
llvm::object::UnixArMemHdrType::Size
char Size[10]
Size of data, not including header or padding.
Definition: Archive.h:101
llvm::object::Archive::Child::getRawSize
Expected< uint64_t > getRawSize() const
Definition: Archive.cpp:538
llvm::object::BigArchiveMemberHeader::getNextOffset
Expected< uint64_t > getNextOffset() const
Definition: Archive.cpp:370
llvm::object::Archive::Symbol::getMember
Expected< Child > getMember() const
Definition: Archive.cpp:965
llvm::object::Archive::findSym
Expected< Optional< Child > > findSym(StringRef name) const
Definition: Archive.cpp:1142
llvm::object::Archive::K_AIXBIG
@ K_AIXBIG
Definition: Archive.h:339
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:99
llvm::object::BigArchive::BigArchive
BigArchive(MemoryBufferRef Source, Error &Err)
Definition: Archive.cpp:1165
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::object::UnixArMemHdrType::Name
char Name[16]
Definition: Archive.h:96
llvm::object::Binary
Definition: Binary.h:32
llvm::object::BigArchive::FixLenHdr::LastChildOffset
char LastChildOffset[20]
Offset to last archive member.
Definition: Archive.h:404
getArchiveMemberDecField
Expected< uint64_t > getArchiveMemberDecField(Twine FieldName, const StringRef RawField, const Archive *Parent, const AbstractArchiveMemberHeader *MemHeader)
Definition: Archive.cpp:171
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition: Error.h:567
uint32_t
llvm::object::ArchiveMemberHeader::getNextChildLoc
Expected< const char * > getNextChildLoc() const override
Get next file member location.
Definition: Archive.cpp:416
llvm::object::Archive::Child::getName
Expected< StringRef > getName() const
Definition: Archive.cpp:622
Archive.h
llvm::object::BigArchive::FirstChildOffset
uint64_t FirstChildOffset
Definition: Archive.h:409
llvm::object::Archive::Child
Definition: Archive.h:163
llvm::object::BigArchive::ArFixLenHdr
const FixLenHdr * ArFixLenHdr
Definition: Archive.h:408
llvm::object::Archive::Symbol::getNext
Symbol getNext() const
Definition: Archive.cpp:1025
llvm::AMDGPU::SendMsg::Msg
const CustomOperand< const MCSubtargetInfo & > Msg[]
Definition: AMDGPUAsmUtils.cpp:39
llvm::object::ArchiveMemberHeader::ArchiveMemberHeader
ArchiveMemberHeader(const Archive *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err)
Definition: Archive.cpp:95
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:74
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::object::Archive::Child::getChildOffset
uint64_t getChildOffset() const
Definition: Archive.cpp:615
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
uint16_t
llvm::object::Archive::createArchiveMemberHeader
std::unique_ptr< AbstractArchiveMemberHeader > createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size, Error *Err) const
Definition: Archive.cpp:674
llvm::sys::getProcessTriple
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Host.cpp:1805
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::object::Archive::kind
Kind kind() const
Definition: Archive.h:341
llvm::object::BigArMemHdrType::Size
char Size[20]
Definition: Archive.h:124
llvm::object::AbstractArchiveMemberHeader::getUID
Expected< unsigned > getUID() const
Definition: Archive.cpp:394
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::object::BigArchive::FixLenHdr
Fixed-Length Header.
Definition: Archive.h:397
llvm::object::BigArchive::LastChildOffset
uint64_t LastChildOffset
Definition: Archive.h:410
llvm::object::ArchiveMemberHeader::isThin
Expected< bool > isThin() const override
Definition: Archive.cpp:408
llvm::SmallString::str
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:260
llvm::object::Archive::K_DARWIN
@ K_DARWIN
Definition: Archive.h:339
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::object::Archive::Child::getSize
Expected< uint64_t > getSize() const
Definition: Archive.cpp:532
llvm::object::BigArchiveMemberHeader::BigArchiveMemberHeader
BigArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err)
Definition: Archive.cpp:130
Binary.h
llvm::sys::fs::perms
perms
Definition: FileSystem.h:86
getArchiveMemberOctField
Expected< uint64_t > getArchiveMemberOctField(Twine FieldName, const StringRef RawField, const Archive *Parent, const AbstractArchiveMemberHeader *MemHeader)
Definition: Archive.cpp:189
llvm::support::endian::read64le
uint64_t read64le(const void *P)
Definition: Endian.h:382
llvm::object::Archive::getDefaultKindForHost
static object::Archive::Kind getDefaultKindForHost()
Definition: Archive.cpp:933
llvm::support::endian::read32le
uint32_t read32le(const void *P)
Definition: Endian.h:381
N
#define N
llvm::sys::toTimePoint
TimePoint< std::chrono::seconds > toTimePoint(std::time_t T)
Convert a std::time_t to a TimePoint.
Definition: Chrono.h:45
llvm::ARM::NameLength
size_t NameLength
Definition: ARMTargetParser.h:93
llvm::ErrorOr
Represents either an error or a value T.
Definition: ErrorOr.h:56
llvm::object::createBinary
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:45
llvm::object::BigArchiveMemberHeader::getSize
Expected< uint64_t > getSize() const override
Definition: Archive.cpp:352
llvm::object::CommonArchiveMemberHeader< UnixArMemHdrType >::ArMemHdr
const UnixArMemHdrType * ArMemHdr
Definition: Archive.h:92
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:149
llvm::object::Archive::Child::getMemoryBufferRef
Expected< MemoryBufferRef > getMemoryBufferRef() const
Definition: Archive.cpp:635
llvm::object::Binary::getData
StringRef getData() const
Definition: Binary.cpp:39
llvm::object::AbstractArchiveMemberHeader::getRawAccessMode
virtual StringRef getRawAccessMode() const =0
llvm::object::CommonArchiveMemberHeader::getRawAccessMode
StringRef getRawAccessMode() const override
Definition: Archive.cpp:71
llvm::OptimizedStructLayoutField
A field in a structure.
Definition: OptimizedStructLayout.h:45
llvm::object::BigArMemHdrType::NextOffset
char NextOffset[20]
Definition: Archive.h:125
llvm::object::ArchiveMemberHeader::getName
Expected< StringRef > getName(uint64_t Size) const override
Get the name looking up long names.
Definition: Archive.cpp:235
raw_ostream.h
llvm::SI::KernelInputOffsets::Offsets
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1312
Endian.h
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:128
llvm::object::Archive::create
static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)
Definition: Archive.cpp:658
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::object::AbstractArchiveMemberHeader::getAccessMode
Expected< sys::fs::perms > getAccessMode() const
Definition: Archive.cpp:375
llvm::object::AbstractArchiveMemberHeader::getRawGID
virtual StringRef getRawGID() const =0