LLVM 23.0.0git
Archive.h
Go to the documentation of this file.
1//===- Archive.h - ar archive file format -----------------------*- C++ -*-===//
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 declares the ar archive file format class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_OBJECT_ARCHIVE_H
14#define LLVM_OBJECT_ARCHIVE_H
15
16#include "llvm/ADT/StringRef.h"
19#include "llvm/Object/Binary.h"
20#include "llvm/Support/Chrono.h"
22#include "llvm/Support/Error.h"
25#include <cassert>
26#include <cstdint>
27#include <memory>
28#include <string>
29#include <vector>
30
31namespace llvm {
32namespace object {
33
34const char ArchiveMagic[] = "!<arch>\n";
35const char ThinArchiveMagic[] = "!<thin>\n";
36const char BigArchiveMagic[] = "<bigaf>\n";
37const char ZOSArchiveMagic[] =
38 "\x5A\x4C\x81\x99\x83\x88\x6E\x15"; // "!<arch>\n" in EBCDIC
39
40class Archive;
41
43protected:
45
46public:
47 friend class Archive;
48 virtual std::unique_ptr<AbstractArchiveMemberHeader> clone() const = 0;
49 virtual ~AbstractArchiveMemberHeader() = default;
50
51 /// Get the name without looking up long names.
52 virtual Expected<StringRef> getRawName() const = 0;
53 virtual StringRef getRawAccessMode() const = 0;
54 virtual StringRef getRawLastModified() const = 0;
55 virtual StringRef getRawUID() const = 0;
56 virtual StringRef getRawGID() const = 0;
57
58 /// Get the name looking up long names.
60 virtual Expected<uint64_t> getSize() const = 0;
61 virtual uint64_t getOffset() const = 0;
62
63 /// Get next file member location.
65 virtual Expected<bool> isThin() const = 0;
66
69 getLastModified() const;
72
73 /// Returns the size in bytes of the format-defined member header of the
74 /// concrete archive type.
75 virtual uint64_t getSizeOf() const = 0;
76
78};
79
80template <typename T>
82public:
83 CommonArchiveMemberHeader(const Archive *Parent, const T *RawHeaderPtr)
85 StringRef getRawAccessMode() const override;
86 StringRef getRawLastModified() const override;
87 StringRef getRawUID() const override;
88 StringRef getRawGID() const override;
89
90 uint64_t getOffset() const override;
91 uint64_t getSizeOf() const override { return sizeof(T); }
92
93 T const *ArMemHdr;
94};
95
97 char Name[16];
98 char LastModified[12];
99 char UID[6];
100 char GID[6];
101 char AccessMode[8];
102 char Size[10]; ///< Size of data, not including header or padding.
103 char Terminator[2];
104};
105
107 : public CommonArchiveMemberHeader<UnixArMemHdrType> {
108public:
109 ArchiveMemberHeader(const Archive *Parent, const char *RawHeaderPtr,
110 uint64_t Size, Error *Err);
111
112 std::unique_ptr<AbstractArchiveMemberHeader> clone() const override {
113 return std::make_unique<ArchiveMemberHeader>(*this);
114 }
115
116 Expected<StringRef> getRawName() const override;
117
119 Expected<uint64_t> getSize() const override;
120 Expected<const char *> getNextChildLoc() const override;
121 Expected<bool> isThin() const override;
122};
123
124// File Member Header
126 char Size[20]; // File member size in decimal
127 char NextOffset[20]; // Next member offset in decimal
128 char PrevOffset[20]; // Previous member offset in decimal
129 char LastModified[12];
130 char UID[12];
131 char GID[12];
132 char AccessMode[12];
133 char NameLen[4]; // File member name length in decimal
134 union {
135 char Name[2]; // Start of member name
136 char Terminator[2];
137 };
138};
139
140// Define file member header of AIX big archive.
142 : public CommonArchiveMemberHeader<BigArMemHdrType> {
143
144public:
145 BigArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr,
146 uint64_t Size, Error *Err);
147 std::unique_ptr<AbstractArchiveMemberHeader> clone() const override {
148 return std::make_unique<BigArchiveMemberHeader>(*this);
149 }
150
151 Expected<StringRef> getRawName() const override;
152 Expected<uint64_t> getRawNameSize() const;
153
155 Expected<uint64_t> getSize() const override;
156 Expected<const char *> getNextChildLoc() const override;
157 Expected<uint64_t> getNextOffset() const;
158 Expected<bool> isThin() const override { return false; }
159};
160
161class LLVM_ABI Archive : public Binary {
162 virtual void anchor();
163
164public:
165 class Child {
166 friend Archive;
167 friend AbstractArchiveMemberHeader;
168
169 const Archive *Parent;
170 std::unique_ptr<AbstractArchiveMemberHeader> Header;
171 /// Includes header but not padding byte.
172 StringRef Data;
173 /// Offset from Data to the start of the file.
174 uint16_t StartOfFile;
175
176 Expected<bool> isThinMember() const;
177
178 public:
179 LLVM_ABI Child(const Archive *Parent, const char *Start, Error *Err);
180 LLVM_ABI Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
181
182 Child(const Child &C)
183 : Parent(C.Parent), Data(C.Data), StartOfFile(C.StartOfFile) {
184 if (C.Header)
185 Header = C.Header->clone();
186 }
187
189 Parent = std::move(C.Parent);
190 Header = std::move(C.Header);
191 Data = C.Data;
192 StartOfFile = C.StartOfFile;
193 }
194
195 Child &operator=(Child &&C) noexcept {
196 if (&C == this)
197 return *this;
198
199 Parent = std::move(C.Parent);
200 Header = std::move(C.Header);
201 Data = C.Data;
202 StartOfFile = C.StartOfFile;
203
204 return *this;
205 }
206
208 if (&C == this)
209 return *this;
210
211 Parent = C.Parent;
212 if (C.Header)
213 Header = C.Header->clone();
214 Data = C.Data;
215 StartOfFile = C.StartOfFile;
216
217 return *this;
218 }
219
220 bool operator==(const Child &other) const {
221 assert(!Parent || !other.Parent || Parent == other.Parent);
222 return Data.begin() == other.Data.begin();
223 }
224
225 const Archive *getParent() const { return Parent; }
226 LLVM_ABI Expected<Child> getNext() const;
227
229 LLVM_ABI Expected<std::string> getFullName() const;
230 Expected<StringRef> getRawName() const { return Header->getRawName(); }
231
233 return Header->getLastModified();
234 }
235
237 return Header->getRawLastModified();
238 }
239
240 Expected<unsigned> getUID() const { return Header->getUID(); }
241 Expected<unsigned> getGID() const { return Header->getGID(); }
242
244 return Header->getAccessMode();
245 }
246
247 /// \return the size of the archive member without the header or padding.
249 /// \return the size in the archive header for this member.
250 LLVM_ABI Expected<uint64_t> getRawSize() const;
251
252 LLVM_ABI Expected<StringRef> getBuffer() const;
253 LLVM_ABI uint64_t getChildOffset() const;
254 uint64_t getDataOffset() const { return getChildOffset() + StartOfFile; }
255
257
259 getAsBinary(LLVMContext *Context = nullptr) const;
260 };
261
263 Child C;
264
265 public:
266 ChildFallibleIterator() : C(Child(nullptr, nullptr, nullptr)) {}
267 ChildFallibleIterator(const Child &C) : C(C) {}
268
269 const Child *operator->() const { return &C; }
270 const Child &operator*() const { return C; }
271
272 bool operator==(const ChildFallibleIterator &other) const {
273 // Ignore errors here: If an error occurred during increment then getNext
274 // will have been set to child_end(), and the following comparison should
275 // do the right thing.
276 return C == other.C;
277 }
278
279 bool operator!=(const ChildFallibleIterator &other) const {
280 return !(*this == other);
281 }
282
284 auto NextChild = C.getNext();
285 if (!NextChild)
286 return NextChild.takeError();
287 C = std::move(*NextChild);
288 return Error::success();
289 }
290 };
291
293
294 class Symbol {
295 const Archive *Parent;
296 uint32_t SymbolIndex;
297 uint32_t StringIndex; // Extra index to the string.
298
299 public:
300 Symbol(const Archive *p, uint32_t symi, uint32_t stri)
301 : Parent(p), SymbolIndex(symi), StringIndex(stri) {}
302
303 bool operator==(const Symbol &other) const {
304 return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
305 }
306
307 LLVM_ABI StringRef getName() const;
308 LLVM_ABI Expected<Child> getMember() const;
309 LLVM_ABI Symbol getNext() const;
310 LLVM_ABI bool isECSymbol() const;
311 };
312
314 Symbol symbol;
315
316 public:
317 symbol_iterator(const Symbol &s) : symbol(s) {}
318
319 const Symbol *operator->() const { return &symbol; }
320 const Symbol &operator*() const { return symbol; }
321
322 bool operator==(const symbol_iterator &other) const {
323 return symbol == other.symbol;
324 }
325
326 bool operator!=(const symbol_iterator &other) const {
327 return !(*this == other);
328 }
329
330 symbol_iterator &operator++() { // Preincrement
331 symbol = symbol.getNext();
332 return *this;
333 }
334 };
335
336 Archive(MemoryBufferRef Source, Error &Err);
338
339 // Explicitly non-copyable.
340 Archive(Archive const &) = delete;
341 Archive &operator=(Archive const &) = delete;
342
343 /// Size field is 10 decimal digits long
344 static const uint64_t MaxMemberSize = 9999999999;
345
347
348 Kind kind() const { return (Kind)Format; }
349 bool isThin() const { return IsThin; }
350 static object::Archive::Kind getDefaultKind();
351 static object::Archive::Kind getDefaultKindForTriple(const Triple &T);
352
353 child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
354 child_iterator child_end() const;
356 bool SkipInternal = true) const {
357 return make_range(child_begin(Err, SkipInternal), child_end());
358 }
359
360 symbol_iterator symbol_begin() const;
361 symbol_iterator symbol_end() const;
365
367
368 static bool classof(Binary const *v) { return v->isArchive(); }
369
370 // check if a symbol is in the archive
372
373 virtual bool isEmpty() const;
374 bool hasSymbolTable() const;
377 uint32_t getNumberOfSymbols() const;
378 uint32_t getNumberOfECSymbols() const;
379 virtual uint64_t getFirstChildOffset() const { return getArchiveMagicLen(); }
380
381 std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
382 return std::move(ThinBuffers);
383 }
384
385 std::unique_ptr<AbstractArchiveMemberHeader>
386 createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size,
387 Error *Err) const;
388
389protected:
390 uint64_t getArchiveMagicLen() const;
391 void setFirstRegular(const Child &C);
392
396
397private:
398 StringRef FirstRegularData;
399 uint16_t FirstRegularStartOfFile = -1;
400
401 unsigned Format : 3;
402 unsigned IsThin : 1;
403 mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
404};
405
406class BigArchive : public Archive {
407public:
408 /// Fixed-Length Header.
409 struct FixLenHdr {
410 char Magic[sizeof(BigArchiveMagic) - 1]; ///< Big archive magic string.
411 char MemOffset[20]; ///< Offset to member table.
412 char GlobSymOffset[20]; ///< Offset to global symbol table.
413 char
414 GlobSym64Offset[20]; ///< Offset global symbol table for 64-bit objects.
415 char FirstChildOffset[20]; ///< Offset to first archive member.
416 char LastChildOffset[20]; ///< Offset to last archive member.
417 char FreeOffset[20]; ///< Offset to first mem on free list.
418 };
419
426
427public:
429 uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
431 bool isEmpty() const override { return getFirstChildOffset() == 0; }
432
435};
436
437} // end namespace object
438} // end namespace llvm
439
440#endif // LLVM_OBJECT_ARCHIVE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:213
#define T
static StringRef getName(Value *V)
static std::optional< int32_t > getOffset(ArrayRef< int32_t > Offsets, size_t Idx)
static const char * name
static unsigned getSize(unsigned Kind)
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
iterator begin() const
Definition StringRef.h:113
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
A wrapper class for fallible iterators.
A range adaptor for a pair of iterators.
virtual StringRef getRawGID() const =0
virtual StringRef getRawUID() const =0
LLVM_ABI Expected< unsigned > getUID() const
Definition Archive.cpp:400
virtual Expected< uint64_t > getSize() const =0
LLVM_ABI Expected< sys::fs::perms > getAccessMode() const
Definition Archive.cpp:381
AbstractArchiveMemberHeader(const Archive *Parent)
Definition Archive.h:44
LLVM_ABI Expected< unsigned > getGID() const
Definition Archive.cpp:407
virtual uint64_t getOffset() const =0
virtual Expected< const char * > getNextChildLoc() const =0
Get next file member location.
virtual Expected< StringRef > getRawName() const =0
Get the name without looking up long names.
virtual Expected< bool > isThin() const =0
LLVM_ABI Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition Archive.cpp:390
virtual uint64_t getSizeOf() const =0
Returns the size in bytes of the format-defined member header of the concrete archive type.
virtual StringRef getRawAccessMode() const =0
virtual std::unique_ptr< AbstractArchiveMemberHeader > clone() const =0
virtual StringRef getRawLastModified() const =0
virtual Expected< StringRef > getName(uint64_t Size) const =0
Get the name looking up long names.
ArchiveMemberHeader(const Archive *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err)
Definition Archive.cpp:94
std::unique_ptr< AbstractArchiveMemberHeader > clone() const override
Definition Archive.h:112
bool operator==(const ChildFallibleIterator &other) const
Definition Archive.h:272
bool operator!=(const ChildFallibleIterator &other) const
Definition Archive.h:279
StringRef getRawLastModified() const
Definition Archive.h:236
bool operator==(const Child &other) const
Definition Archive.h:220
LLVM_ABI uint64_t getChildOffset() const
Definition Archive.cpp:621
Child & operator=(const Child &C)
Definition Archive.h:207
Expected< unsigned > getGID() const
Definition Archive.h:241
uint64_t getDataOffset() const
Definition Archive.h:254
Expected< StringRef > getRawName() const
Definition Archive.h:230
Expected< unsigned > getUID() const
Definition Archive.h:240
LLVM_ABI Child(const Archive *Parent, const char *Start, Error *Err)
Definition Archive.cpp:464
Child & operator=(Child &&C) noexcept
Definition Archive.h:195
Expected< sys::fs::perms > getAccessMode() const
Definition Archive.h:243
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition Archive.h:232
const Archive * getParent() const
Definition Archive.h:225
Child(const Child &C)
Definition Archive.h:182
Symbol(const Archive *p, uint32_t symi, uint32_t stri)
Definition Archive.h:300
bool operator==(const Symbol &other) const
Definition Archive.h:303
const Symbol & operator*() const
Definition Archive.h:320
bool operator!=(const symbol_iterator &other) const
Definition Archive.h:326
const Symbol * operator->() const
Definition Archive.h:319
bool operator==(const symbol_iterator &other) const
Definition Archive.h:322
symbol_iterator symbol_begin() const
Definition Archive.cpp:1128
iterator_range< symbol_iterator > symbols() const
Definition Archive.h:362
virtual uint64_t getFirstChildOffset() const
Definition Archive.h:379
bool isThin() const
Definition Archive.h:349
Archive & operator=(Archive const &)=delete
StringRef getStringTable() const
Definition Archive.h:376
fallible_iterator< ChildFallibleIterator > child_iterator
Definition Archive.h:292
uint64_t getArchiveMagicLen() const
Definition Archive.cpp:689
StringRef getSymbolTable() const
Definition Archive.h:375
StringRef ECSymbolTable
Definition Archive.h:394
symbol_iterator symbol_end() const
Definition Archive.cpp:1186
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition Archive.h:355
child_iterator child_end() const
Definition Archive.cpp:998
Archive(Archive const &)=delete
static bool classof(Binary const *v)
Definition Archive.h:368
StringRef StringTable
Definition Archive.h:395
Archive(MemoryBufferRef Source, Error &Err)
Definition Archive.cpp:704
Kind kind() const
Definition Archive.h:348
StringRef SymbolTable
Definition Archive.h:393
child_iterator child_begin(Error &Err, bool SkipInternal=true) const
Definition Archive.cpp:982
static const uint64_t MaxMemberSize
Size field is 10 decimal digits long.
Definition Archive.h:344
std::vector< std::unique_ptr< MemoryBuffer > > takeThinBuffers()
Definition Archive.h:381
Expected< bool > isThin() const override
Definition Archive.h:158
std::unique_ptr< AbstractArchiveMemberHeader > clone() const override
Definition Archive.h:147
BigArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err)
Definition Archive.cpp:128
bool isEmpty() const override
Definition Archive.h:431
uint64_t getLastChildOffset() const
Definition Archive.h:430
std::string MergedGlobalSymtabBuf
Definition Archive.h:423
const FixLenHdr * ArFixLenHdr
Definition Archive.h:420
uint64_t getFirstChildOffset() const override
Definition Archive.h:429
LLVM_ABI BigArchive(MemoryBufferRef Source, Error &Err)
Definition Archive.cpp:1341
Binary(unsigned int Type, MemoryBufferRef Source)
Definition Binary.cpp:36
MemoryBufferRef getMemoryBufferRef() const
Definition Binary.cpp:43
CommonArchiveMemberHeader(const Archive *Parent, const T *RawHeaderPtr)
Definition Archive.h:83
uint64_t getSizeOf() const override
Returns the size in bytes of the format-defined member header of the concrete archive type.
Definition Archive.h:91
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
const char ArchiveMagic[]
Definition Archive.h:34
const char ZOSArchiveMagic[]
Definition Archive.h:37
const char ThinArchiveMagic[]
Definition Archive.h:35
const char BigArchiveMagic[]
Definition Archive.h:36
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
char Magic[sizeof(BigArchiveMagic) - 1]
Big archive magic string.
Definition Archive.h:410
char FirstChildOffset[20]
Offset to first archive member.
Definition Archive.h:415
char LastChildOffset[20]
Offset to last archive member.
Definition Archive.h:416
char FreeOffset[20]
Offset to first mem on free list.
Definition Archive.h:417
char GlobSym64Offset[20]
Offset global symbol table for 64-bit objects.
Definition Archive.h:414
char MemOffset[20]
Offset to member table.
Definition Archive.h:411
char GlobSymOffset[20]
Offset to global symbol table.
Definition Archive.h:412
char Size[10]
Size of data, not including header or padding.
Definition Archive.h:102