//===-- ArchiveReader.cpp - Read LLVM archive files -------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Builds up standard unix archive files (.a) containing LLVM bitcode.
//
//===----------------------------------------------------------------------===//

#include "ArchiveInternals.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Module.h"
#include <cstdlib>
#include <memory>
using namespace llvm;

/// Read a variable-bit-rate encoded unsigned integer
static inline unsigned readInteger(const char*&At, const char*End) {
  unsigned Shift = 0;
  unsigned Result = 0;

  do {
    if (At == End)
      return Result;
    Result |= (unsigned)((*At++) & 0x7F) << Shift;
    Shift += 7;
  } while (At[-1] & 0x80);
  return Result;
}

// Completely parse the Archive's symbol table and populate symTab member var.
bool
Archive::parseSymbolTable(const void* data, unsigned size, std::string* error) {
  const char* At = (const char*) data;
  const char* End = At + size;
  while (At < End) {
    unsigned offset = readInteger(At, End);
    if (At == End) {
      if (error)
        *error = "Ran out of data reading vbr_uint for symtab offset!";
      return false;
    }
    unsigned length = readInteger(At, End);
    if (At == End) {
      if (error)
        *error = "Ran out of data reading vbr_uint for symtab length!";
      return false;
    }
    if (At + length > End) {
      if (error)
        *error = "Malformed symbol table: length not consistent with size";
      return false;
    }
    // we don't care if it can't be inserted (duplicate entry)
    symTab.insert(std::make_pair(std::string(At, length), offset));
    At += length;
  }
  symTabSize = size;
  return true;
}

