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