LLVM 20.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"
21#include "llvm/Support/Error.h"
24#include <cassert>
25#include <cstdint>
26#include <memory>
27#include <string>
28#include <vector>
29
30namespace llvm {
31namespace object {
32
33const char ArchiveMagic[] = "!<arch>\n";
34const char ThinArchiveMagic[] = "!<thin>\n";
35const char BigArchiveMagic[] = "<bigaf>\n";
36
37class Archive;
38
40protected:
42
43public:
44 friend class Archive;
45 virtual std::unique_ptr<AbstractArchiveMemberHeader> clone() const = 0;
46 virtual ~AbstractArchiveMemberHeader() = default;
47
48 /// Get the name without looking up long names.
49 virtual Expected<StringRef> getRawName() const = 0;
50 virtual StringRef getRawAccessMode() const = 0;
51 virtual StringRef getRawLastModified() const = 0;
52 virtual StringRef getRawUID() const = 0;
53 virtual StringRef getRawGID() const = 0;
54
55 /// Get the name looking up long names.
57 virtual Expected<uint64_t> getSize() const = 0;
58 virtual uint64_t getOffset() const = 0;
59
60 /// Get next file member location.
62 virtual Expected<bool> isThin() const = 0;
63
68
69 /// Returns the size in bytes of the format-defined member header of the
70 /// concrete archive type.
71 virtual uint64_t getSizeOf() const = 0;
72
74};
75
76template <typename T>
78public:
79 CommonArchiveMemberHeader(const Archive *Parent, const T *RawHeaderPtr)
81 StringRef getRawAccessMode() const override;
82 StringRef getRawLastModified() const override;
83 StringRef getRawUID() const override;
84 StringRef getRawGID() const override;
85
86 uint64_t getOffset() const override;
87 uint64_t getSizeOf() const override { return sizeof(T); }
88
89 T const *ArMemHdr;
90};
91
93 char Name[16];
94 char LastModified[12];
95 char UID[6];
96 char GID[6];
97 char AccessMode[8];
98 char Size[10]; ///< Size of data, not including header or padding.
99 char Terminator[2];
100};
101
102class ArchiveMemberHeader : public CommonArchiveMemberHeader<UnixArMemHdrType> {
103public:
104 ArchiveMemberHeader(const Archive *Parent, const char *RawHeaderPtr,
105 uint64_t Size, Error *Err);
106
107 std::unique_ptr<AbstractArchiveMemberHeader> clone() const override {
108 return std::make_unique<ArchiveMemberHeader>(*this);
109 }
110
111 Expected<StringRef> getRawName() const override;
112
114 Expected<uint64_t> getSize() const override;
116 Expected<bool> isThin() const override;
117};
118
119// File Member Header
121 char Size[20]; // File member size in decimal
122 char NextOffset[20]; // Next member offset in decimal
123 char PrevOffset[20]; // Previous member offset in decimal
124 char LastModified[12];
125 char UID[12];
126 char GID[12];
127 char AccessMode[12];
128 char NameLen[4]; // File member name length in decimal
129 union {
130 char Name[2]; // Start of member name
131 char Terminator[2];
132 };
133};
134
135// Define file member header of AIX big archive.
137 : public CommonArchiveMemberHeader<BigArMemHdrType> {
138
139public:
140 BigArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr,
141 uint64_t Size, Error *Err);
142 std::unique_ptr<AbstractArchiveMemberHeader> clone() const override {
143 return std::make_unique<BigArchiveMemberHeader>(*this);
144 }
145
146 Expected<StringRef> getRawName() const override;
148
150 Expected<uint64_t> getSize() const override;
153 Expected<bool> isThin() const override { return false; }
154};
155
156class Archive : public Binary {
157 virtual void anchor();
158
159public:
160 class Child {
161 friend Archive;
163
164 const Archive *Parent;
165 std::unique_ptr<AbstractArchiveMemberHeader> Header;
166 /// Includes header but not padding byte.
167 StringRef Data;
168 /// Offset from Data to the start of the file.
169 uint16_t StartOfFile;
170
171 Expected<bool> isThinMember() const;
172
173 public:
174 Child(const Archive *Parent, const char *Start, Error *Err);
175 Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
176
177 Child(const Child &C)
178 : Parent(C.Parent), Data(C.Data), StartOfFile(C.StartOfFile) {
179 if (C.Header)
180 Header = C.Header->clone();
181 }
182
184 Parent = std::move(C.Parent);
185 Header = std::move(C.Header);
186 Data = C.Data;
187 StartOfFile = C.StartOfFile;
188 }
189
190 Child &operator=(Child &&C) noexcept {
191 if (&C == this)
192 return *this;
193
194 Parent = std::move(C.Parent);
195 Header = std::move(C.Header);
196 Data = C.Data;
197 StartOfFile = C.StartOfFile;
198
199 return *this;
200 }
201
203 if (&C == this)
204 return *this;
205
206 Parent = C.Parent;
207 if (C.Header)
208 Header = C.Header->clone();
209 Data = C.Data;
210 StartOfFile = C.StartOfFile;
211
212 return *this;
213 }
214
215 bool operator==(const Child &other) const {
216 assert(!Parent || !other.Parent || Parent == other.Parent);
217 return Data.begin() == other.Data.begin();
218 }
219
220 const Archive *getParent() const { return Parent; }
221 Expected<Child> getNext() const;
222
225 Expected<StringRef> getRawName() const { return Header->getRawName(); }
226
228 return Header->getLastModified();
229 }
230
232 return Header->getRawLastModified();
233 }
234
235 Expected<unsigned> getUID() const { return Header->getUID(); }
236 Expected<unsigned> getGID() const { return Header->getGID(); }
237
239 return Header->getAccessMode();
240 }
241
242 /// \return the size of the archive member without the header or padding.
244 /// \return the size in the archive header for this member.
246
248 uint64_t getChildOffset() const;
249 uint64_t getDataOffset() const { return getChildOffset() + StartOfFile; }
250
252
254 getAsBinary(LLVMContext *Context = nullptr) const;
255 };
256
258 Child C;
259
260 public:
261 ChildFallibleIterator() : C(Child(nullptr, nullptr, nullptr)) {}
262 ChildFallibleIterator(const Child &C) : C(C) {}
263
264 const Child *operator->() const { return &C; }
265 const Child &operator*() const { return C; }
266
267 bool operator==(const ChildFallibleIterator &other) const {
268 // Ignore errors here: If an error occurred during increment then getNext
269 // will have been set to child_end(), and the following comparison should
270 // do the right thing.
271 return C == other.C;
272 }
273
274 bool operator!=(const ChildFallibleIterator &other) const {
275 return !(*this == other);
276 }
277
279 auto NextChild = C.getNext();
280 if (!NextChild)
281 return NextChild.takeError();
282 C = std::move(*NextChild);
283 return Error::success();
284 }
285 };
286
288
289 class Symbol {
290 const Archive *Parent;
291 uint32_t SymbolIndex;
292 uint32_t StringIndex; // Extra index to the string.
293
294 public:
295 Symbol(const Archive *p, uint32_t symi, uint32_t stri)
296 : Parent(p), SymbolIndex(symi), StringIndex(stri) {}
297
298 bool operator==(const Symbol &other) const {
299 return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
300 }
301
302 StringRef getName() const;
304 Symbol getNext() const;
305 bool isECSymbol() const;
306 };
307
309 Symbol symbol;
310
311 public:
312 symbol_iterator(const Symbol &s) : symbol(s) {}
313
314 const Symbol *operator->() const { return &symbol; }
315 const Symbol &operator*() const { return symbol; }
316
317 bool operator==(const symbol_iterator &other) const {
318 return symbol == other.symbol;
319 }
320
321 bool operator!=(const symbol_iterator &other) const {
322 return !(*this == other);
323 }
324
325 symbol_iterator &operator++() { // Preincrement
326 symbol = symbol.getNext();
327 return *this;
328 }
329 };
330
331 Archive(MemoryBufferRef Source, Error &Err);
333
334 /// Size field is 10 decimal digits long
335 static const uint64_t MaxMemberSize = 9999999999;
336
338
339 Kind kind() const { return (Kind)Format; }
340 bool isThin() const { return IsThin; }
343
344 child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
347 bool SkipInternal = true) const {
348 return make_range(child_begin(Err, SkipInternal), child_end());
349 }
350
355 }
356
358
359 static bool classof(Binary const *v) { return v->isArchive(); }
360
361 // check if a symbol is in the archive
363
364 virtual bool isEmpty() const;
365 bool hasSymbolTable() const;
370 virtual uint64_t getFirstChildOffset() const { return getArchiveMagicLen(); }
371
372 std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
373 return std::move(ThinBuffers);
374 }
375
376 std::unique_ptr<AbstractArchiveMemberHeader>
377 createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size,
378 Error *Err) const;
379
380protected:
382 void setFirstRegular(const Child &C);
383
387
388private:
389 StringRef FirstRegularData;
390 uint16_t FirstRegularStartOfFile = -1;
391
392 unsigned Format : 3;
393 unsigned IsThin : 1;
394 mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
395};
396
397class BigArchive : public Archive {
398public:
399 /// Fixed-Length Header.
400 struct FixLenHdr {
401 char Magic[sizeof(BigArchiveMagic) - 1]; ///< Big archive magic string.
402 char MemOffset[20]; ///< Offset to member table.
403 char GlobSymOffset[20]; ///< Offset to global symbol table.
404 char
405 GlobSym64Offset[20]; ///< Offset global symbol table for 64-bit objects.
406 char FirstChildOffset[20]; ///< Offset to first archive member.
407 char LastChildOffset[20]; ///< Offset to last archive member.
408 char FreeOffset[20]; ///< Offset to first mem on free list.
409 };
410
417
418public:
419 BigArchive(MemoryBufferRef Source, Error &Err);
420 uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
422 bool isEmpty() const override { return getFirstChildOffset() == 0; }
423
426};
427
428} // end namespace object
429} // end namespace llvm
430
431#endif // LLVM_OBJECT_ARCHIVE_H
uint64_t Size
#define T
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:50
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
iterator begin() const
Definition: StringRef.h:111
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
A wrapper class for fallible iterators.
A range adaptor for a pair of iterators.
virtual StringRef getRawGID() const =0
virtual StringRef getRawUID() const =0
Expected< unsigned > getUID() const
Definition: Archive.cpp:404
virtual Expected< uint64_t > getSize() const =0
Expected< sys::fs::perms > getAccessMode() const
Definition: Archive.cpp:385
AbstractArchiveMemberHeader(const Archive *Parent)
Definition: Archive.h:41
Expected< unsigned > getGID() const
Definition: Archive.cpp:411
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
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition: Archive.cpp:394
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.
std::unique_ptr< AbstractArchiveMemberHeader > clone() const override
Definition: Archive.h:107
Expected< StringRef > getName(uint64_t Size) const override
Get the name looking up long names.
Definition: Archive.cpp:245
Expected< StringRef > getRawName() const override
Get the name without looking up long names.
Definition: Archive.cpp:155
Expected< bool > isThin() const override
Definition: Archive.cpp:418
Expected< uint64_t > getSize() const override
Definition: Archive.cpp:357
Expected< const char * > getNextChildLoc() const override
Get next file member location.
Definition: Archive.cpp:426
bool operator==(const ChildFallibleIterator &other) const
Definition: Archive.h:267
bool operator!=(const ChildFallibleIterator &other) const
Definition: Archive.h:274
Expected< StringRef > getBuffer() const
Definition: Archive.cpp:573
StringRef getRawLastModified() const
Definition: Archive.h:231
Expected< Child > getNext() const
Definition: Archive.cpp:595
bool operator==(const Child &other) const
Definition: Archive.h:215
Expected< std::string > getFullName() const
Definition: Archive.cpp:555
uint64_t getChildOffset() const
Definition: Archive.cpp:626
Expected< uint64_t > getRawSize() const
Definition: Archive.cpp:549
Expected< StringRef > getName() const
Definition: Archive.cpp:633
Expected< uint64_t > getSize() const
Definition: Archive.cpp:543
Child & operator=(const Child &C)
Definition: Archive.h:202
Expected< unsigned > getGID() const
Definition: Archive.h:236
uint64_t getDataOffset() const
Definition: Archive.h:249
Expected< StringRef > getRawName() const
Definition: Archive.h:225
Expected< std::unique_ptr< Binary > > getAsBinary(LLVMContext *Context=nullptr) const
Definition: Archive.cpp:658
Expected< MemoryBufferRef > getMemoryBufferRef() const
Definition: Archive.cpp:646
Expected< unsigned > getUID() const
Definition: Archive.h:235
Child & operator=(Child &&C) noexcept
Definition: Archive.h:190
Expected< sys::fs::perms > getAccessMode() const
Definition: Archive.h:238
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition: Archive.h:227
const Archive * getParent() const
Definition: Archive.h:220
Child(const Child &C)
Definition: Archive.h:177
Symbol(const Archive *p, uint32_t symi, uint32_t stri)
Definition: Archive.h:295
Expected< Child > getMember() const
Definition: Archive.cpp:1021
bool operator==(const Symbol &other) const
Definition: Archive.h:298
StringRef getName() const
Definition: Archive.cpp:1015
symbol_iterator & operator++()
Definition: Archive.h:325
const Symbol & operator*() const
Definition: Archive.h:315
bool operator!=(const symbol_iterator &other) const
Definition: Archive.h:321
const Symbol * operator->() const
Definition: Archive.h:314
bool operator==(const symbol_iterator &other) const
Definition: Archive.h:317
std::unique_ptr< AbstractArchiveMemberHeader > createArchiveMemberHeader(const char *RawHeaderPtr, uint64_t Size, Error *Err) const
Definition: Archive.cpp:685
symbol_iterator symbol_begin() const
Definition: Archive.cpp:1133
iterator_range< symbol_iterator > symbols() const
Definition: Archive.h:353
virtual uint64_t getFirstChildOffset() const
Definition: Archive.h:370
bool isThin() const
Definition: Archive.h:340
StringRef getStringTable() const
Definition: Archive.h:367
uint32_t getNumberOfSymbols() const
Definition: Archive.cpp:1240
fallible_iterator< ChildFallibleIterator > child_iterator
Definition: Archive.h:287
uint32_t getNumberOfECSymbols() const
Definition: Archive.cpp:1258
void setFirstRegular(const Child &C)
Definition: Archive.cpp:704
static object::Archive::Kind getDefaultKindForTriple(Triple &T)
Definition: Archive.cpp:972
uint64_t getArchiveMagicLen() const
Definition: Archive.cpp:694
StringRef getSymbolTable() const
Definition: Archive.h:366
StringRef ECSymbolTable
Definition: Archive.h:385
symbol_iterator symbol_end() const
Definition: Archive.cpp:1191
static object::Archive::Kind getDefaultKind()
Definition: Archive.cpp:982
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition: Archive.h:346
virtual bool isEmpty() const
Definition: Archive.cpp:1281
child_iterator child_end() const
Definition: Archive.cpp:1003
bool hasSymbolTable() const
Definition: Archive.cpp:1285
static bool classof(Binary const *v)
Definition: Archive.h:359
StringRef StringTable
Definition: Archive.h:386
Kind kind() const
Definition: Archive.h:339
StringRef SymbolTable
Definition: Archive.h:384
Expected< iterator_range< symbol_iterator > > ec_symbols() const
Definition: Archive.cpp:1195
Expected< std::optional< Child > > findSym(StringRef name) const
Definition: Archive.cpp:1264
child_iterator child_begin(Error &Err, bool SkipInternal=true) const
Definition: Archive.cpp:987
static const uint64_t MaxMemberSize
Size field is 10 decimal digits long.
Definition: Archive.h:335
std::vector< std::unique_ptr< MemoryBuffer > > takeThinBuffers()
Definition: Archive.h:372
static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)
Definition: Archive.cpp:669
Expected< uint64_t > getSize() const override
Definition: Archive.cpp:362
Expected< StringRef > getRawName() const override
Get the name without looking up long names.
Definition: Archive.cpp:216
Expected< bool > isThin() const override
Definition: Archive.h:153
std::unique_ptr< AbstractArchiveMemberHeader > clone() const override
Definition: Archive.h:142
Expected< const char * > getNextChildLoc() const override
Get next file member location.
Definition: Archive.cpp:451
Expected< StringRef > getName(uint64_t Size) const override
Get the name looking up long names.
Definition: Archive.cpp:353
Expected< uint64_t > getRawNameSize() const
Definition: Archive.cpp:375
Expected< uint64_t > getNextOffset() const
Definition: Archive.cpp:380
bool isEmpty() const override
Definition: Archive.h:422
uint64_t getLastChildOffset() const
Definition: Archive.h:421
std::string MergedGlobalSymtabBuf
Definition: Archive.h:414
const FixLenHdr * ArFixLenHdr
Definition: Archive.h:411
uint64_t FirstChildOffset
Definition: Archive.h:412
uint64_t LastChildOffset
Definition: Archive.h:413
uint64_t getFirstChildOffset() const override
Definition: Archive.h:420
StringRef getRawLastModified() const override
Definition: Archive.cpp:76
StringRef getRawUID() const override
Definition: Archive.cpp:80
CommonArchiveMemberHeader(const Archive *Parent, const T *RawHeaderPtr)
Definition: Archive.h:79
uint64_t getSizeOf() const override
Returns the size in bytes of the format-defined member header of the concrete archive type.
Definition: Archive.h:87
uint64_t getOffset() const override
Definition: Archive.cpp:88
StringRef getRawAccessMode() const override
Definition: Archive.cpp:71
StringRef getRawGID() const override
Definition: Archive.cpp:84
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:33
const char ThinArchiveMagic[]
Definition: Archive.h:34
const char BigArchiveMagic[]
Definition: Archive.h:35
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Fixed-Length Header.
Definition: Archive.h:400
char Magic[sizeof(BigArchiveMagic) - 1]
Big archive magic string.
Definition: Archive.h:401
char FirstChildOffset[20]
Offset to first archive member.
Definition: Archive.h:406
char LastChildOffset[20]
Offset to last archive member.
Definition: Archive.h:407
char FreeOffset[20]
Offset to first mem on free list.
Definition: Archive.h:408
char GlobSym64Offset[20]
Offset global symbol table for 64-bit objects.
Definition: Archive.h:405
char MemOffset[20]
Offset to member table.
Definition: Archive.h:402
char GlobSymOffset[20]
Offset to global symbol table.
Definition: Archive.h:403
char Size[10]
Size of data, not including header or padding.
Definition: Archive.h:98