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/SmallString.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/MemoryBuffer.h"
19 #include "llvm/Support/Path.h"
20 
21 using namespace llvm;
22 using namespace object;
23 using namespace llvm::support::endian;
24 
25 static const char *const Magic = "!<arch>\n";
26 static const char *const ThinMagic = "!<thin>\n";
27 
28 void Archive::anchor() { }
29 
30 static Error
31 malformedError(Twine Msg) {
32   std::string StringMsg = "truncated or malformed archive (" + Msg.str() + ")";
33   return make_error<GenericBinaryError>(std::move(StringMsg),
34                                         object_error::parse_failed);
35 }
36 
37 StringRef ArchiveMemberHeader::getName() const {
38   char EndCond;
39   if (Name[0] == '/' || Name[0] == '#')
40     EndCond = ' ';
41   else
42     EndCond = '/';
43   llvm::StringRef::size_type end =
44       llvm::StringRef(Name, sizeof(Name)).find(EndCond);
45   if (end == llvm::StringRef::npos)
46     end = sizeof(Name);
47   assert(end <= sizeof(Name) && end > 0);
48   // Don't include the EndCond if there is one.
49   return llvm::StringRef(Name, end);
50 }
51 
52 Expected<uint32_t> ArchiveMemberHeader::getSize() const {
53   uint32_t Ret;
54   if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, Ret)) {
55     std::string Buf;
56     raw_string_ostream OS(Buf);
57     OS.write_escaped(llvm::StringRef(Size, sizeof(Size)).rtrim(" "));
58     OS.flush();
59     return malformedError("characters in size field in archive header are not "
60                           "all decimal numbers: '" + Buf + "'");
61   }
62   return Ret;
63 }
64 
65 sys::fs::perms ArchiveMemberHeader::getAccessMode() const {
66   unsigned Ret;
67   if (StringRef(AccessMode, sizeof(AccessMode)).rtrim(' ').getAsInteger(8, Ret))
68     llvm_unreachable("Access mode is not an octal number.");
69   return static_cast<sys::fs::perms>(Ret);
70 }
71 
72 sys::TimeValue ArchiveMemberHeader::getLastModified() const {
73   unsigned Seconds;
74   if (StringRef(LastModified, sizeof(LastModified)).rtrim(' ')
75           .getAsInteger(10, Seconds))
76     llvm_unreachable("Last modified time not a decimal number.");
77 
78   sys::TimeValue Ret;
79   Ret.fromEpochTime(Seconds);
80   return Ret;
81 }
82 
83 unsigned ArchiveMemberHeader::getUID() const {
84   unsigned Ret;
85   StringRef User = StringRef(UID, sizeof(UID)).rtrim(' ');
86   if (User.empty())
87     return 0;
88   if (User.getAsInteger(10, Ret))
89     llvm_unreachable("UID time not a decimal number.");
90   return Ret;
91 }
92 
93 unsigned ArchiveMemberHeader::getGID() const {
94   unsigned Ret;
95   StringRef Group = StringRef(GID, sizeof(GID)).rtrim(' ');
96   if (Group.empty())
97     return 0;
98   if (Group.getAsInteger(10, Ret))
99     llvm_unreachable("GID time not a decimal number.");
100   return Ret;
101 }
102 
103 Archive::Child::Child(const Archive *Parent, StringRef Data,
104                       uint16_t StartOfFile)
105     : Parent(Parent), Data(Data), StartOfFile(StartOfFile) {}
106 
107 Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
108     : Parent(Parent) {
109   if (!Start)
110     return;
111 
112   uint64_t Size = sizeof(ArchiveMemberHeader);
113   Data = StringRef(Start, Size);
114   if (!isThinMember()) {
115     Expected<uint64_t> MemberSize = getRawSize();
116     if (!MemberSize) {
117       if (Err) {
118         ErrorAsOutParameter ErrAsOutParam(*Err);
119         *Err = MemberSize.takeError();
120       }
121       return;
122     }
123     Size += MemberSize.get();
124     Data = StringRef(Start, Size);
125   }
126 
127   // Setup StartOfFile and PaddingBytes.
128   StartOfFile = sizeof(ArchiveMemberHeader);
129   // Don't include attached name.
130   StringRef Name = getRawName();
131   if (Name.startswith("#1/")) {
132     uint64_t NameSize;
133     if (Name.substr(3).rtrim(' ').getAsInteger(10, NameSize))
134       llvm_unreachable("Long name length is not an integer");
135     StartOfFile += NameSize;
136   }
137 }
138 
139 Expected<uint64_t> Archive::Child::getSize() const {
140   if (Parent->IsThin) {
141     Expected<uint32_t> Size = getHeader()->getSize();
142     if (!Size)
143       return Size.takeError();
144     return Size.get();
145   }
146   return Data.size() - StartOfFile;
147 }
148 
149 Expected<uint64_t> Archive::Child::getRawSize() const {
150   return getHeader()->getSize();
151 }
152 
153 bool Archive::Child::isThinMember() const {
154   StringRef Name = getHeader()->getName();
155   return Parent->IsThin && Name != "/" && Name != "//";
156 }
157 
158 ErrorOr<std::string> Archive::Child::getFullName() const {
159   assert(isThinMember());
160   ErrorOr<StringRef> NameOrErr = getName();
161   if (std::error_code EC = NameOrErr.getError())
162     return EC;
163   StringRef Name = *NameOrErr;
164   if (sys::path::is_absolute(Name))
165     return Name;
166 
167   SmallString<128> FullName = sys::path::parent_path(
168       Parent->getMemoryBufferRef().getBufferIdentifier());
169   sys::path::append(FullName, Name);
170   return StringRef(FullName);
171 }
172 
173 ErrorOr<StringRef> Archive::Child::getBuffer() const {
174   if (!isThinMember()) {
175     Expected<uint32_t> Size = getSize();
176     if (!Size)
177       return errorToErrorCode(Size.takeError());
178     return StringRef(Data.data() + StartOfFile, Size.get());
179   }
180   ErrorOr<std::string> FullNameOrEr = getFullName();
181   if (std::error_code EC = FullNameOrEr.getError())
182     return EC;
183   const std::string &FullName = *FullNameOrEr;
184   ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(FullName);
185   if (std::error_code EC = Buf.getError())
186     return EC;
187   Parent->ThinBuffers.push_back(std::move(*Buf));
188   return Parent->ThinBuffers.back()->getBuffer();
189 }
190 
191 Expected<Archive::Child> Archive::Child::getNext() const {
192   size_t SpaceToSkip = Data.size();
193   // If it's odd, add 1 to make it even.
194   if (SpaceToSkip & 1)
195     ++SpaceToSkip;
196 
197   const char *NextLoc = Data.data() + SpaceToSkip;
198 
199   // Check to see if this is at the end of the archive.
200   if (NextLoc == Parent->Data.getBufferEnd())
201     return Child(Parent, nullptr, nullptr);
202 
203   // Check to see if this is past the end of the archive.
204   if (NextLoc > Parent->Data.getBufferEnd())
205     return malformedError("offset to next archive member past the end of the "
206                           "archive");
207 
208   Error Err;
209   Child Ret(Parent, NextLoc, &Err);
210   if (Err)
211     return std::move(Err);
212   return Ret;
213 }
214 
215 uint64_t Archive::Child::getChildOffset() const {
216   const char *a = Parent->Data.getBuffer().data();
217   const char *c = Data.data();
218   uint64_t offset = c - a;
219   return offset;
220 }
221 
222 ErrorOr<StringRef> Archive::Child::getName() const {
223   StringRef name = getRawName();
224   // Check if it's a special name.
225   if (name[0] == '/') {
226     if (name.size() == 1) // Linker member.
227       return name;
228     if (name.size() == 2 && name[1] == '/') // String table.
229       return name;
230     // It's a long name.
231     // Get the offset.
232     std::size_t offset;
233     if (name.substr(1).rtrim(' ').getAsInteger(10, offset))
234       llvm_unreachable("Long name offset is not an integer");
235 
236     // Verify it.
237     if (offset >= Parent->StringTable.size())
238       return object_error::parse_failed;
239     const char *addr = Parent->StringTable.begin() + offset;
240 
241     // GNU long file names end with a "/\n".
242     if (Parent->kind() == K_GNU || Parent->kind() == K_MIPS64) {
243       StringRef::size_type End = StringRef(addr).find('\n');
244       return StringRef(addr, End - 1);
245     }
246     return StringRef(addr);
247   } else if (name.startswith("#1/")) {
248     uint64_t name_size;
249     if (name.substr(3).rtrim(' ').getAsInteger(10, name_size))
250       llvm_unreachable("Long name length is not an ingeter");
251     return Data.substr(sizeof(ArchiveMemberHeader), name_size).rtrim('\0');
252   } else {
253     // It is not a long name so trim the blanks at the end of the name.
254     if (name[name.size() - 1] != '/') {
255       return name.rtrim(' ');
256     }
257   }
258   // It's a simple name.
259   if (name[name.size() - 1] == '/')
260     return name.substr(0, name.size() - 1);
261   return name;
262 }
263 
264 ErrorOr<MemoryBufferRef> Archive::Child::getMemoryBufferRef() const {
265   ErrorOr<StringRef> NameOrErr = getName();
266   if (std::error_code EC = NameOrErr.getError())
267     return EC;
268   StringRef Name = NameOrErr.get();
269   ErrorOr<StringRef> Buf = getBuffer();
270   if (std::error_code EC = Buf.getError())
271     return EC;
272   return MemoryBufferRef(*Buf, Name);
273 }
274 
275 Expected<std::unique_ptr<Binary>>
276 Archive::Child::getAsBinary(LLVMContext *Context) const {
277   ErrorOr<MemoryBufferRef> BuffOrErr = getMemoryBufferRef();
278   if (std::error_code EC = BuffOrErr.getError())
279     return errorCodeToError(EC);
280 
281   auto BinaryOrErr = createBinary(BuffOrErr.get(), Context);
282   if (BinaryOrErr)
283     return std::move(*BinaryOrErr);
284   return BinaryOrErr.takeError();
285 }
286 
287 Expected<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) {
288   Error Err;
289   std::unique_ptr<Archive> Ret(new Archive(Source, Err));
290   if (Err)
291     return std::move(Err);
292   return std::move(Ret);
293 }
294 
295 void Archive::setFirstRegular(const Child &C) {
296   FirstRegularData = C.Data;
297   FirstRegularStartOfFile = C.StartOfFile;
298 }
299 
300 Archive::Archive(MemoryBufferRef Source, Error &Err)
301     : Binary(Binary::ID_Archive, Source) {
302   ErrorAsOutParameter ErrAsOutParam(Err);
303   StringRef Buffer = Data.getBuffer();
304   // Check for sufficient magic.
305   if (Buffer.startswith(ThinMagic)) {
306     IsThin = true;
307   } else if (Buffer.startswith(Magic)) {
308     IsThin = false;
309   } else {
310     Err = make_error<GenericBinaryError>("File too small to be an archive",
311                                          object_error::invalid_file_type);
312     return;
313   }
314 
315   // Get the special members.
316   child_iterator I = child_begin(Err, false);
317   if (Err)
318     return;
319   child_iterator E = child_end();
320 
321   // This is at least a valid empty archive. Since an empty archive is the
322   // same in all formats, just claim it to be gnu to make sure Format is
323   // initialized.
324   Format = K_GNU;
325 
326   if (I == E) {
327     Err = Error::success();
328     return;
329   }
330   const Child *C = &*I;
331 
332   auto Increment = [&]() {
333     ++I;
334     if (Err)
335       return true;
336     C = &*I;
337     return false;
338   };
339 
340   StringRef Name = C->getRawName();
341 
342   // Below is the pattern that is used to figure out the archive format
343   // GNU archive format
344   //  First member : / (may exist, if it exists, points to the symbol table )
345   //  Second member : // (may exist, if it exists, points to the string table)
346   //  Note : The string table is used if the filename exceeds 15 characters
347   // BSD archive format
348   //  First member : __.SYMDEF or "__.SYMDEF SORTED" (the symbol table)
349   //  There is no string table, if the filename exceeds 15 characters or has a
350   //  embedded space, the filename has #1/<size>, The size represents the size
351   //  of the filename that needs to be read after the archive header
352   // COFF archive format
353   //  First member : /
354   //  Second member : / (provides a directory of symbols)
355   //  Third member : // (may exist, if it exists, contains the string table)
356   //  Note: Microsoft PE/COFF Spec 8.3 says that the third member is present
357   //  even if the string table is empty. However, lib.exe does not in fact
358   //  seem to create the third member if there's no member whose filename
359   //  exceeds 15 characters. So the third member is optional.
360 
361   if (Name == "__.SYMDEF" || Name == "__.SYMDEF_64") {
362     if (Name == "__.SYMDEF")
363       Format = K_BSD;
364     else // Name == "__.SYMDEF_64"
365       Format = K_DARWIN64;
366     // We know that the symbol table is not an external file, so we just assert
367     // there is no error.
368     SymbolTable = *C->getBuffer();
369     if (Increment())
370       return;
371     setFirstRegular(*C);
372 
373     Err = Error::success();
374     return;
375   }
376 
377   if (Name.startswith("#1/")) {
378     Format = K_BSD;
379     // We know this is BSD, so getName will work since there is no string table.
380     ErrorOr<StringRef> NameOrErr = C->getName();
381     if (auto ec = NameOrErr.getError()) {
382       Err = errorCodeToError(ec);
383       return;
384     }
385     Name = NameOrErr.get();
386     if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {
387       // We know that the symbol table is not an external file, so we just
388       // assert there is no error.
389       SymbolTable = *C->getBuffer();
390       if (Increment())
391         return;
392     }
393     else if (Name == "__.SYMDEF_64 SORTED" || Name == "__.SYMDEF_64") {
394       Format = K_DARWIN64;
395       // We know that the symbol table is not an external file, so we just
396       // assert there is no error.
397       SymbolTable = *C->getBuffer();
398       if (Increment())
399         return;
400     }
401     setFirstRegular(*C);
402     return;
403   }
404 
405   // MIPS 64-bit ELF archives use a special format of a symbol table.
406   // This format is marked by `ar_name` field equals to "/SYM64/".
407   // For detailed description see page 96 in the following document:
408   // http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
409 
410   bool has64SymTable = false;
411   if (Name == "/" || Name == "/SYM64/") {
412     // We know that the symbol table is not an external file, so we just assert
413     // there is no error.
414     SymbolTable = *C->getBuffer();
415     if (Name == "/SYM64/")
416       has64SymTable = true;
417 
418     if (Increment())
419       return;
420     if (I == E) {
421       Err = Error::success();
422       return;
423     }
424     Name = C->getRawName();
425   }
426 
427   if (Name == "//") {
428     Format = has64SymTable ? K_MIPS64 : K_GNU;
429     // The string table is never an external member, so we just assert on the
430     // ErrorOr.
431     StringTable = *C->getBuffer();
432     if (Increment())
433       return;
434     setFirstRegular(*C);
435     Err = Error::success();
436     return;
437   }
438 
439   if (Name[0] != '/') {
440     Format = has64SymTable ? K_MIPS64 : K_GNU;
441     setFirstRegular(*C);
442     Err = Error::success();
443     return;
444   }
445 
446   if (Name != "/") {
447     Err = errorCodeToError(object_error::parse_failed);
448     return;
449   }
450 
451   Format = K_COFF;
452   // We know that the symbol table is not an external file, so we just assert
453   // there is no error.
454   SymbolTable = *C->getBuffer();
455 
456   if (Increment())
457     return;
458 
459   if (I == E) {
460     setFirstRegular(*C);
461     Err = Error::success();
462     return;
463   }
464 
465   Name = C->getRawName();
466 
467   if (Name == "//") {
468     // The string table is never an external member, so we just assert on the
469     // ErrorOr.
470     StringTable = *C->getBuffer();
471     if (Increment())
472       return;
473   }
474 
475   setFirstRegular(*C);
476   Err = Error::success();
477 }
478 
479 Archive::child_iterator Archive::child_begin(Error &Err,
480                                              bool SkipInternal) const {
481   if (Data.getBufferSize() == 8) // empty archive.
482     return child_end();
483 
484   if (SkipInternal)
485     return child_iterator(Child(this, FirstRegularData,
486                                 FirstRegularStartOfFile),
487                           &Err);
488 
489   const char *Loc = Data.getBufferStart() + strlen(Magic);
490   Child C(this, Loc, &Err);
491   if (Err)
492     return child_end();
493   return child_iterator(C, &Err);
494 }
495 
496 Archive::child_iterator Archive::child_end() const {
497   return child_iterator(Child(this, nullptr, nullptr), nullptr);
498 }
499 
500 StringRef Archive::Symbol::getName() const {
501   return Parent->getSymbolTable().begin() + StringIndex;
502 }
503 
504 ErrorOr<Archive::Child> Archive::Symbol::getMember() const {
505   const char *Buf = Parent->getSymbolTable().begin();
506   const char *Offsets = Buf;
507   if (Parent->kind() == K_MIPS64 || Parent->kind() == K_DARWIN64)
508     Offsets += sizeof(uint64_t);
509   else
510     Offsets += sizeof(uint32_t);
511   uint32_t Offset = 0;
512   if (Parent->kind() == K_GNU) {
513     Offset = read32be(Offsets + SymbolIndex * 4);
514   } else if (Parent->kind() == K_MIPS64) {
515     Offset = read64be(Offsets + SymbolIndex * 8);
516   } else if (Parent->kind() == K_BSD) {
517     // The SymbolIndex is an index into the ranlib structs that start at
518     // Offsets (the first uint32_t is the number of bytes of the ranlib
519     // structs).  The ranlib structs are a pair of uint32_t's the first
520     // being a string table offset and the second being the offset into
521     // the archive of the member that defines the symbol.  Which is what
522     // is needed here.
523     Offset = read32le(Offsets + SymbolIndex * 8 + 4);
524   } else if (Parent->kind() == K_DARWIN64) {
525     // The SymbolIndex is an index into the ranlib_64 structs that start at
526     // Offsets (the first uint64_t is the number of bytes of the ranlib_64
527     // structs).  The ranlib_64 structs are a pair of uint64_t's the first
528     // being a string table offset and the second being the offset into
529     // the archive of the member that defines the symbol.  Which is what
530     // is needed here.
531     Offset = read64le(Offsets + SymbolIndex * 16 + 8);
532   } else {
533     // Skip offsets.
534     uint32_t MemberCount = read32le(Buf);
535     Buf += MemberCount * 4 + 4;
536 
537     uint32_t SymbolCount = read32le(Buf);
538     if (SymbolIndex >= SymbolCount)
539       return object_error::parse_failed;
540 
541     // Skip SymbolCount to get to the indices table.
542     const char *Indices = Buf + 4;
543 
544     // Get the index of the offset in the file member offset table for this
545     // symbol.
546     uint16_t OffsetIndex = read16le(Indices + SymbolIndex * 2);
547     // Subtract 1 since OffsetIndex is 1 based.
548     --OffsetIndex;
549 
550     if (OffsetIndex >= MemberCount)
551       return object_error::parse_failed;
552 
553     Offset = read32le(Offsets + OffsetIndex * 4);
554   }
555 
556   const char *Loc = Parent->getData().begin() + Offset;
557   Error Err;
558   Child C(Parent, Loc, &Err);
559   if (Err)
560     return errorToErrorCode(std::move(Err));
561   return C;
562 }
563 
564 Archive::Symbol Archive::Symbol::getNext() const {
565   Symbol t(*this);
566   if (Parent->kind() == K_BSD) {
567     // t.StringIndex is an offset from the start of the __.SYMDEF or
568     // "__.SYMDEF SORTED" member into the string table for the ranlib
569     // struct indexed by t.SymbolIndex .  To change t.StringIndex to the
570     // offset in the string table for t.SymbolIndex+1 we subtract the
571     // its offset from the start of the string table for t.SymbolIndex
572     // and add the offset of the string table for t.SymbolIndex+1.
573 
574     // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
575     // which is the number of bytes of ranlib structs that follow.  The ranlib
576     // structs are a pair of uint32_t's the first being a string table offset
577     // and the second being the offset into the archive of the member that
578     // define the symbol. After that the next uint32_t is the byte count of
579     // the string table followed by the string table.
580     const char *Buf = Parent->getSymbolTable().begin();
581     uint32_t RanlibCount = 0;
582     RanlibCount = read32le(Buf) / 8;
583     // If t.SymbolIndex + 1 will be past the count of symbols (the RanlibCount)
584     // don't change the t.StringIndex as we don't want to reference a ranlib
585     // past RanlibCount.
586     if (t.SymbolIndex + 1 < RanlibCount) {
587       const char *Ranlibs = Buf + 4;
588       uint32_t CurRanStrx = 0;
589       uint32_t NextRanStrx = 0;
590       CurRanStrx = read32le(Ranlibs + t.SymbolIndex * 8);
591       NextRanStrx = read32le(Ranlibs + (t.SymbolIndex + 1) * 8);
592       t.StringIndex -= CurRanStrx;
593       t.StringIndex += NextRanStrx;
594     }
595   } else {
596     // Go to one past next null.
597     t.StringIndex = Parent->getSymbolTable().find('\0', t.StringIndex) + 1;
598   }
599   ++t.SymbolIndex;
600   return t;
601 }
602 
603 Archive::symbol_iterator Archive::symbol_begin() const {
604   if (!hasSymbolTable())
605     return symbol_iterator(Symbol(this, 0, 0));
606 
607   const char *buf = getSymbolTable().begin();
608   if (kind() == K_GNU) {
609     uint32_t symbol_count = 0;
610     symbol_count = read32be(buf);
611     buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
612   } else if (kind() == K_MIPS64) {
613     uint64_t symbol_count = read64be(buf);
614     buf += sizeof(uint64_t) + (symbol_count * (sizeof(uint64_t)));
615   } else if (kind() == K_BSD) {
616     // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
617     // which is the number of bytes of ranlib structs that follow.  The ranlib
618     // structs are a pair of uint32_t's the first being a string table offset
619     // and the second being the offset into the archive of the member that
620     // define the symbol. After that the next uint32_t is the byte count of
621     // the string table followed by the string table.
622     uint32_t ranlib_count = 0;
623     ranlib_count = read32le(buf) / 8;
624     const char *ranlibs = buf + 4;
625     uint32_t ran_strx = 0;
626     ran_strx = read32le(ranlibs);
627     buf += sizeof(uint32_t) + (ranlib_count * (2 * (sizeof(uint32_t))));
628     // Skip the byte count of the string table.
629     buf += sizeof(uint32_t);
630     buf += ran_strx;
631   } else if (kind() == K_DARWIN64) {
632     // The __.SYMDEF_64 or "__.SYMDEF_64 SORTED" member starts with a uint64_t
633     // which is the number of bytes of ranlib_64 structs that follow.  The
634     // ranlib_64 structs are a pair of uint64_t's the first being a string
635     // table offset and the second being the offset into the archive of the
636     // member that define the symbol. After that the next uint64_t is the byte
637     // count of the string table followed by the string table.
638     uint64_t ranlib_count = 0;
639     ranlib_count = read64le(buf) / 16;
640     const char *ranlibs = buf + 8;
641     uint64_t ran_strx = 0;
642     ran_strx = read64le(ranlibs);
643     buf += sizeof(uint64_t) + (ranlib_count * (2 * (sizeof(uint64_t))));
644     // Skip the byte count of the string table.
645     buf += sizeof(uint64_t);
646     buf += ran_strx;
647   } else {
648     uint32_t member_count = 0;
649     uint32_t symbol_count = 0;
650     member_count = read32le(buf);
651     buf += 4 + (member_count * 4); // Skip offsets.
652     symbol_count = read32le(buf);
653     buf += 4 + (symbol_count * 2); // Skip indices.
654   }
655   uint32_t string_start_offset = buf - getSymbolTable().begin();
656   return symbol_iterator(Symbol(this, 0, string_start_offset));
657 }
658 
659 Archive::symbol_iterator Archive::symbol_end() const {
660   return symbol_iterator(Symbol(this, getNumberOfSymbols(), 0));
661 }
662 
663 uint32_t Archive::getNumberOfSymbols() const {
664   if (!hasSymbolTable())
665     return 0;
666   const char *buf = getSymbolTable().begin();
667   if (kind() == K_GNU)
668     return read32be(buf);
669   if (kind() == K_MIPS64)
670     return read64be(buf);
671   if (kind() == K_BSD)
672     return read32le(buf) / 8;
673   if (kind() == K_DARWIN64)
674     return read64le(buf) / 16;
675   uint32_t member_count = 0;
676   member_count = read32le(buf);
677   buf += 4 + (member_count * 4); // Skip offsets.
678   return read32le(buf);
679 }
680 
681 Expected<Optional<Archive::Child>> Archive::findSym(StringRef name) const {
682   Archive::symbol_iterator bs = symbol_begin();
683   Archive::symbol_iterator es = symbol_end();
684 
685   for (; bs != es; ++bs) {
686     StringRef SymName = bs->getName();
687     if (SymName == name) {
688       if (auto MemberOrErr = bs->getMember())
689         return Child(*MemberOrErr);
690       else
691         return errorCodeToError(MemberOrErr.getError());
692     }
693   }
694   return Optional<Child>();
695 }
696 
697 bool Archive::hasSymbolTable() const { return !SymbolTable.empty(); }
698