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