LLVM  4.0.0
Archive.h
Go to the documentation of this file.
1 //===- Archive.h - ar archive file format -----------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the ar archive file format class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_OBJECT_ARCHIVE_H
15 #define LLVM_OBJECT_ARCHIVE_H
16 
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Object/Binary.h"
21 #include "llvm/Support/Chrono.h"
22 #include "llvm/Support/Error.h"
26 
27 namespace llvm {
28 namespace object {
29 
30 class Archive;
31 
33 public:
34  friend class Archive;
35  ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr,
36  uint64_t Size, Error *Err);
37  // ArchiveMemberHeader() = default;
38 
39  /// Get the name without looking up long names.
41 
42  /// Get the name looking up long names.
43  Expected<llvm::StringRef> getName(uint64_t Size) const;
44 
45  /// Members are not larger than 4GB.
47 
51  return StringRef(ArMemHdr->LastModified,
52  sizeof(ArMemHdr->LastModified)).rtrim(' ');
53  }
54  Expected<unsigned> getUID() const;
55  Expected<unsigned> getGID() const;
56 
57  // This returns the size of the private struct ArMemHdrType
58  uint64_t getSizeOf() const {
59  return sizeof(ArMemHdrType);
60  }
61 
62 private:
63  struct ArMemHdrType {
64  char Name[16];
65  char LastModified[12];
66  char UID[6];
67  char GID[6];
68  char AccessMode[8];
69  char Size[10]; ///< Size of data, not including header or padding.
70  char Terminator[2];
71  };
72  Archive const *Parent;
73  ArMemHdrType const *ArMemHdr;
74 };
75 
76 class Archive : public Binary {
77  virtual void anchor();
78 public:
79  class Child {
80  friend Archive;
81  const Archive *Parent;
82  friend ArchiveMemberHeader;
83  ArchiveMemberHeader Header;
84  /// \brief Includes header but not padding byte.
85  StringRef Data;
86  /// \brief Offset from Data to the start of the file.
87  uint16_t StartOfFile;
88 
89  Expected<bool> isThinMember() const;
90 
91  public:
92  Child(const Archive *Parent, const char *Start, Error *Err);
93  Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
94 
95  bool operator ==(const Child &other) const {
96  assert(!Parent || !other.Parent || Parent == other.Parent);
97  return Data.begin() == other.Data.begin();
98  }
99 
100  const Archive *getParent() const { return Parent; }
101  Expected<Child> getNext() const;
102 
105  Expected<StringRef> getRawName() const { return Header.getRawName(); }
107  return Header.getLastModified();
108  }
110  return Header.getRawLastModified();
111  }
112  Expected<unsigned> getUID() const { return Header.getUID(); }
113  Expected<unsigned> getGID() const { return Header.getGID(); }
115  return Header.getAccessMode();
116  }
117  /// \return the size of the archive member without the header or padding.
118  Expected<uint64_t> getSize() const;
119  /// \return the size in the archive header for this member.
121 
123  uint64_t getChildOffset() const;
124 
126 
128  getAsBinary(LLVMContext *Context = nullptr) const;
129  };
130 
132  Child C;
133  Error *E;
134 
135  public:
136  child_iterator() : C(Child(nullptr, nullptr, nullptr)), E(nullptr) {}
137  child_iterator(const Child &C, Error *E) : C(C), E(E) {}
138  const Child *operator->() const { return &C; }
139  const Child &operator*() const { return C; }
140 
141  bool operator==(const child_iterator &other) const {
142  // Ignore errors here: If an error occurred during increment then getNext
143  // will have been set to child_end(), and the following comparison should
144  // do the right thing.
145  return C == other.C;
146  }
147 
148  bool operator!=(const child_iterator &other) const {
149  return !(*this == other);
150  }
151 
152  // Code in loops with child_iterators must check for errors on each loop
153  // iteration. And if there is an error break out of the loop.
154  child_iterator &operator++() { // Preincrement
155  assert(E && "Can't increment iterator with no Error attached");
156  ErrorAsOutParameter ErrAsOutParam(E);
157  if (auto ChildOrErr = C.getNext())
158  C = *ChildOrErr;
159  else {
160  C = C.getParent()->child_end().C;
161  *E = ChildOrErr.takeError();
162  E = nullptr;
163  }
164  return *this;
165  }
166  };
167 
168  class Symbol {
169  const Archive *Parent;
170  uint32_t SymbolIndex;
171  uint32_t StringIndex; // Extra index to the string.
172 
173  public:
174  bool operator ==(const Symbol &other) const {
175  return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
176  }
177 
178  Symbol(const Archive *p, uint32_t symi, uint32_t stri)
179  : Parent(p)
180  , SymbolIndex(symi)
181  , StringIndex(stri) {}
182  StringRef getName() const;
183  Expected<Child> getMember() const;
184  Symbol getNext() const;
185  };
186 
188  Symbol symbol;
189  public:
190  symbol_iterator(const Symbol &s) : symbol(s) {}
191  const Symbol *operator->() const { return &symbol; }
192  const Symbol &operator*() const { return symbol; }
193 
194  bool operator==(const symbol_iterator &other) const {
195  return symbol == other.symbol;
196  }
197 
198  bool operator!=(const symbol_iterator &other) const {
199  return !(*this == other);
200  }
201 
202  symbol_iterator& operator++() { // Preincrement
203  symbol = symbol.getNext();
204  return *this;
205  }
206  };
207 
210 
211  enum Kind {
217  };
218 
219  Kind kind() const { return (Kind)Format; }
220  bool isThin() const { return IsThin; }
221 
222  child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
223  child_iterator child_end() const;
225  bool SkipInternal = true) const {
226  return make_range(child_begin(Err, SkipInternal), child_end());
227  }
228 
230  symbol_iterator symbol_end() const;
232  return make_range(symbol_begin(), symbol_end());
233  }
234 
235  // Cast methods.
236  static inline bool classof(Binary const *v) {
237  return v->isArchive();
238  }
239 
240  // check if a symbol is in the archive
242 
243  bool isEmpty() const;
244  bool hasSymbolTable() const;
245  StringRef getSymbolTable() const { return SymbolTable; }
246  StringRef getStringTable() const { return StringTable; }
248 
249  std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
250  return std::move(ThinBuffers);
251  }
252 
253 private:
254  StringRef SymbolTable;
255  StringRef StringTable;
256 
257  StringRef FirstRegularData;
258  uint16_t FirstRegularStartOfFile = -1;
259  void setFirstRegular(const Child &C);
260 
261  unsigned Format : 3;
262  unsigned IsThin : 1;
263  mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
264 };
265 
266 }
267 }
268 
269 #endif
child_iterator(const Child &C, Error *E)
Definition: Archive.h:137
LLVMContext & Context
symbol_iterator symbol_end() const
Definition: Archive.cpp:935
Expected< unsigned > getUID() const
Definition: Archive.cpp:263
Expected< Optional< Child > > findSym(StringRef name) const
Definition: Archive.cpp:957
Expected< uint64_t > getRawSize() const
Definition: Archive.cpp:384
bool operator==(const symbol_iterator &other) const
Definition: Archive.h:194
Kind kind() const
Definition: Archive.h:219
Expected< unsigned > getGID() const
Definition: Archive.h:113
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
Expected< uint32_t > getSize() const
Members are not larger than 4GB.
Definition: Archive.cpp:206
Archive(MemoryBufferRef Source, Error &Err)
Definition: Archive.cpp:523
uint64_t getChildOffset() const
Definition: Archive.cpp:468
StringRef getStringTable() const
Definition: Archive.h:246
child_iterator child_begin(Error &Err, bool SkipInternal=true) const
Definition: Archive.cpp:755
const Symbol * operator->() const
Definition: Archive.h:191
StringRef getSymbolTable() const
Definition: Archive.h:245
Expected< llvm::StringRef > getRawName() const
Get the name without looking up long names.
Definition: Archive.cpp:84
std::vector< std::unique_ptr< MemoryBuffer > > takeThinBuffers()
Definition: Archive.h:249
Expected< uint64_t > getSize() const
Definition: Archive.cpp:374
ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err)
Definition: Archive.cpp:37
Child(const Archive *Parent, const char *Start, Error *Err)
Definition: Archive.cpp:307
uint64_t getSizeOf() const
Definition: Archive.h:58
Expected< StringRef > getName() const
Definition: Archive.cpp:475
bool operator==(const child_iterator &other) const
Definition: Archive.h:141
const Symbol & operator*() const
Definition: Archive.h:192
iterator_range< symbol_iterator > symbols() const
Definition: Archive.h:231
LLVM_NODISCARD StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:811
Tagged union holding either a T or a Error.
bool operator!=(const symbol_iterator &other) const
Definition: Archive.h:198
llvm::StringRef getRawLastModified() const
Definition: Archive.h:50
Symbol(const Archive *p, uint32_t symi, uint32_t stri)
Definition: Archive.h:178
Expected< llvm::StringRef > getName(uint64_t Size) const
Get the name looking up long names.
Definition: Archive.cpp:112
iterator begin() const
Definition: StringRef.h:103
Expected< sys::fs::perms > getAccessMode() const
Definition: Archive.h:114
static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)
Definition: Archive.cpp:510
bool hasSymbolTable() const
Definition: Archive.cpp:976
Expected< Child > getNext() const
Definition: Archive.cpp:436
Expected< unsigned > getUID() const
Definition: Archive.h:112
bool operator==(const Child &other) const
Definition: Archive.h:95
child_iterator child_end() const
Definition: Archive.cpp:772
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
StringRef getName() const
Definition: Archive.cpp:776
bool operator==(const Symbol &other) const
Definition: Archive.h:174
bool isThin() const
Definition: Archive.h:220
const Child * operator->() const
Definition: Archive.h:138
Expected< std::string > getFullName() const
Definition: Archive.cpp:396
const Child & operator*() const
Definition: Archive.h:139
const Archive * getParent() const
Definition: Archive.h:100
Expected< std::unique_ptr< Binary > > getAsBinary(LLVMContext *Context=nullptr) const
Definition: Archive.cpp:499
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
symbol_iterator symbol_begin() const
Definition: Archive.cpp:879
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
A range adaptor for a pair of iterators.
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition: Archive.h:106
Helper for Errors used as out-parameters.
Expected< StringRef > getRawName() const
Definition: Archive.h:105
Expected< Child > getMember() const
Definition: Archive.cpp:780
StringRef getRawLastModified() const
Definition: Archive.h:109
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition: Archive.cpp:243
uint32_t getNumberOfSymbols() const
Definition: Archive.cpp:939
Expected< sys::fs::perms > getAccessMode() const
Definition: Archive.cpp:224
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Expected< unsigned > getGID() const
Definition: Archive.cpp:282
bool isEmpty() const
Definition: Archive.cpp:974
static const char * name
Lightweight error class with error context and mandatory checking.
static bool classof(Binary const *v)
Definition: Archive.h:236
Expected< StringRef > getBuffer() const
Definition: Archive.cpp:414
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
bool isArchive() const
Definition: Binary.h:100
Expected< MemoryBufferRef > getMemoryBufferRef() const
Definition: Archive.cpp:487
bool operator!=(const child_iterator &other) const
Definition: Archive.h:148
symbol_iterator & operator++()
Definition: Archive.h:202
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition: Archive.h:224