Go to the documentation of this file.
36 #include <system_error>
42 void Archive::anchor() {}
45 std::string StringMsg =
"truncated or malformed archive (" +
Msg.str() +
")";
46 return make_error<GenericBinaryError>(
std::move(StringMsg),
52 const char *RawHeaderPtr,
uint64_t Size) {
53 StringRef Msg(
"remaining size of archive too small for next archive "
61 uint64_t Offset = RawHeaderPtr - ArMemHeader->Parent->getData().data();
65 template <
class T, std::
size_t N>
89 return reinterpret_cast<const char *
>(ArMemHdr) - Parent->getData().data();
96 const char *RawHeaderPtr,
100 if (RawHeaderPtr ==
nullptr)
115 std::string
Msg(
"terminator characters in archive member \"" + Buf +
116 "\" not the correct \"`\\n\" values for the archive "
131 const char *RawHeaderPtr,
135 if (RawHeaderPtr ==
nullptr)
152 return malformedError(
"name contains a leading space for archive member "
153 "header at offset " +
172 const Archive *Parent,
173 const AbstractArchiveMemberHeader *MemHeader) {
176 uint64_t Offset = MemHeader->getOffset();
178 " field in archive member header are not "
179 "all decimal numbers: '" +
182 "member header at offset " +
190 const Archive *Parent,
191 const AbstractArchiveMemberHeader *MemHeader) {
194 uint64_t Offset = MemHeader->getOffset();
196 " field in archive member header are not "
197 "all octal numbers: '" +
200 "member header at offset " +
220 if (!NameStringWithNameTerminator.
endswith(NameTerminator)) {
222 reinterpret_cast<const char *
>(
ArMemHdr->
Name + NameLenWithPadding) -
226 "name does not have name terminator \"`\\n\" for archive member"
227 "header at offset " +
243 return malformedError(
"archive header truncated before the name field "
244 "for archive member header at offset " +
245 Twine(ArchiveOffset));
255 if (
Name[0] ==
'/') {
256 if (
Name.size() == 1)
258 if (
Name.size() == 2 &&
Name[1] ==
'/')
262 if (
Name.equals(
"/<XFGHASHMAP>/"))
266 if (
Name.equals(
"/<ECSYMBOLS>/"))
270 std::size_t StringOffset;
271 if (
Name.substr(1).rtrim(
' ').getAsInteger(10, StringOffset)) {
278 return malformedError(
"long name offset characters after the '/' are "
279 "not all decimal numbers: '" +
280 Buf +
"' for archive member header at offset " +
281 Twine(ArchiveOffset));
289 " past the end of the string table for archive "
290 "member header at offset " +
291 Twine(ArchiveOffset));
301 Twine(StringOffset) +
"not terminated");
308 if (
Name.startswith(
"#1/")) {
317 return malformedError(
"long name length characters after the #1/ are "
318 "not all decimal numbers: '" +
319 Buf +
"' for archive member header at offset " +
320 Twine(ArchiveOffset));
326 " extends past the end of the member or archive "
327 "for archive member header at offset " +
328 Twine(ArchiveOffset));
337 return Name.rtrim(
' ');
340 return Name.drop_back(1);
362 return *SizeOrErr +
alignTo(*NameLenOrErr, 2);
378 if (!AccessModeOrErr)
428 Size += MemberSize.
get();
432 const char *NextLoc =
447 if (!NextOffsetOrErr)
454 : Parent(Parent),
Data(
Data), StartOfFile(StartOfFile) {
475 assert(Err &&
"Err can't be nullptr if Start is not a nullptr");
484 uint64_t Size = Header->getSizeOf();
498 Size += MemberSize.
get();
503 StartOfFile = Header->getSizeOf();
515 StartOfFile += ((
Name.size() + 1) >> 1) << 1;
516 }
else if (
Name.startswith(
"#1/")) {
521 *Err =
malformedError(
"long name length characters after the #1/ are "
522 "not all decimal numbers: '" +
524 "' for archive member header at offset " +
534 return Header->getSize();
535 return Data.size() - StartOfFile;
539 return Header->getSize();
542 Expected<bool> Archive::Child::isThinMember()
const {
return Header->isThin(); }
547 return isThin.takeError();
554 return std::string(
Name);
557 Parent->getMemoryBufferRef().getBufferIdentifier());
559 return std::string(FullName.
str());
570 return Size.takeError();
576 const std::string &FullName = *FullNameOrErr;
578 if (std::error_code EC = Buf.
getError())
580 Parent->ThinBuffers.push_back(
std::move(*Buf));
581 return Parent->ThinBuffers.back()->getBuffer();
589 const char *NextLoc = *NextLocOrErr;
592 if (NextLoc ==
nullptr)
593 return Child(
nullptr,
nullptr,
nullptr);
596 if (NextLoc > Parent->Data.getBufferEnd()) {
597 std::string
Msg(
"offset to next archive member past the end of the archive "
602 uint64_t Offset =
Data.data() - Parent->getData().data();
616 const char *
a = Parent->Data.getBuffer().data();
617 const char *
c =
Data.data();
628 Header->getName(Header->getSizeOf() + RawSize);
655 return BinaryOrErr.takeError();
660 std::unique_ptr<Archive>
Ret;
664 Ret = std::make_unique<BigArchive>(
Source, Err);
666 Ret = std::make_unique<Archive>(
Source, Err);
673 std::unique_ptr<AbstractArchiveMemberHeader>
678 return std::make_unique<ArchiveMemberHeader>(
this, RawHeaderPtr, Size, Err);
679 return std::make_unique<BigArchiveMemberHeader>(
this, RawHeaderPtr, Size,
694 FirstRegularData =
C.Data;
695 FirstRegularStartOfFile =
C.StartOfFile;
712 Err = make_error<GenericBinaryError>(
"file too small to be an archive",
737 auto Increment = [&]() {
771 if (
Name ==
"__.SYMDEF" ||
Name ==
"__.SYMDEF_64") {
772 if (
Name ==
"__.SYMDEF")
783 SymbolTable = BufOrErr.
get();
792 if (
Name.startswith(
"#1/")) {
801 if (
Name ==
"__.SYMDEF SORTED" ||
Name ==
"__.SYMDEF") {
809 SymbolTable = BufOrErr.
get();
812 }
else if (
Name ==
"__.SYMDEF_64 SORTED" ||
Name ==
"__.SYMDEF_64") {
821 SymbolTable = BufOrErr.
get();
834 bool has64SymTable =
false;
835 if (
Name ==
"/" ||
Name ==
"/SYM64/") {
843 SymbolTable = BufOrErr.
get();
844 if (
Name ==
"/SYM64/")
845 has64SymTable =
true;
870 StringTable = BufOrErr.
get();
878 if (
Name[0] !=
'/') {
898 SymbolTable = BufOrErr.
get();
909 NameOrErr =
C->getRawName();
924 StringTable = BufOrErr.
get();
942 bool SkipInternal)
const {
948 Child(
this, FirstRegularData, FirstRegularStartOfFile), Err);
966 const char *Buf = Parent->getSymbolTable().begin();
973 if (Parent->kind() ==
K_GNU) {
975 }
else if (Parent->kind() ==
K_GNU64) {
977 }
else if (Parent->kind() ==
K_BSD) {
996 Buf += MemberCount * 4 + 4;
999 if (SymbolIndex >= SymbolCount)
1003 const char *Indices = Buf + 4;
1011 if (OffsetIndex >= MemberCount)
1017 const char *Loc = Parent->getData().begin() + Offset;
1019 Child C(Parent, Loc, &Err);
1027 if (Parent->kind() ==
K_BSD) {
1041 const char *Buf = Parent->getSymbolTable().begin();
1047 if (
t.SymbolIndex + 1 < RanlibCount) {
1048 const char *Ranlibs = Buf + 4;
1051 CurRanStrx =
read32le(Ranlibs +
t.SymbolIndex * 8);
1052 NextRanStrx =
read32le(Ranlibs + (
t.SymbolIndex + 1) * 8);
1053 t.StringIndex -= CurRanStrx;
1054 t.StringIndex += NextRanStrx;
1058 t.StringIndex = Parent->getSymbolTable().find(
'\0',
t.StringIndex) + 1;
1085 const char *ranlibs = buf + 4;
1101 const char *ranlibs = buf + 8;
1112 buf += 4 + (member_count * 4);
1114 buf += 4 + (symbol_count * 2);
1138 buf += 4 + (member_count * 4);
1146 for (; bs != es; ++bs) {
1148 if (SymName ==
name) {
1150 return Child(*MemberOrErr);
1152 return MemberOrErr.takeError();
1174 Err =
malformedError(
"malformed AIX big archive: first member offset \"" +
1175 RawOffset +
"\" is not a number");
1180 Err =
malformedError(
"malformed AIX big archive: last member offset \"" +
1181 RawOffset +
"\" is not a number");
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static StringRef getName(Value *V)
const char * getBufferStart() const
This is an optimization pass for GlobalISel generic memory operations.
Expected< std::unique_ptr< Binary > > getAsBinary(LLVMContext *Context=nullptr) const
Expected< Child > getNext() const
child_iterator child_end() const
Archive(MemoryBufferRef Source, Error &Err)
LLVM_NODISCARD StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
static Error createMemberHeaderParseError(const AbstractArchiveMemberHeader *ArMemHeader, const char *RawHeaderPtr, uint64_t Size)
Child(const Archive *Parent, const char *Start, Error *Err)
LLVM_NODISCARD bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
A raw_ostream that writes to an std::string.
static constexpr size_t npos
#define offsetof(TYPE, MEMBER)
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
uint16_t read16le(const void *P)
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
void setFirstRegular(const Child &C)
Expected< std::string > getFullName() const
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
static ErrorSuccess success()
Create a success value.
StringRef getStringTable() const
Triple - Helper class for working with autoconf configuration names.
uint32_t getNumberOfSymbols() const
const_iterator end(StringRef path)
Get end iterator over path.
symbol_iterator symbol_begin() const
size_t getBufferSize() const
Tagged union holding either a T or a Error.
uint32_t read32be(const void *P)
LLVM_NODISCARD StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
void consumeError(Error Err)
Consume a Error without doing anything.
uint64_t read64be(const void *P)
StringRef getName() const
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
const char ArchiveMagic[]
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
const char ThinArchiveMagic[]
char FirstChildOffset[20]
Offset to first archive member.
MemoryBufferRef getMemoryBufferRef() const
uint64_t getArchiveMagicLen() const
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
const char BigArchiveMagic[]
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or DriverKit).
virtual bool isEmpty() const
(vector float) vec_cmpeq(*A, *B) C
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
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
virtual uint64_t getFirstChildOffset() const
static fallible_iterator end(Underlying I)
Construct a fallible iterator that can be used as an end-of-range value.
std::error_code getError() const
StringRef getFieldRawString(const T(&Field)[N])
StringRef getSymbolTable() const
Expected< StringRef > getBuffer() const
Helper for Errors used as out-parameters.
bool isOSAIX() const
Tests whether the OS is AIX.
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
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Expected< StringRef > getRawName() const
static fallible_iterator itr(Underlying I, Error &Err)
Construct a fallible iterator that cannot be used as an end-of-range value.
bar al al movzbl eax ret Missed when stored in a memory object
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
const char * getBufferEnd() const
static Error malformedError(Twine Msg)
symbol_iterator symbol_end() const
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
This is an important class for using LLVM in a threaded context.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
bool hasSymbolTable() const
StringRef getBuffer() const
child_iterator child_begin(Error &Err, bool SkipInternal=true) const
A wrapper class for fallible iterators.
char Size[10]
Size of data, not including header or padding.
Expected< uint64_t > getRawSize() const
Expected< Child > getMember() const
Expected< Optional< Child > > findSym(StringRef name) const
BigArchive(MemoryBufferRef Source, Error &Err)
StringRef - Represent a constant reference to a string, i.e.
char LastChildOffset[20]
Offset to last archive member.
Expected< uint64_t > getArchiveMemberDecField(Twine FieldName, const StringRef RawField, const Archive *Parent, const AbstractArchiveMemberHeader *MemHeader)
reference get()
Returns a reference to the stored T value.
Expected< StringRef > getName() const
uint64_t FirstChildOffset
const FixLenHdr * ArFixLenHdr
const CustomOperand< const MCSubtargetInfo & > Msg[]
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
uint64_t getChildOffset() const
std::unique_ptr< AbstractArchiveMemberHeader > createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size, Error *Err) const
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Lightweight error class with error context and mandatory checking.
StringRef str() const
Explicit conversion to StringRef.
Error takeError()
Take ownership of the stored error.
Expected< uint64_t > getSize() const
Expected< uint64_t > getArchiveMemberOctField(Twine FieldName, const StringRef RawField, const Archive *Parent, const AbstractArchiveMemberHeader *MemHeader)
uint64_t read64le(const void *P)
static object::Archive::Kind getDefaultKindForHost()
uint32_t read32le(const void *P)
TimePoint< std::chrono::seconds > toTimePoint(std::time_t T)
Convert a std::time_t to a TimePoint.
Represents either an error or a value T.
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Expected< MemoryBufferRef > getMemoryBufferRef() const
StringRef getData() const
static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)
LLVM Value Representation.