LLVM 24.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
161// Define file member header of z/OS archive.
162// The fixed part of the member header (in EBCDIC) is:
163// struct ar_hdr {
164// char ar_name[16]; /* space-padded member name */
165// char ar_date[12]; /* date (decimal) */
166// char ar_uid[6]; /* user id (decimal) */
167// char ar_gid[6]; /* group id (decimal) */
168// char ar_mode[8]; /* access mode (octal) */
169// char ar_size[10]; /* length in bytes (decimal) */
170// char ar_fmag[2]; /* contains backtick (X'79'), followed by new line
171// (X'15') */
172// };
174public:
175 ZOSArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr,
176 uint64_t Size, Error *Err);
177 std::unique_ptr<AbstractArchiveMemberHeader> clone() const override {
178 return std::make_unique<ZOSArchiveMemberHeader>(*this);
179 }
180
181 // Converted EBCDIC to ASCII header string fields.
182 std::string RawMemberName;
183 std::string MemberName;
184 std::string LastModified;
185 std::string UID;
186 std::string GID;
187 std::string AccessMode;
188
190
191 Expected<StringRef> getRawName() const override;
193 StringRef getRawAccessMode() const override;
194 StringRef getRawLastModified() const override;
195 StringRef getRawUID() const override;
196 StringRef getRawGID() const override;
197 Expected<uint64_t> getSize() const override;
198 Expected<bool> isThin() const override { return false; }
199};
200
201class LLVM_ABI Archive : public Binary {
202 virtual void anchor();
203
204public:
205 class Child {
206 friend Archive;
207 friend AbstractArchiveMemberHeader;
208
209 const Archive *Parent;
210 std::unique_ptr<AbstractArchiveMemberHeader> Header;
211 /// Includes header but not padding byte.
212 StringRef Data;
213 /// Offset from Data to the start of the file.
214 uint16_t StartOfFile;
215
216 Expected<bool> isThinMember() const;
217
218 public:
219 LLVM_ABI Child(const Archive *Parent, const char *Start, Error *Err);
220 LLVM_ABI Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
221
222 Child(const Child &C)
223 : Parent(C.Parent), Data(C.Data), StartOfFile(C.StartOfFile) {
224 if (C.Header)
225 Header = C.Header->clone();
226 }
227
229 Parent = std::move(C.Parent);
230 Header = std::move(C.Header);
231 Data = C.Data;
232 StartOfFile = C.StartOfFile;
233 }
234
235 Child &operator=(Child &&C) noexcept {
236 if (&C == this)
237 return *this;
238
239 Parent = std::move(C.Parent);
240 Header = std::move(C.Header);
241 Data = C.Data;
242 StartOfFile = C.StartOfFile;
243
244 return *this;
245 }
246
248 if (&C == this)
249 return *this;
250
251 Parent = C.Parent;
252 if (C.Header)
253 Header = C.Header->clone();
254 Data = C.Data;
255 StartOfFile = C.StartOfFile;
256
257 return *this;
258 }
259
260 bool operator==(const Child &other) const {
261 assert(!Parent || !other.Parent || Parent == other.Parent);
262 return Data.begin() == other.Data.begin();
263 }
264
265 const Archive *getParent() const { return Parent; }
266 LLVM_ABI Expected<Child> getNext() const;
267
269 LLVM_ABI Expected<std::string> getFullName() const;
270 Expected<StringRef> getRawName() const { return Header->getRawName(); }
271
273 return Header->getLastModified();
274 }
275
277 return Header->getRawLastModified();
278 }
279
280 Expected<unsigned> getUID() const { return Header->getUID(); }
281 Expected<unsigned> getGID() const { return Header->getGID(); }
282
284 return Header->getAccessMode();
285 }
286
287 /// \return the size of the archive member without the header or padding.
289 /// \return the size in the archive header for this member.
290 LLVM_ABI Expected<uint64_t> getRawSize() const;
291
292 LLVM_ABI Expected<StringRef> getBuffer() const;
293 LLVM_ABI uint64_t getChildOffset() const;
294 uint64_t getDataOffset() const { return getChildOffset() + StartOfFile; }
295
297
299 getAsBinary(LLVMContext *Context = nullptr) const;
300 };
301
303 Child C;
304
305 public:
306 ChildFallibleIterator() : C(Child(nullptr, nullptr, nullptr)) {}
307 ChildFallibleIterator(const Child &C) : C(C) {}
308
309 const Child *operator->() const { return &C; }
310 const Child &operator*() const { return C; }
311
312 bool operator==(const ChildFallibleIterator &other) const {
313 // Ignore errors here: If an error occurred during increment then getNext
314 // will have been set to child_end(), and the following comparison should
315 // do the right thing.
316 return C == other.C;
317 }
318
319 bool operator!=(const ChildFallibleIterator &other) const {
320 return !(*this == other);
321 }
322
324 auto NextChild = C.getNext();
325 if (!NextChild)
326 return NextChild.takeError();
327 C = std::move(*NextChild);
328 return Error::success();
329 }
330 };
331
333
334 class Symbol {
335 const Archive *Parent;
336 uint32_t SymbolIndex;
337 uint32_t StringIndex; // Extra index to the string.
338
339 public:
340 Symbol(const Archive *p, uint32_t symi, uint32_t stri)
341 : Parent(p), SymbolIndex(symi), StringIndex(stri) {}
342
343 bool operator==(const Symbol &other) const {
344 return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
345 }
346
347 LLVM_ABI StringRef getName() const;
348 LLVM_ABI Expected<Child> getMember() const;
349 LLVM_ABI Symbol getNext() const;
350 LLVM_ABI bool isECSymbol() const;
351
352 /// Archive attribute bit masks for K_ZOS archive symbol table entries.
353 static constexpr uint32_t ZOSAttrWSA = 0x1;
354 static constexpr uint32_t ZOSAttrXPLink = 0x2;
355 static constexpr uint32_t ZOSAttr64Bit = 0x4;
356 static constexpr uint32_t ZOSKnownAttrMask =
358
359 /// For K_ZOS archives, returns the 32-bit attribute word stored alongside
360 /// the symbol table entry. The low bits are described by the ZOSAttr*
361 /// constants above. Returns 0 for non-z/OS archives.
363 };
364
366 Symbol symbol;
367
368 public:
369 symbol_iterator(const Symbol &s) : symbol(s) {}
370
371 const Symbol *operator->() const { return &symbol; }
372 const Symbol &operator*() const { return symbol; }
373
374 bool operator==(const symbol_iterator &other) const {
375 return symbol == other.symbol;
376 }
377
378 bool operator!=(const symbol_iterator &other) const {
379 return !(*this == other);
380 }
381
382 symbol_iterator &operator++() { // Preincrement
383 symbol = symbol.getNext();
384 return *this;
385 }
386 };
387
388 Archive(MemoryBufferRef Source, Error &Err);
390
391 // Explicitly non-copyable.
392 Archive(Archive const &) = delete;
393 Archive &operator=(Archive const &) = delete;
394
395 /// Size field is 10 decimal digits long
396 static const uint64_t MaxMemberSize = 9999999999;
397
408
409 Kind kind() const { return (Kind)Format; }
410 bool isThin() const { return IsThin; }
411 static object::Archive::Kind getDefaultKind();
412 static object::Archive::Kind getDefaultKindForTriple(const Triple &T);
413
414 child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
415 child_iterator child_end() const;
417 bool SkipInternal = true) const {
418 return make_range(child_begin(Err, SkipInternal), child_end());
419 }
420
421 symbol_iterator symbol_begin() const;
422 symbol_iterator symbol_end() const;
426
428
429 static bool classof(Binary const *v) { return v->isArchive(); }
430
431 // check if a symbol is in the archive
433
434 virtual bool isEmpty() const;
435 bool hasSymbolTable() const;
438 uint32_t getNumberOfSymbols() const;
439 uint32_t getNumberOfECSymbols() const;
440 virtual uint64_t getFirstChildOffset() const { return getArchiveMagicLen(); }
441
442 std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
443 return std::move(ThinBuffers);
444 }
445
446 std::unique_ptr<AbstractArchiveMemberHeader>
447 createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size,
448 Error *Err) const;
449
450protected:
451 uint64_t getArchiveMagicLen() const;
452 void setFirstRegular(const Child &C);
453
457
458private:
459 StringRef FirstRegularData;
460 uint16_t FirstRegularStartOfFile = -1;
461
462 unsigned Format : 3;
463 unsigned IsThin : 1;
464 mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
465};
466
467class BigArchive : public Archive {
468public:
469 /// Fixed-Length Header.
470 struct FixLenHdr {
471 char Magic[sizeof(BigArchiveMagic) - 1]; ///< Big archive magic string.
472 char MemOffset[20]; ///< Offset to member table.
473 char GlobSymOffset[20]; ///< Offset to global symbol table.
474 char
475 GlobSym64Offset[20]; ///< Offset global symbol table for 64-bit objects.
476 char FirstChildOffset[20]; ///< Offset to first archive member.
477 char LastChildOffset[20]; ///< Offset to last archive member.
478 char FreeOffset[20]; ///< Offset to first mem on free list.
479 };
480
487
488public:
490 uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
492 bool isEmpty() const override { return getFirstChildOffset() == 0; }
493
496};
497
498class ZOSArchive : public Archive {
499public:
500 // Fixed-Length header.
501 struct FixLenHdr {
502 char Magic[sizeof(ZOSArchiveMagic) - 1]; ///< ZOS archive magic string.
503 };
504
506
507private:
508 std::string SymbolTableBuf; // __.SYMDEF strings converted to ASCII.
509};
510} // end namespace object
511} // end namespace llvm
512
513#endif // LLVM_OBJECT_ARCHIVE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define LLVM_ABI
Definition Compiler.h:215
#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
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
iterator begin() const
Definition StringRef.h:114
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
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:521
virtual Expected< uint64_t > getSize() const =0
LLVM_ABI Expected< sys::fs::perms > getAccessMode() const
Definition Archive.cpp:502
AbstractArchiveMemberHeader(const Archive *Parent)
Definition Archive.h:44
LLVM_ABI Expected< unsigned > getGID() const
Definition Archive.cpp:528
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:511
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:95
std::unique_ptr< AbstractArchiveMemberHeader > clone() const override
Definition Archive.h:112
bool operator==(const ChildFallibleIterator &other) const
Definition Archive.h:312
bool operator!=(const ChildFallibleIterator &other) const
Definition Archive.h:319
StringRef getRawLastModified() const
Definition Archive.h:276
bool operator==(const Child &other) const
Definition Archive.h:260
LLVM_ABI uint64_t getChildOffset() const
Definition Archive.cpp:742
Child & operator=(const Child &C)
Definition Archive.h:247
Expected< unsigned > getGID() const
Definition Archive.h:281
uint64_t getDataOffset() const
Definition Archive.h:294
Expected< StringRef > getRawName() const
Definition Archive.h:270
Expected< unsigned > getUID() const
Definition Archive.h:280
LLVM_ABI Child(const Archive *Parent, const char *Start, Error *Err)
Definition Archive.cpp:585
Child & operator=(Child &&C) noexcept
Definition Archive.h:235
Expected< sys::fs::perms > getAccessMode() const
Definition Archive.h:283
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition Archive.h:272
const Archive * getParent() const
Definition Archive.h:265
Child(const Child &C)
Definition Archive.h:222
static constexpr uint32_t ZOSKnownAttrMask
Definition Archive.h:356
static constexpr uint32_t ZOSAttr64Bit
Definition Archive.h:355
Symbol(const Archive *p, uint32_t symi, uint32_t stri)
Definition Archive.h:340
bool operator==(const Symbol &other) const
Definition Archive.h:343
static constexpr uint32_t ZOSAttrXPLink
Definition Archive.h:354
static constexpr uint32_t ZOSAttrWSA
Archive attribute bit masks for K_ZOS archive symbol table entries.
Definition Archive.h:353
LLVM_ABI uint32_t getZOSAttributes() const
For K_ZOS archives, returns the 32-bit attribute word stored alongside the symbol table entry.
Definition Archive.cpp:1143
const Symbol & operator*() const
Definition Archive.h:372
bool operator!=(const symbol_iterator &other) const
Definition Archive.h:378
const Symbol * operator->() const
Definition Archive.h:371
bool operator==(const symbol_iterator &other) const
Definition Archive.h:374
symbol_iterator symbol_begin() const
Definition Archive.cpp:1279
iterator_range< symbol_iterator > symbols() const
Definition Archive.h:423
virtual uint64_t getFirstChildOffset() const
Definition Archive.h:440
bool isThin() const
Definition Archive.h:410
Archive & operator=(Archive const &)=delete
StringRef getStringTable() const
Definition Archive.h:437
fallible_iterator< ChildFallibleIterator > child_iterator
Definition Archive.h:332
uint64_t getArchiveMagicLen() const
Definition Archive.cpp:816
StringRef getSymbolTable() const
Definition Archive.h:436
StringRef ECSymbolTable
Definition Archive.h:455
symbol_iterator symbol_end() const
Definition Archive.cpp:1346
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition Archive.h:416
child_iterator child_end() const
Definition Archive.cpp:1131
Archive(Archive const &)=delete
static bool classof(Binary const *v)
Definition Archive.h:429
StringRef StringTable
Definition Archive.h:456
Archive(MemoryBufferRef Source, Error &Err)
Definition Archive.cpp:831
Kind kind() const
Definition Archive.h:409
StringRef SymbolTable
Definition Archive.h:454
child_iterator child_begin(Error &Err, bool SkipInternal=true) const
Definition Archive.cpp:1115
static const uint64_t MaxMemberSize
Size field is 10 decimal digits long.
Definition Archive.h:396
std::vector< std::unique_ptr< MemoryBuffer > > takeThinBuffers()
Definition Archive.h:442
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:137
bool isEmpty() const override
Definition Archive.h:492
uint64_t getLastChildOffset() const
Definition Archive.h:491
std::string MergedGlobalSymtabBuf
Definition Archive.h:484
const FixLenHdr * ArFixLenHdr
Definition Archive.h:481
uint64_t getFirstChildOffset() const override
Definition Archive.h:490
LLVM_ABI BigArchive(MemoryBufferRef Source, Error &Err)
Definition Archive.cpp:1503
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
StringRef getRawGID() const override
Definition Archive.cpp:423
StringRef getRawAccessMode() const override
Definition Archive.cpp:413
ZOSArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err)
Definition Archive.cpp:388
void setMemberHeaderStrings(Error *Err, uint64_t Size)
Definition Archive.cpp:425
std::unique_ptr< AbstractArchiveMemberHeader > clone() const override
Definition Archive.h:177
StringRef getRawUID() const override
Definition Archive.cpp:421
Expected< StringRef > getRawName() const override
Get the name without looking up long names.
Definition Archive.cpp:405
StringRef getRawLastModified() const override
Definition Archive.cpp:417
Expected< bool > isThin() const override
Definition Archive.h:198
LLVM_ABI ZOSArchive(MemoryBufferRef Source, Error &Err)
Definition Archive.cpp:1614
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
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.
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:471
char FirstChildOffset[20]
Offset to first archive member.
Definition Archive.h:476
char LastChildOffset[20]
Offset to last archive member.
Definition Archive.h:477
char FreeOffset[20]
Offset to first mem on free list.
Definition Archive.h:478
char GlobSym64Offset[20]
Offset global symbol table for 64-bit objects.
Definition Archive.h:475
char MemOffset[20]
Offset to member table.
Definition Archive.h:472
char GlobSymOffset[20]
Offset to global symbol table.
Definition Archive.h:473
char Size[10]
Size of data, not including header or padding.
Definition Archive.h:102
char Magic[sizeof(ZOSArchiveMagic) - 1]
ZOS archive magic string.
Definition Archive.h:502