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