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