LLVM  6.0.0svn
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"
25 #include <algorithm>
26 #include <cassert>
27 #include <cstdint>
28 #include <memory>
29 #include <string>
30 #include <vector>
31 
32 namespace llvm {
33 namespace object {
34 
35 class Archive;
36 
38 public:
39  friend class Archive;
40 
41  ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr,
42  uint64_t Size, Error *Err);
43  // ArchiveMemberHeader() = default;
44 
45  /// Get the name without looking up long names.
47 
48  /// Get the name looking up long names.
49  Expected<StringRef> getName(uint64_t Size) const;
50 
51  /// Members are not larger than 4GB.
53 
56 
58  return StringRef(ArMemHdr->LastModified,
59  sizeof(ArMemHdr->LastModified)).rtrim(' ');
60  }
61 
62  Expected<unsigned> getUID() const;
63  Expected<unsigned> getGID() const;
64 
65  // This returns the size of the private struct ArMemHdrType
66  uint64_t getSizeOf() const {
67  return sizeof(ArMemHdrType);
68  }
69 
70 private:
71  struct ArMemHdrType {
72  char Name[16];
73  char LastModified[12];
74  char UID[6];
75  char GID[6];
76  char AccessMode[8];
77  char Size[10]; ///< Size of data, not including header or padding.
78  char Terminator[2];
79  };
80  Archive const *Parent;
81  ArMemHdrType const *ArMemHdr;
82 };
83 
84 class Archive : public Binary {
85  virtual void anchor();
86 
87 public:
88  class Child {
89  friend Archive;
90  friend ArchiveMemberHeader;
91 
92  const Archive *Parent;
93  ArchiveMemberHeader Header;
94  /// \brief Includes header but not padding byte.
96  /// \brief Offset from Data to the start of the file.
97  uint16_t StartOfFile;
98 
99  Expected<bool> isThinMember() const;
100 
101  public:
102  Child(const Archive *Parent, const char *Start, Error *Err);
103  Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
104 
105  bool operator ==(const Child &other) const {
106  assert(!Parent || !other.Parent || Parent == other.Parent);
107  return Data.begin() == other.Data.begin();
108  }
109 
110  const Archive *getParent() const { return Parent; }
111  Expected<Child> getNext() const;
112 
114  Expected<std::string> getFullName() const;
115  Expected<StringRef> getRawName() const { return Header.getRawName(); }
116 
118  return Header.getLastModified();
119  }
120 
122  return Header.getRawLastModified();
123  }
124 
125  Expected<unsigned> getUID() const { return Header.getUID(); }
126  Expected<unsigned> getGID() const { return Header.getGID(); }
127 
129  return Header.getAccessMode();
130  }
131 
132  /// \return the size of the archive member without the header or padding.
133  Expected<uint64_t> getSize() const;
134  /// \return the size in the archive header for this member.
135  Expected<uint64_t> getRawSize() const;
136 
137  Expected<StringRef> getBuffer() const;
138  uint64_t getChildOffset() const;
139 
140  Expected<MemoryBufferRef> getMemoryBufferRef() const;
141 
143  getAsBinary(LLVMContext *Context = nullptr) const;
144  };
145 
147  Child C;
148  Error *E = nullptr;
149 
150  public:
151  child_iterator() : C(Child(nullptr, nullptr, nullptr)) {}
152  child_iterator(const Child &C, Error *E) : C(C), E(E) {}
153 
154  const Child *operator->() const { return &C; }
155  const Child &operator*() const { return C; }
156 
157  bool operator==(const child_iterator &other) const {
158  // Ignore errors here: If an error occurred during increment then getNext
159  // will have been set to child_end(), and the following comparison should
160  // do the right thing.
161  return C == other.C;
162  }
163 
164  bool operator!=(const child_iterator &other) const {
165  return !(*this == other);
166  }
167 
168  // Code in loops with child_iterators must check for errors on each loop
169  // iteration. And if there is an error break out of the loop.
170  child_iterator &operator++() { // Preincrement
171  assert(E && "Can't increment iterator with no Error attached");
172  ErrorAsOutParameter ErrAsOutParam(E);
173  if (auto ChildOrErr = C.getNext())
174  C = *ChildOrErr;
175  else {
176  C = C.getParent()->child_end().C;
177  *E = ChildOrErr.takeError();
178  E = nullptr;
179  }
180  return *this;
181  }
182  };
183 
184  class Symbol {
185  const Archive *Parent;
186  uint32_t SymbolIndex;
187  uint32_t StringIndex; // Extra index to the string.
188 
189  public:
190  Symbol(const Archive *p, uint32_t symi, uint32_t stri)
191  : Parent(p)
192  , SymbolIndex(symi)
193  , StringIndex(stri) {}
194 
195  bool operator ==(const Symbol &other) const {
196  return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
197  }
198 
199  StringRef getName() const;
200  Expected<Child> getMember() const;
201  Symbol getNext() const;
202  };
203 
205  Symbol symbol;
206 
207  public:
208  symbol_iterator(const Symbol &s) : symbol(s) {}
209 
210  const Symbol *operator->() const { return &symbol; }
211  const Symbol &operator*() const { return symbol; }
212 
213  bool operator==(const symbol_iterator &other) const {
214  return symbol == other.symbol;
215  }
216 
217  bool operator!=(const symbol_iterator &other) const {
218  return !(*this == other);
219  }
220 
221  symbol_iterator& operator++() { // Preincrement
222  symbol = symbol.getNext();
223  return *this;
224  }
225  };
226 
228  static Expected<std::unique_ptr<Archive>> create(MemoryBufferRef Source);
229 
230  enum Kind {
236  K_COFF
237  };
238 
239  Kind kind() const { return (Kind)Format; }
240  bool isThin() const { return IsThin; }
241 
242  child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
243  child_iterator child_end() const;
245  bool SkipInternal = true) const {
246  return make_range(child_begin(Err, SkipInternal), child_end());
247  }
248 
249  symbol_iterator symbol_begin() const;
250  symbol_iterator symbol_end() const;
252  return make_range(symbol_begin(), symbol_end());
253  }
254 
255  // Cast methods.
256  static bool classof(Binary const *v) {
257  return v->isArchive();
258  }
259 
260  // check if a symbol is in the archive
261  Expected<Optional<Child>> findSym(StringRef name) const;
262 
263  bool isEmpty() const;
264  bool hasSymbolTable() const;
265  StringRef getSymbolTable() const { return SymbolTable; }
266  StringRef getStringTable() const { return StringTable; }
267  uint32_t getNumberOfSymbols() const;
268 
269  std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
270  return std::move(ThinBuffers);
271  }
272 
273 private:
274  StringRef SymbolTable;
275  StringRef StringTable;
276 
277  StringRef FirstRegularData;
278  uint16_t FirstRegularStartOfFile = -1;
279  void setFirstRegular(const Child &C);
280 
281  unsigned Format : 3;
282  unsigned IsThin : 1;
283  mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
284 };
285 
286 } // end namespace object
287 } // end namespace llvm
288 
289 #endif // LLVM_OBJECT_ARCHIVE_H
uint64_t CallInst * C
child_iterator(const Child &C, Error *E)
Definition: Archive.h:152
LLVMContext & Context
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
const Child * operator->() const
Definition: Archive.h:154
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
Expected< Child > getNext() const
Definition: Archive.cpp:453
bool operator==(const child_iterator &other) const
Definition: Archive.h:157
bool operator==(const symbol_iterator &other) const
Definition: Archive.h:213
Expected< StringRef > getRawName() const
Get the name without looking up long names.
Definition: Archive.cpp:101
std::vector< std::unique_ptr< MemoryBuffer > > takeThinBuffers()
Definition: Archive.h:269
ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr, uint64_t Size, Error *Err)
Definition: Archive.cpp:54
StringRef getRawLastModified() const
Definition: Archive.h:121
Expected< unsigned > getUID() const
Definition: Archive.cpp:280
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
Expected< unsigned > getGID() const
Definition: Archive.cpp:299
Symbol(const Archive *p, uint32_t symi, uint32_t stri)
Definition: Archive.h:190
const Child & operator*() const
Definition: Archive.h:155
bool isArchive() const
Definition: Binary.h:101
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition: Archive.h:117
StringRef getRawLastModified() const
Definition: Archive.h:57
uint64_t getSizeOf() const
Definition: Archive.h:66
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
StringRef getStringTable() const
Definition: Archive.h:266
Expected< sys::fs::perms > getAccessMode() const
Definition: Archive.cpp:241
const Symbol & operator*() const
Definition: Archive.h:211
Expected< unsigned > getUID() const
Definition: Archive.h:125
const Symbol * operator->() const
Definition: Archive.h:210
const Archive * getParent() const
Definition: Archive.h:110
Expected< sys::fs::perms > getAccessMode() const
Definition: Archive.h:128
Expected< StringRef > getName(uint64_t Size) const
Get the name looking up long names.
Definition: Archive.cpp:129
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Kind kind() const
Definition: Archive.h:239
bool operator==(const DataRefImpl &a, const DataRefImpl &b)
Definition: SymbolicFile.h:53
A range adaptor for a pair of iterators.
Expected< StringRef > getRawName() const
Definition: Archive.h:115
Helper for Errors used as out-parameters.
Definition: Error.h:990
bool operator!=(const symbol_iterator &other) const
Definition: Archive.h:217
iterator begin() const
Definition: StringRef.h:106
child_iterator child_end() const
Definition: Archive.cpp:789
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition: Archive.h:244
bool operator!=(const child_iterator &other) const
Definition: Archive.h:164
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
Definition: Archive.cpp:260
Expected< uint32_t > getSize() const
Members are not larger than 4GB.
Definition: Archive.cpp:223
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
iterator_range< symbol_iterator > symbols() const
Definition: Archive.h:251
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static bool classof(Binary const *v)
Definition: Archive.h:256
bool isThin() const
Definition: Archive.h:240
LLVM_NODISCARD StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:822
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Expected< unsigned > getGID() const
Definition: Archive.h:126
StringRef getSymbolTable() const
Definition: Archive.h:265
symbol_iterator & operator++()
Definition: Archive.h:221