// This member parses an ArchiveMemberHeader that is presumed to be pointed to
// by At. The At pointer is updated to the byte just after the header, which
// can be variable in size.
ArchiveMember*
Archive::parseMemberHeader(const char*& At, const char* End, std::string* error)
{
  if (At + sizeof(ArchiveMemberHeader) >= End) {
    if (error)
      *error = "Unexpected end of file";
    return 0;
  }

  // Cast archive member header
  ArchiveMemberHeader* Hdr = (ArchiveMemberHeader*)At;
  At += sizeof(ArchiveMemberHeader);

  // Extract the size and determine if the file is
  // compressed or not (negative length).
  int flags = 0;
  int MemberSize = atoi(Hdr->size);
  if (MemberSize < 0) {
    flags |= ArchiveMember::CompressedFlag;
    MemberSize = -MemberSize;
  }

  // Check the size of the member for sanity
  if (At + MemberSize > End) {
    if (error)
      *error = "invalid member length in archive file";
    return 0;
  }

  // Check the member signature
  if (!Hdr->checkSignature()) {
    if (error)
      *error = "invalid file member signature";
    return 0;
  }

  // Convert and check the member name
  // The empty name ( '/' and 15 blanks) is for a foreign (non-LLVM) symbol
  // table. The special name "//" and 14 blanks is for a string table, used
  // for long file names. This library doesn't generate either of those but
  // it will accept them. If the name starts with #1/ and the remainder is
  // digits, then those digits specify the length of the name that is
  // stored immediately following the header. The special name
  // __LLVM_SYM_TAB__ identifies the symbol table for LLVM bitcode.
  // Anything else is a regular, short filename that is terminated with
  // a '/' and blanks.

  std::string pathname;
  switch (Hdr->name[0]) {
    case '#':
      if (Hdr->name[1] == '1' && Hdr->name[2] == '/') {
        if (isdigit(Hdr->name[3])) {
          unsigned len = atoi(&Hdr->name[3]);
          pathname.assign(At, len);
          At += len;
          MemberSize -= len;
          flags |= ArchiveMember::HasLongFilenameFlag;
        } else {
          if (error)
            *error = "invalid long filename";
          return 0;
        }
      } else if (Hdr->name[1] == '_' &&
                 (0 == memcmp(Hdr->name, ARFILE_LLVM_SYMTAB_NAME, 16))) {
        // The member is using a long file name (>15 chars) format.
        // This format is standard for 4.4BSD and Mac OSX operating
        // systems. LLVM uses it similarly. In this format, the
        // remainder of the name field (after #1/) specifies the
        // length of the file name which occupy the first bytes of
        // the member's data. The pathname already has the #1/ stripped.
        pathname.assign(ARFILE_LLVM_SYMTAB_NAME);
        flags |= ArchiveMember::LLVMSymbolTableFlag;
      }
      break;
    case '/':
      if (Hdr->name[1]== '/') {
        if (0 == memcmp(Hdr->name, ARFILE_STRTAB_NAME, 16)) {
          pathname.assign(ARFILE_STRTAB_NAME);
          flags |= ArchiveMember::StringTableFlag;
        } else {
          if (error)
            *error = "invalid string table name";
          return 0;
        }
      } else if (Hdr->name[1] == ' ') {
        if (0 == memcmp(Hdr->name, ARFILE_SVR4_SYMTAB_NAME, 16)) {
          pathname.assign(ARFILE_SVR4_SYMTAB_NAME);
          flags |= ArchiveMember::SVR4SymbolTableFlag;
        } else {
          if (error)
            *error = "invalid SVR4 symbol table name";
          return 0;
        }
      } else if (isdigit(Hdr->name[1])) {
        unsigned index = atoi(&Hdr->name[1]);
        if (index < strtab.length()) {
          const char* namep = strtab.c_str() + index;
          const char* endp = strtab.c_str() + strtab.length();
          const char* p = namep;
          const char* last_p = p;
          while (p < endp) {
            if (*p == '\n' && *last_p == '/') {
              pathname.assign(namep, last_p - namep);
              flags |= ArchiveMember::HasLongFilenameFlag;
              break;
            }
            last_p = p;
            p++;
          }
          if (p >= endp) {
            if (error)
              *error = "missing name termiantor in string table";
            return 0;
          }
        } else {
          if (error)
            *error = "name index beyond string table";
          return 0;
        }
      }
      break;
    case '_':
      if (Hdr->name[1] == '_' &&
          (0 == memcmp(Hdr->name, ARFILE_BSD4_SYMTAB_NAME, 16))) {
        pathname.assign(ARFILE_BSD4_SYMTAB_NAME);
        flags |= ArchiveMember::BSD4SymbolTableFlag;
        break;
      }
      /* FALL THROUGH */

    default:
      char* slash = (char*) memchr(Hdr->name, '/', 16);
      if (slash == 0)
        slash = Hdr->name + 16;
      pathname.assign(Hdr->name, slash - Hdr->name);
      break;
  }

  // Determine if this is a bitcode file
  switch (sys::IdentifyFileType(At, 4)) {
    case sys::Bitcode_FileType:
      flags |= ArchiveMember::BitcodeFlag;
      break;
    default:
      flags &= ~ArchiveMember::BitcodeFlag;
      break;
  }

  // Instantiate the ArchiveMember to be filled
  ArchiveMember* member = new ArchiveMember(this);

  // Fill in fields of the ArchiveMember
  member->parent = this;
  member->path.set(pathname);
  member->info.fileSize = MemberSize;
  member->info.modTime.fromEpochTime(atoi(Hdr->date));
  unsigned int mode;
  sscanf(Hdr->mode, "%o", &mode);
  member->info.mode = mode;
  member->info.user = atoi(Hdr->uid);
  member->info.group = atoi(Hdr->gid);
  member->flags = flags;
  member->data = At;

  return member;
}

bool
Archive::checkSignature(std::string* error) {
  // Check the magic string at file's header
  if (mapfile->getBufferSize() < 8 || memcmp(base, ARFILE_MAGIC, 8)) {
    if (error)
      *error = "invalid signature for an archive file";
    return false;
  }
  return true;
}

