e1433384bcae19b9639bf2be577581bfe6f16434
[oota-llvm.git] / lib / Object / Archive.cpp
1 //===- Archive.cpp - ar File Format implementation --------------*- 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 defines the ArchiveObjectFile class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Object/Archive.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Support/MemoryBuffer.h"
19
20 using namespace llvm;
21 using namespace object;
22
23 static const char *Magic = "!<arch>\n";
24
25 namespace {
26 struct ArchiveMemberHeader {
27   char Name[16];
28   char LastModified[12];
29   char UID[6];
30   char GID[6];
31   char AccessMode[8];
32   char Size[10]; ///< Size of data, not including header or padding.
33   char Terminator[2];
34
35   ///! Get the name without looking up long names.
36   StringRef getName() const {
37     char EndCond;
38     if (Name[0] == '/' || Name[0] == '#')
39       EndCond = ' ';
40     else
41       EndCond = '/';
42     StringRef::size_type end = StringRef(Name, sizeof(Name)).find(EndCond);
43     if (end == StringRef::npos)
44       end = sizeof(Name);
45     assert(end <= sizeof(Name) && end > 0);
46     // Don't include the EndCond if there is one.
47     return StringRef(Name, end);
48   }
49
50   uint64_t getSize() const {
51     uint64_t ret;
52     if (StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, ret))
53       llvm_unreachable("Size is not an integer.");
54     return ret;
55   }
56 };
57 }
58
59 static const ArchiveMemberHeader *ToHeader(const char *base) {
60   return reinterpret_cast<const ArchiveMemberHeader *>(base);
61 }
62
63
64 static bool isInternalMember(const ArchiveMemberHeader &amh) {
65   static const char *const internals[] = {
66     "/",
67     "//",
68     "#_LLVM_SYM_TAB_#"
69   };
70
71   StringRef name = amh.getName();
72   for (std::size_t i = 0; i < sizeof(internals) / sizeof(*internals); ++i) {
73     if (name == internals[i])
74       return true;
75   }
76   return false;
77 }
78
79 void Archive::anchor() { }
80
81 Archive::Child Archive::Child::getNext() const {
82   size_t SpaceToSkip = sizeof(ArchiveMemberHeader) +
83     ToHeader(Data.data())->getSize();
84   // If it's odd, add 1 to make it even.
85   if (SpaceToSkip & 1)
86     ++SpaceToSkip;
87
88   const char *NextLoc = Data.data() + SpaceToSkip;
89
90   // Check to see if this is past the end of the archive.
91   if (NextLoc >= Parent->Data->getBufferEnd())
92     return Child(Parent, StringRef(0, 0));
93
94   size_t NextSize = sizeof(ArchiveMemberHeader) +
95     ToHeader(NextLoc)->getSize();
96
97   return Child(Parent, StringRef(NextLoc, NextSize));
98 }
99
100 error_code Archive::Child::getName(StringRef &Result) const {
101   StringRef name = ToHeader(Data.data())->getName();
102   // Check if it's a special name.
103   if (name[0] == '/') {
104     if (name.size() == 1) { // Linker member.
105       Result = name;
106       return object_error::success;
107     }
108     if (name.size() == 2 && name[1] == '/') { // String table.
109       Result = name;
110       return object_error::success;
111     }
112     // It's a long name.
113     // Get the offset.
114     std::size_t offset;
115     if (name.substr(1).rtrim(" ").getAsInteger(10, offset))
116       llvm_unreachable("Long name offset is not an integer");
117     const char *addr = Parent->StringTable->Data.begin()
118                        + sizeof(ArchiveMemberHeader)
119                        + offset;
120     // Verify it.
121     if (Parent->StringTable == Parent->end_children()
122         || addr < (Parent->StringTable->Data.begin()
123                    + sizeof(ArchiveMemberHeader))
124         || addr > (Parent->StringTable->Data.begin()
125                    + sizeof(ArchiveMemberHeader)
126                    + Parent->StringTable->getSize()))
127       return object_error::parse_failed;
128
129     // GNU long file names end with a /.
130     if (Parent->kind() == K_GNU) {
131       StringRef::size_type End = StringRef(addr).find('/');
132       Result = StringRef(addr, End);
133     } else {
134       Result = addr;
135     }
136     return object_error::success;
137   } else if (name.startswith("#1/")) {
138     uint64_t name_size;
139     if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
140       llvm_unreachable("Long name length is not an ingeter");
141     Result = Data.substr(sizeof(ArchiveMemberHeader), name_size);
142     return object_error::success;
143   }
144   // It's a simple name.
145   if (name[name.size() - 1] == '/')
146     Result = name.substr(0, name.size() - 1);
147   else
148     Result = name;
149   return object_error::success;
150 }
151
152 uint64_t Archive::Child::getSize() const {
153   uint64_t size = ToHeader(Data.data())->getSize();
154   // Don't include attached name.
155   StringRef name =  ToHeader(Data.data())->getName();
156   if (name.startswith("#1/")) {
157     uint64_t name_size;
158     if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
159       llvm_unreachable("Long name length is not an integer");
160     size -= name_size;
161   }
162   return size;
163 }
164
165 MemoryBuffer *Archive::Child::getBuffer() const {
166   StringRef name = ToHeader(Data.data())->getName();
167   int size = sizeof(ArchiveMemberHeader);
168   if (name.startswith("#1/")) {
169     uint64_t name_size;
170     if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
171       llvm_unreachable("Long name length is not an integer");
172     size += name_size;
173   }
174   if (getName(name))
175     return 0;
176   return MemoryBuffer::getMemBuffer(Data.substr(size, getSize()),
177                                     name,
178                                     false);
179 }
180
181 error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const {
182   OwningPtr<Binary> ret;
183   if (error_code ec =
184     createBinary(getBuffer(), ret))
185     return ec;
186   Result.swap(ret);
187   return object_error::success;
188 }
189
190 Archive::Archive(MemoryBuffer *source, error_code &ec)
191   : Binary(Binary::ID_Archive, source) {
192   // Check for sufficient magic.
193   if (!source || source->getBufferSize()
194                  < (8 + sizeof(ArchiveMemberHeader) + 2) // Smallest archive.
195               || StringRef(source->getBufferStart(), 8) != Magic) {
196     ec = object_error::invalid_file_type;
197     return;
198   }
199
200   // Get the special members.
201   child_iterator i = begin_children(false);
202   child_iterator e = end_children();
203
204   StringRef name;
205   if ((ec = i->getName(name)))
206     return;
207
208   // Below is the pattern that is used to figure out the archive format
209   // GNU archive format
210   //  First member : / (points to the symbol table )
211   //  Second member : // (may exist, if it exists, points to the string table)
212   //  Note : The string table is used if the filename exceeds 15 characters
213   // BSD archive format
214   //  First member : __.SYMDEF (points to the symbol table)
215   //  There is no string table, if the filename exceeds 15 characters or has a 
216   //  embedded space, the filename has #1/<size>, The size represents the size 
217   //  of the filename that needs to be read after the archive header
218   // COFF archive format
219   //  First member : /
220   //  Second member : / (provides a directory of symbols)
221   //  Third member : // contains the string table, this is present even if the
222   //                    string table is empty
223   if (name == "/") {
224     SymbolTable = i;
225     StringTable = e;
226     if (i != e) ++i;
227     if (i == e) {
228       ec = object_error::parse_failed;
229       return;
230     }
231     if ((ec = i->getName(name)))
232       return;
233     if (name[0] != '/') {
234       Format = K_GNU;
235     } else if ((name.size() > 1) && (name == "//")) { 
236       Format = K_GNU;
237       StringTable = i;
238       ++i;
239     } else  { 
240       Format = K_COFF;
241       if (i != e) {
242         SymbolTable = i;
243         ++i;
244       }
245       if (i != e) {
246         StringTable = i;
247       }
248     }
249   } else if (name == "__.SYMDEF") {
250     Format = K_BSD;
251     SymbolTable = i;
252     StringTable = e;
253   } 
254   ec = object_error::success;
255 }
256
257 Archive::child_iterator Archive::begin_children(bool skip_internal) const {
258   const char *Loc = Data->getBufferStart() + strlen(Magic);
259   size_t Size = sizeof(ArchiveMemberHeader) +
260     ToHeader(Loc)->getSize();
261   Child c(this, StringRef(Loc, Size));
262   // Skip internals at the beginning of an archive.
263   if (skip_internal && isInternalMember(*ToHeader(Loc)))
264     return c.getNext();
265   return c;
266 }
267
268 Archive::child_iterator Archive::end_children() const {
269   return Child(this, StringRef(0, 0));
270 }
271
272 error_code Archive::Symbol::getName(StringRef &Result) const {
273   Result =
274     StringRef(Parent->SymbolTable->getBuffer()->getBufferStart() + StringIndex);
275   return object_error::success;
276 }
277
278 error_code Archive::Symbol::getMember(child_iterator &Result) const {
279   const char *Buf = Parent->SymbolTable->getBuffer()->getBufferStart();
280   const char *Offsets = Buf + 4;
281   uint32_t Offset = 0;
282   if (Parent->kind() == K_GNU) {
283     Offset = *(reinterpret_cast<const support::ubig32_t*>(Offsets)
284                + SymbolIndex);
285   } else if (Parent->kind() == K_BSD) {
286     llvm_unreachable("BSD format is not supported");
287   } else {
288     uint32_t MemberCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
289     
290     // Skip offsets.
291     Buf += sizeof(support::ulittle32_t)
292            + (MemberCount * sizeof(support::ulittle32_t));
293
294     uint32_t SymbolCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
295
296     if (SymbolIndex >= SymbolCount)
297       return object_error::parse_failed;
298
299     // Skip SymbolCount to get to the indices table.
300     const char *Indices = Buf + sizeof(support::ulittle32_t);
301
302     // Get the index of the offset in the file member offset table for this
303     // symbol.
304     uint16_t OffsetIndex =
305       *(reinterpret_cast<const support::ulittle16_t*>(Indices)
306         + SymbolIndex);
307     // Subtract 1 since OffsetIndex is 1 based.
308     --OffsetIndex;
309
310     if (OffsetIndex >= MemberCount)
311       return object_error::parse_failed;
312
313     Offset = *(reinterpret_cast<const support::ulittle32_t*>(Offsets)
314                + OffsetIndex);
315   }
316
317   const char *Loc = Parent->getData().begin() + Offset;
318   size_t Size = sizeof(ArchiveMemberHeader) +
319     ToHeader(Loc)->getSize();
320   Result = Child(Parent, StringRef(Loc, Size));
321
322   return object_error::success;
323 }
324
325 Archive::Symbol Archive::Symbol::getNext() const {
326   Symbol t(*this);
327   // Go to one past next null.
328   t.StringIndex =
329     Parent->SymbolTable->getBuffer()->getBuffer().find('\0', t.StringIndex) + 1;
330   ++t.SymbolIndex;
331   return t;
332 }
333
334 Archive::symbol_iterator Archive::begin_symbols() const {
335   const char *buf = SymbolTable->getBuffer()->getBufferStart();
336   if (kind() == K_GNU) {
337     uint32_t symbol_count = 0;
338     symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
339     buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
340   } else if (kind() == K_BSD) {
341     llvm_unreachable("BSD archive format is not supported");
342   } else {
343     uint32_t member_count = 0;
344     uint32_t symbol_count = 0;
345     member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
346     buf += 4 + (member_count * 4); // Skip offsets.
347     symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
348     buf += 4 + (symbol_count * 2); // Skip indices.
349   }
350   uint32_t string_start_offset =
351     buf - SymbolTable->getBuffer()->getBufferStart();
352   return symbol_iterator(Symbol(this, 0, string_start_offset));
353 }
354
355 Archive::symbol_iterator Archive::end_symbols() const {
356   const char *buf = SymbolTable->getBuffer()->getBufferStart();
357   uint32_t symbol_count = 0;
358   if (kind() == K_GNU) {
359     symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
360     buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
361   } else if (kind() == K_BSD) {
362     llvm_unreachable("BSD archive format is not supported");
363   } else {
364     uint32_t member_count = 0;
365     member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
366     buf += 4 + (member_count * 4); // Skip offsets.
367     symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
368   }
369   return symbol_iterator(
370     Symbol(this, symbol_count, 0));
371 }
372
373 Archive::child_iterator Archive::findSym(StringRef name) const {
374   Archive::symbol_iterator bs = begin_symbols();
375   Archive::symbol_iterator es = end_symbols();
376   Archive::child_iterator result;
377   
378   StringRef symname;
379   for (; bs != es; ++bs) {
380     if (bs->getName(symname))
381         return end_children();
382     if (symname == name) {
383       if (bs->getMember(result))
384         return end_children();
385       return result;
386     }
387   }
388   return end_children();
389 }