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