// This function loads the entire archive and fully populates its ilist with
// the members of the archive file. This is typically used in preparation for
// editing the contents of the archive.
bool
Archive::loadArchive(std::string* error) {

  // Set up parsing
  members.clear();
  symTab.clear();
  const char *At = base;
  const char *End = mapfile->getBufferEnd();

  if (!checkSignature(error))
    return false;

  At += 8;  // Skip the magic string.

  bool seenSymbolTable = false;
  bool foundFirstFile = false;
  while (At < End) {
    // parse the member header
    const char* Save = At;
    ArchiveMember* mbr = parseMemberHeader(At, End, error);
    if (!mbr)
      return false;

    // check if this is the foreign symbol table
    if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) {
      // We just save this but don't do anything special
      // with it. It doesn't count as the "first file".
      if (foreignST) {
        // What? Multiple foreign symbol tables? Just chuck it
        // and retain the last one found.
        delete foreignST;
      }
      foreignST = mbr;
      At += mbr->getSize();
      if ((intptr_t(At) & 1) == 1)
        At++;
    } else if (mbr->isStringTable()) {
      // Simply suck the entire string table into a string
      // variable. This will be used to get the names of the
      // members that use the "/ddd" format for their names
      // (SVR4 style long names).
      strtab.assign(At, mbr->getSize());
      At += mbr->getSize();
      if ((intptr_t(At) & 1) == 1)
        At++;
      delete mbr;
    } else if (mbr->isLLVMSymbolTable()) {
      // This is the LLVM symbol table for the archive. If we've seen it
      // already, its an error. Otherwise, parse the symbol table and move on.
      if (seenSymbolTable) {
        if (error)
          *error = "invalid archive: multiple symbol tables";
        return false;
      }
      if (!parseSymbolTable(mbr->getData(), mbr->getSize(), error))
        return false;
      seenSymbolTable = true;
      At += mbr->getSize();
      if ((intptr_t(At) & 1) == 1)
        At++;
      delete mbr; // We don't need this member in the list of members.
    } else {
      // This is just a regular file. If its the first one, save its offset.
      // Otherwise just push it on the list and move on to the next file.
      if (!foundFirstFile) {
        firstFileOffset = Save - base;
        foundFirstFile = true;
      }
      members.push_back(mbr);
      At += mbr->getSize();
      if ((intptr_t(At) & 1) == 1)
        At++;
    }
  }
  return true;
}

// Open and completely load the archive file.
Archive*
Archive::OpenAndLoad(const sys::Path& file, LLVMContext* C, 
                     std::string* ErrorMessage) {
  std::auto_ptr<Archive> result ( new Archive(file, C));
  if (result->mapToMemory(ErrorMessage))
    return 0;
  if (!result->loadArchive(ErrorMessage))
    return 0;
  return result.release();
}

// Get all the bitcode modules from the archive
bool
Archive::getAllModules(std::vector<Module*>& Modules,
                       std::string* ErrMessage) {

  for (iterator I=begin(), E=end(); I != E; ++I) {
    if (I->isBitcode()) {
      std::string FullMemberName = archPath.toString() +
        "(" + I->getPath().toString() + ")";
      MemoryBuffer *Buffer =
        MemoryBuffer::getNewMemBuffer(I->getSize(), FullMemberName.c_str());
      memcpy((char*)Buffer->getBufferStart(), I->getData(), I->getSize());
      
      Module *M = ParseBitcodeFile(Buffer, Context, ErrMessage);
      delete Buffer;
      if (!M)
        return true;

      Modules.push_back(M);
    }
  }
  return false;
}

