32
32
namespace llvm {
33
33
namespace object {
34
34
35
+ const char ArchiveMagic[] = " !<arch>\n " ;
36
+ const char ThinArchiveMagic[] = " !<thin>\n " ;
37
+ const char BigArchiveMagic[] = " <bigaf>\n " ;
38
+
35
39
class Archive ;
36
40
37
- class ArchiveMemberHeader {
41
+ class AbstractArchiveMemberHeader {
42
+ protected:
43
+ AbstractArchiveMemberHeader (const Archive *Parent) : Parent(Parent){};
44
+
38
45
public:
39
46
friend class Archive ;
40
-
41
- ArchiveMemberHeader (Archive const *Parent, const char *RawHeaderPtr,
42
- uint64_t Size , Error *Err);
43
- // ArchiveMemberHeader() = default;
47
+ virtual std::unique_ptr<AbstractArchiveMemberHeader> clone () const = 0;
48
+ virtual ~AbstractArchiveMemberHeader (){};
44
49
45
50
// / Get the name without looking up long names.
46
- Expected<StringRef> getRawName () const ;
51
+ virtual Expected<StringRef> getRawName () const = 0;
52
+ virtual StringRef getRawAccessMode () const = 0;
53
+ virtual StringRef getRawLastModified () const = 0;
54
+ virtual StringRef getRawUID () const = 0;
55
+ virtual StringRef getRawGID () const = 0;
47
56
48
57
// / Get the name looking up long names.
49
- Expected<StringRef> getName (uint64_t Size ) const ;
58
+ virtual Expected<StringRef> getName (uint64_t Size ) const = 0;
59
+ virtual Expected<uint64_t > getSize () const = 0;
60
+ virtual uint64_t getOffset () const = 0;
50
61
51
- Expected<uint64_t > getSize () const ;
62
+ // / Get next file member location.
63
+ virtual Expected<const char *> getNextChildLoc () const = 0;
64
+ virtual Expected<bool > isThin () const = 0;
52
65
53
66
Expected<sys::fs::perms> getAccessMode () const ;
54
67
Expected<sys::TimePoint<std::chrono::seconds>> getLastModified () const ;
68
+ Expected<unsigned > getUID () const ;
69
+ Expected<unsigned > getGID () const ;
70
+
71
+ // / Returns the size in bytes of the format-defined member header of the
72
+ // / concrete archive type.
73
+ virtual uint64_t getSizeOf () const = 0;
74
+
75
+ const Archive *Parent;
76
+ };
77
+
78
+ template <typename T>
79
+ class CommonArchiveMemberHeader : public AbstractArchiveMemberHeader {
80
+ public:
81
+ CommonArchiveMemberHeader (const Archive *Parent, const T *RawHeaderPtr)
82
+ : AbstractArchiveMemberHeader(Parent), ArMemHdr(RawHeaderPtr){};
83
+ StringRef getRawAccessMode () const override ;
84
+ StringRef getRawLastModified () const override ;
85
+ StringRef getRawUID () const override ;
86
+ StringRef getRawGID () const override ;
87
+
88
+ uint64_t getOffset () const override ;
89
+ uint64_t getSizeOf () const override { return sizeof (T); }
90
+
91
+ T const *ArMemHdr;
92
+ };
55
93
56
- StringRef getRawLastModified () const {
57
- return StringRef (ArMemHdr->LastModified , sizeof (ArMemHdr->LastModified ))
58
- .rtrim (' ' );
94
+ struct UnixArMemHdrType {
95
+ char Name[16 ];
96
+ char LastModified[12 ];
97
+ char UID[6 ];
98
+ char GID[6 ];
99
+ char AccessMode[8 ];
100
+ char Size [10 ]; // /< Size of data, not including header or padding.
101
+ char Terminator[2 ];
102
+ };
103
+
104
+ class ArchiveMemberHeader : public CommonArchiveMemberHeader <UnixArMemHdrType> {
105
+ public:
106
+ ArchiveMemberHeader (const Archive *Parent, const char *RawHeaderPtr,
107
+ uint64_t Size , Error *Err);
108
+
109
+ std::unique_ptr<AbstractArchiveMemberHeader> clone () const override {
110
+ return std::make_unique<ArchiveMemberHeader>(*this );
59
111
}
60
112
61
- Expected<unsigned > getUID () const ;
62
- Expected<unsigned > getGID () const ;
113
+ Expected<StringRef> getRawName () const override ;
63
114
64
- // This returns the size of the private struct ArMemHdrType
65
- uint64_t getSizeOf () const { return sizeof (ArMemHdrType); }
115
+ Expected<StringRef> getName (uint64_t Size ) const override ;
116
+ Expected<uint64_t > getSize () const override ;
117
+ Expected<const char *> getNextChildLoc () const override ;
118
+ Expected<bool > isThin () const override ;
119
+ };
66
120
67
- private:
68
- struct ArMemHdrType {
69
- char Name[16 ];
70
- char LastModified[12 ];
71
- char UID[6 ];
72
- char GID[6 ];
73
- char AccessMode[8 ];
74
- char Size [10 ]; // /< Size of data, not including header or padding.
121
+ // File Member Header
122
+ struct BigArMemHdrType {
123
+ char Size [20 ]; // File member size in decimal
124
+ char NextOffset[20 ]; // Next member offset in decimal
125
+ char PrevOffset[20 ]; // Previous member offset in decimal
126
+ char LastModified[12 ];
127
+ char UID[12 ];
128
+ char GID[12 ];
129
+ char AccessMode[12 ];
130
+ char NameLen[4 ]; // File member name length in decimal
131
+ union {
132
+ char Name[2 ]; // Start of member name
75
133
char Terminator[2 ];
76
134
};
77
- Archive const *Parent;
78
- ArMemHdrType const *ArMemHdr;
135
+ };
136
+
137
+ // Define file member header of AIX big archive.
138
+ class BigArchiveMemberHeader
139
+ : public CommonArchiveMemberHeader<BigArMemHdrType> {
140
+
141
+ public:
142
+ BigArchiveMemberHeader (Archive const *Parent, const char *RawHeaderPtr,
143
+ uint64_t Size , Error *Err);
144
+ std::unique_ptr<AbstractArchiveMemberHeader> clone () const override {
145
+ return std::make_unique<BigArchiveMemberHeader>(*this );
146
+ }
147
+
148
+ Expected<StringRef> getRawName () const override ;
149
+ Expected<uint64_t > getRawNameSize () const ;
150
+
151
+ Expected<StringRef> getName (uint64_t Size ) const override ;
152
+ Expected<uint64_t > getSize () const override ;
153
+ Expected<const char *> getNextChildLoc () const override ;
154
+ Expected<uint64_t > getNextOffset () const ;
155
+ Expected<bool > isThin () const override { return false ; }
79
156
};
80
157
81
158
class Archive : public Binary {
@@ -84,10 +161,10 @@ class Archive : public Binary {
84
161
public:
85
162
class Child {
86
163
friend Archive;
87
- friend ArchiveMemberHeader ;
164
+ friend AbstractArchiveMemberHeader ;
88
165
89
166
const Archive *Parent;
90
- ArchiveMemberHeader Header;
167
+ std::unique_ptr<AbstractArchiveMemberHeader> Header;
91
168
// / Includes header but not padding byte.
92
169
StringRef Data;
93
170
// / Offset from Data to the start of the file.
@@ -99,6 +176,44 @@ class Archive : public Binary {
99
176
Child (const Archive *Parent, const char *Start, Error *Err);
100
177
Child (const Archive *Parent, StringRef Data, uint16_t StartOfFile);
101
178
179
+ Child (const Child &C)
180
+ : Parent(C.Parent), Data(C.Data), StartOfFile(C.StartOfFile) {
181
+ if (C.Header )
182
+ Header = C.Header ->clone ();
183
+ }
184
+
185
+ Child (Child &&C) {
186
+ Parent = std::move (C.Parent );
187
+ Header = std::move (C.Header );
188
+ Data = C.Data ;
189
+ StartOfFile = C.StartOfFile ;
190
+ }
191
+
192
+ Child &operator =(Child &&C) noexcept {
193
+ if (&C == this )
194
+ return *this ;
195
+
196
+ Parent = std::move (C.Parent );
197
+ Header = std::move (C.Header );
198
+ Data = C.Data ;
199
+ StartOfFile = C.StartOfFile ;
200
+
201
+ return *this ;
202
+ }
203
+
204
+ Child &operator =(const Child &C) {
205
+ if (&C == this )
206
+ return *this ;
207
+
208
+ Parent = C.Parent ;
209
+ if (C.Header )
210
+ Header = C.Header ->clone ();
211
+ Data = C.Data ;
212
+ StartOfFile = C.StartOfFile ;
213
+
214
+ return *this ;
215
+ }
216
+
102
217
bool operator ==(const Child &other) const {
103
218
assert (!Parent || !other.Parent || Parent == other.Parent );
104
219
return Data.begin () == other.Data .begin ();
@@ -109,19 +224,21 @@ class Archive : public Binary {
109
224
110
225
Expected<StringRef> getName () const ;
111
226
Expected<std::string> getFullName () const ;
112
- Expected<StringRef> getRawName () const { return Header. getRawName (); }
227
+ Expected<StringRef> getRawName () const { return Header-> getRawName (); }
113
228
114
229
Expected<sys::TimePoint<std::chrono::seconds>> getLastModified () const {
115
- return Header. getLastModified ();
230
+ return Header-> getLastModified ();
116
231
}
117
232
118
- StringRef getRawLastModified () const { return Header.getRawLastModified (); }
233
+ StringRef getRawLastModified () const {
234
+ return Header->getRawLastModified ();
235
+ }
119
236
120
- Expected<unsigned > getUID () const { return Header. getUID (); }
121
- Expected<unsigned > getGID () const { return Header. getGID (); }
237
+ Expected<unsigned > getUID () const { return Header-> getUID (); }
238
+ Expected<unsigned > getGID () const { return Header-> getGID (); }
122
239
123
240
Expected<sys::fs::perms> getAccessMode () const {
124
- return Header. getAccessMode ();
241
+ return Header-> getAccessMode ();
125
242
}
126
243
127
244
// / \return the size of the archive member without the header or padding.
@@ -218,7 +335,7 @@ class Archive : public Binary {
218
335
// / Size field is 10 decimal digits long
219
336
static const uint64_t MaxMemberSize = 9999999999 ;
220
337
221
- enum Kind { K_GNU, K_GNU64, K_BSD, K_DARWIN, K_DARWIN64, K_COFF };
338
+ enum Kind { K_GNU, K_GNU64, K_BSD, K_DARWIN, K_DARWIN64, K_COFF, K_AIXBIG };
222
339
223
340
Kind kind () const { return (Kind)Format; }
224
341
bool isThin () const { return IsThin; }
@@ -236,7 +353,6 @@ class Archive : public Binary {
236
353
return make_range (symbol_begin (), symbol_end ());
237
354
}
238
355
239
- // Cast methods.
240
356
static bool classof (Binary const *v) { return v->isArchive (); }
241
357
242
358
// check if a symbol is in the archive
@@ -247,24 +363,55 @@ class Archive : public Binary {
247
363
StringRef getSymbolTable () const { return SymbolTable; }
248
364
StringRef getStringTable () const { return StringTable; }
249
365
uint32_t getNumberOfSymbols () const ;
366
+ virtual uint64_t getFirstChildOffset () const { return getArchiveMagicLen (); }
250
367
251
368
std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers () {
252
369
return std::move (ThinBuffers);
253
370
}
254
371
372
+ std::unique_ptr<AbstractArchiveMemberHeader>
373
+ createArchiveMemberHeader (const char *RawHeaderPtr, uint64_t Size ,
374
+ Error *Err) const ;
375
+
376
+ protected:
377
+ uint64_t getArchiveMagicLen () const ;
378
+ void setFirstRegular (const Child &C);
379
+
255
380
private:
256
381
StringRef SymbolTable;
257
382
StringRef StringTable;
258
383
259
384
StringRef FirstRegularData;
260
385
uint16_t FirstRegularStartOfFile = -1 ;
261
- void setFirstRegular (const Child &C);
262
386
263
387
unsigned Format : 3 ;
264
388
unsigned IsThin : 1 ;
265
389
mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
266
390
};
267
391
392
+ class BigArchive : public Archive {
393
+ // / Fixed-Length Header.
394
+ struct FixLenHdr {
395
+ char Magic[sizeof (BigArchiveMagic) - 1 ]; // /< Big archive magic string.
396
+ char MemOffset[20 ]; // /< Offset to member table.
397
+ char GlobSymOffset[20 ]; // /< Offset to global symbol table.
398
+ char
399
+ GlobSym64Offset[20 ]; // /< Offset global symbol table for 64-bit objects.
400
+ char FirstChildOffset[20 ]; // /< Offset to first archive member.
401
+ char LastChildOffset[20 ]; // /< Offset to last archive member.
402
+ char FreeOffset[20 ]; // /< Offset to first mem on free list.
403
+ };
404
+
405
+ const FixLenHdr *ArFixLenHdr;
406
+ uint64_t FirstChildOffset = 0 ;
407
+ uint64_t LastChildOffset = 0 ;
408
+
409
+ public:
410
+ BigArchive (MemoryBufferRef Source, Error &Err);
411
+ uint64_t getFirstChildOffset () const override { return FirstChildOffset; }
412
+ uint64_t getLastChildOffset () const { return LastChildOffset; }
413
+ };
414
+
268
415
} // end namespace object
269
416
} // end namespace llvm
270
417
0 commit comments