// Load just the symbol table from the archive file
bool
Archive::loadSymbolTable(std::string* ErrorMsg) {

  // Set up parsing
  members.clear();
  symTab.clear();
  const char *At = base;
  const char *End = mapfile->getBufferEnd();

  // Make sure we're dealing with an archive
  if (!checkSignature(ErrorMsg))
    return false;

  At += 8; // Skip signature

  // Parse the first file member header
  const char* FirstFile = At;
  ArchiveMember* mbr = parseMemberHeader(At, End, ErrorMsg);
  if (!mbr)
    return false;

  if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) {
    // Skip the foreign symbol table, we don't do anything with it
    At += mbr->getSize();
    if ((intptr_t(At) & 1) == 1)
      At++;
    delete mbr;

    // Read the next one
    FirstFile = At;
    mbr = parseMemberHeader(At, End, ErrorMsg);
    if (!mbr) {
      delete mbr;
      return false;
    }
  }

  if (mbr->isStringTable()) {
    // Process the string table entry
    strtab.assign((const char*)mbr->getData(), mbr->getSize());
    At += mbr->getSize();
    if ((intptr_t(At) & 1) == 1)
      At++;
    delete mbr;
    // Get the next one
    FirstFile = At;
    mbr = parseMemberHeader(At, End, ErrorMsg);
    if (!mbr) {
      delete mbr;
      return false;
    }
  }

  // See if its the symbol table
  if (mbr->isLLVMSymbolTable()) {
    if (!parseSymbolTable(mbr->getData(), mbr->getSize(), ErrorMsg)) {
      delete mbr;
      return false;
    }

    At += mbr->getSize();
    if ((intptr_t(At) & 1) == 1)
      At++;
    delete mbr;
    // Can't be any more symtab headers so just advance
    FirstFile = At;
  } else {
    // There's no symbol table in the file. We have to rebuild it from scratch
    // because the intent of this method is to get the symbol table loaded so
    // it can be searched efficiently.
    // Add the member to the members list
    members.push_back(mbr);
  }

  firstFileOffset = FirstFile - base;
  return true;
}

// Open the archive and load just the symbol tables
Archive* Archive::OpenAndLoadSymbols(const sys::Path& file, LLVMContext* C,
                                     std::string* ErrorMessage) {
  std::auto_ptr<Archive> result ( new Archive(file, C) );
  if (result->mapToMemory(ErrorMessage))
    return 0;
  if (!result->loadSymbolTable(ErrorMessage))
    return 0;
  return result.release();
}

// Look up one symbol in the symbol table and return a ModuleProvider for the
// module that defines that symbol.
ModuleProvider*
Archive::findModuleDefiningSymbol(const std::string& symbol, 
                                  std::string* ErrMsg) {
  SymTabType::iterator SI = symTab.find(symbol);
  if (SI == symTab.end())
    return 0;

  // The symbol table was previously constructed assuming that the members were
  // written without the symbol table header. Because VBR encoding is used, the
  // values could not be adjusted to account for the offset of the symbol table
  // because that could affect the size of the symbol table due to VBR encoding.
  // We now have to account for this by adjusting the offset by the size of the
  // symbol table and its header.
  unsigned fileOffset =
    SI->second +                // offset in symbol-table-less file
    firstFileOffset;            // add offset to first "real" file in archive

  // See if the module is already loaded
  ModuleMap::iterator MI = modules.find(fileOffset);
  if (MI != modules.end())
    return MI->second.first;

  // Module hasn't been loaded yet, we need to load it
  const char* modptr = base + fileOffset;
  ArchiveMember* mbr = parseMemberHeader(modptr, mapfile->getBufferEnd(),
                                         ErrMsg);
  if (!mbr)
    return 0;

  // Now, load the bitcode module to get the ModuleProvider
  std::string FullMemberName = archPath.toString() + "(" +
    mbr->getPath().toString() + ")";
  MemoryBuffer *Buffer =MemoryBuffer::getNewMemBuffer(mbr->getSize(),
                                                      FullMemberName.c_str());
  memcpy((char*)Buffer->getBufferStart(), mbr->getData(), mbr->getSize());
  
  ModuleProvider *mp = getBitcodeModuleProvider(Buffer, Context, ErrMsg);
  if (!mp)
    return 0;

  modules.insert(std::make_pair(fileOffset, std::make_pair(mp, mbr)));

  return mp;
}

// Look up multiple symbols in the symbol table and return a set of
// ModuleProviders that define those symbols.
bool
Archive::findModulesDefiningSymbols(std::set<std::string>& symbols,
                                    std::set<ModuleProvider*>& result,
                                    std::string* error) {
  if (!mapfile || !base) {
    if (error)
      *error = "Empty archive invalid for finding modules defining symbols";
    return false;
  }

  if (symTab.empty()) {
    // We don't have a symbol table, so we must build it now but lets also
    // make sure that we populate the modules table as we do this to ensure
    // that we don't load them twice when findModuleDefiningSymbol is called
    // below.

    // Get a pointer to the first file
    const char* At  = base + firstFileOffset;
    const char* End = mapfile->getBufferEnd();

    while ( At < End) {
      // Compute the offset to be put in the symbol table
      unsigned offset = At - base - firstFileOffset;

      // Parse the file's header
      ArchiveMember* mbr = parseMemberHeader(At, End, error);
      if (!mbr)
        return false;

      // If it contains symbols
      if (mbr->isBitcode()) {
        // Get the symbols
        std::vector<std::string> symbols;
        std::string FullMemberName = archPath.toString() + "(" +
          mbr->getPath().toString() + ")";
        ModuleProvider* MP = 
          GetBitcodeSymbols((const unsigned char*)At, mbr->getSize(),
                            FullMemberName, Context, symbols, error);

        if (MP) {
          // Insert the module's symbols into the symbol table
          for (std::vector<std::string>::iterator I = symbols.begin(),
               E=symbols.end(); I != E; ++I ) {
            symTab.insert(std::make_pair(*I, offset));
          }
          // Insert the ModuleProvider and the ArchiveMember into the table of
          // modules.
          modules.insert(std::make_pair(offset, std::make_pair(MP, mbr)));
        } else {
          if (error)
            *error = "Can't parse bitcode member: " + 
              mbr->getPath().toString() + ": " + *error;
          delete mbr;
          return false;
        }
      }

      // Go to the next file location
      At += mbr->getSize();
      if ((intptr_t(At) & 1) == 1)
        At++;
    }
  }

  // At this point we have a valid symbol table (one way or another) so we
  // just use it to quickly find the symbols requested.

  for (std::set<std::string>::iterator I=symbols.begin(),
       E=symbols.end(); I != E;) {
    // See if this symbol exists
    ModuleProvider* mp = findModuleDefiningSymbol(*I,error);
    if (mp) {
      // The symbol exists, insert the ModuleProvider into our result,
      // duplicates wil be ignored
      result.insert(mp);

      // Remove the symbol now that its been resolved, being careful to
      // post-increment the iterator.
      symbols.erase(I++);
    } else {
      ++I;
    }
  }
  return true;
}

bool Archive::isBitcodeArchive() {
  // Make sure the symTab has been loaded. In most cases this should have been
  // done when the archive was constructed, but still,  this is just in case.
  if (symTab.empty())
    if (!loadSymbolTable(0))
      return false;

  // Now that we know it's been loaded, return true
  // if it has a size
  if (symTab.size()) return true;

  // We still can't be sure it isn't a bitcode archive
  if (!loadArchive(0))
    return false;

  std::vector<Module *> Modules;
  std::string ErrorMessage;

  // Scan the archive, trying to load a bitcode member.  We only load one to
  // see if this works.
  for (iterator I = begin(), E = end(); I != E; ++I) {
    if (!I->isBitcode())
      continue;
    
    std::string FullMemberName = 
      archPath.toString() + "(" + I->getPath().toString() + ")";

    MemoryBuffer *Buffer =
      MemoryBuffer::getNewMemBuffer(I->getSize(), FullMemberName.c_str());
    memcpy((char*)Buffer->getBufferStart(), I->getData(), I->getSize());
    Module *M = ParseBitcodeFile(Buffer, Context);
    delete Buffer;
    if (!M)
      return false;  // Couldn't parse bitcode, not a bitcode archive.
    delete M;
    return true;
  }
  
  return false;
}
