// import-archive.cc -- Go frontend read import data from an archive file.

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go-system.h"

#include "go-diagnostics.h"
#include "import.h"

#ifndef O_BINARY
#define O_BINARY 0
#endif

// Archive magic numbers.

static const char armag[] =
{
  '!', '<', 'a', 'r', 'c', 'h', '>', '\n'
};

static const char armagt[] =
{
  '!', '<', 't', 'h', 'i', 'n', '>', '\n'
};

static const char armagb[] =
{
  '<', 'b', 'i', 'g', 'a', 'f', '>', '\n'
};

static const char arfmag[2] = { '`', '\n' };

// Archive fixed length header for AIX big format.

struct Archive_fl_header
{
  // Archive magic string.
  char fl_magic[8];
  // Offset to member table.
  char fl_memoff[20];
  // Offset to global symbol table.
  char fl_gstoff[20];
  // Offset to global symbol table for 64-bit objects.
  char fl_gst64off[20];
  // Offset to first archive member.
  char fl_fstmoff[20];
  // Offset to last archive member.
  char fl_lstmoff[20];
  // Offset to first member on free list.
  char fl_freeoff[20];
};

// The header of an entry in an archive.  This is all readable text,
// padded with spaces where necesary.

struct Archive_header
{
  // The entry name.
  char ar_name[16];
  // The file modification time.
  char ar_date[12];
  // The user's UID in decimal.
  char ar_uid[6];
  // The user's GID in decimal.
  char ar_gid[6];
  // The file mode in octal.
  char ar_mode[8];
  // The file size in decimal.
  char ar_size[10];
  // The final magic code.
  char ar_fmag[2];
};

// The header of an entry in an AIX big archive.
// This is followed by ar_namlen bytes + 2 bytes for arfmag.

struct Archive_big_header
{
  // The file size in decimal.
  char ar_size[20];
  // The next member offset in decimal.
  char ar_nxtmem[20];
  // The previous member offset in decimal.
  char ar_prvmem[20];
  // The file modification time in decimal.
  char ar_date[12];
  // The user's UID in decimal.
  char ar_uid[12];
  // The user's GID in decimal.
  char ar_gid[12];
  // The file mode in octal.
  char ar_mode[12];
  // The file name length in decimal.
  char ar_namlen[4];
};

// The functions in this file extract Go export data from an archive.

const int Import::archive_magic_len;

// Return true if BYTES, which are from the start of the file, are an
// archive magic number.

bool
Import::is_archive_magic(const char* bytes)
{
  return (memcmp(bytes, armag, Import::archive_magic_len) == 0
	  || memcmp(bytes, armagt, Import::archive_magic_len) == 0
	  || memcmp(bytes, armagb, Import::archive_magic_len) == 0);
}

// An object used to read an archive file.

class Archive_file
{
 public:
  Archive_file(const std::string& filename, int fd, Location location)
    : filename_(filename), fd_(fd), filesize_(-1), first_member_offset_(0),
      extended_names_(), is_thin_archive_(false), is_big_archive_(false),
      location_(location), nested_archives_()
  { }

  // Initialize.
  bool
  initialize();

  // Return the file name.
  const std::string&
  filename() const
  { return this->filename_; }

  // Get the file size.
  off_t
  filesize() const
  { return this->filesize_; }

  // Return the offset of the first member.
  off_t
  first_member_offset() const
  { return this->first_member_offset_; }

  // Return whether this is a thin archive.
  bool
  is_thin_archive() const
  { return this->is_thin_archive_; }

  // Return whether this is a big archive.
  bool
  is_big_archive() const
  { return this->is_big_archive_; }

  // Return the location of the import statement.
  Location
  location() const
  { return this->location_; }

  // Read bytes.
  bool
  read(off_t offset, off_t size, char*);

  // Parse a decimal in readable text.
  bool
  parse_decimal(const char* str, off_t size, long* res) const;

  // Read the archive header at OFF, setting *PNAME, *SIZE,
  // *NESTED_OFF and *NEXT_OFF.
  bool
  read_header(off_t off, std::string* pname, off_t* size, off_t* nested_off,
              off_t* next_off);

  // Interpret the header of HDR, the header of the archive member at
  // file offset OFF.  Return whether it succeeded.  Set *SIZE to the
  // size of the member.  Set *PNAME to the name of the member.  Set
  // *NESTED_OFF to the offset in a nested archive.
  bool
  interpret_header(const Archive_header* hdr, off_t off,
		   std::string* pname, off_t* size, off_t* nested_off) const;

  // Get the file and offset for an archive member.
  bool
  get_file_and_offset(off_t off, const std::string& hdrname,
		      off_t nested_off, int* memfd, off_t* memoff,
		      std::string* memname);

 private:
  // Initialize a big archive (AIX)
  bool
  initialize_big_archive();

  // Initialize a normal archive
  bool
  initialize_archive();

  // Read the big archive header at OFF, setting *PNAME, *SIZE and *NEXT_OFF.
  bool
  read_big_archive_header(off_t off, std::string* pname,
                          off_t* size, off_t* next_off);

  // Read the normal archive header at OFF, setting *PNAME, *SIZE,
  // *NESTED_OFF and *NEXT_OFF.
  bool
  read_archive_header(off_t off, std::string* pname, off_t* size,
                      off_t* nested_off, off_t* next_off);

  // For keeping track of open nested archives in a thin archive file.
  typedef std::map<std::string, Archive_file*> Nested_archive_table;

  // The name of the file.
  std::string filename_;
  // The file descriptor.
  int fd_;
  // The file size;
  off_t filesize_;
  // The first member offset;
  off_t first_member_offset_;
  // The extended name table.
  std::string extended_names_;
  // Whether this is a thin archive.
  bool is_thin_archive_;
  // Whether this is a big archive.
  bool is_big_archive_;
  // The location of the import statements.
  Location location_;
  // Table of nested archives.
  Nested_archive_table nested_archives_;
};

bool
Archive_file::initialize()
{
  struct stat st;
  if (fstat(this->fd_, &st) < 0)
    {
      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
      return false;
    }
  this->filesize_ = st.st_size;

  char buf[sizeof(armagt)];
  if (::lseek(this->fd_, 0, SEEK_SET) < 0
      || ::read(this->fd_, buf, sizeof(armagt)) != sizeof(armagt))
    {
      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
      return false;
    }
  if (memcmp(buf, armagt, sizeof(armagt)) == 0)
    this->is_thin_archive_ = true;
  else if (memcmp(buf, armagb, sizeof(armagb)) == 0)
    this->is_big_archive_ = true;

  if (this->is_big_archive_)
    return this->initialize_big_archive();
  else
    return this->initialize_archive();
}

// Initialize a big archive (AIX).

bool
Archive_file::initialize_big_archive()
{
  Archive_fl_header flhdr;

  // Read the fixed length header.
  if (::lseek(this->fd_, 0, SEEK_SET) < 0
      || ::read(this->fd_, &flhdr, sizeof(flhdr)) != sizeof(flhdr))
    {
      go_error_at(this->location_, "%s: could not read archive header",
                  this->filename_.c_str());
      return false;
    }

  // Parse offset of the first member.
  long off;
  if (!this->parse_decimal(flhdr.fl_fstmoff, sizeof(flhdr.fl_fstmoff), &off))
    {
      char* buf = new char[sizeof(flhdr.fl_fstmoff) + 1];
      memcpy(buf, flhdr.fl_fstmoff, sizeof(flhdr.fl_fstmoff));
      go_error_at(this->location_,
                  ("%s: malformed first member offset in archive header"
                   " (expected decimal, got %s)"),
                  this->filename_.c_str(), buf);
      delete[] buf;
      return false;
    }
  if (off == 0) // Empty archive.
    this->first_member_offset_ = this->filesize_;
  else
    this->first_member_offset_ = off;
  return true;
}

// Initialize a normal archive.

bool
Archive_file::initialize_archive()
{
  this->first_member_offset_ = sizeof(armag);
  if (this->first_member_offset_ == this->filesize_)
    {
      // Empty archive.
      return true;
    }

  // Look for the extended name table.
  std::string filename;
  off_t size;
  off_t next_off;
  if (!this->read_header(this->first_member_offset_, &filename,
                         &size, NULL, &next_off))
    return false;
  if (filename.empty())
    {
      // We found the symbol table.
      if (!this->read_header(next_off, &filename, &size, NULL, NULL))
	filename.clear();
    }
  if (filename == "/")
    {
      char* rdbuf = new char[size];
      if (::read(this->fd_, rdbuf, size) != size)
	{
	  go_error_at(this->location_, "%s: could not read extended names",
		   filename.c_str());
	  delete[] rdbuf;
	  return false;
	}
      this->extended_names_.assign(rdbuf, size);
      delete[] rdbuf;
    }

  return true;
}

// Read bytes from the file.

bool
Archive_file::read(off_t offset, off_t size, char* buf)
{
  if (::lseek(this->fd_, offset, SEEK_SET) < 0
      || ::read(this->fd_, buf, size) != size)
    {
      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
      return false;
    }
  return true;
}

// Parse a decimal in readable text.

bool
Archive_file::parse_decimal(const char* str, off_t size, long* res) const
{
  char* buf = new char[size + 1];
  memcpy(buf, str, size);
  char* ps = buf + size;
  while (ps > buf && ps[-1] == ' ')
    --ps;
  *ps = '\0';

  errno = 0;
  char* end;
  *res = strtol(buf, &end, 10);
  if (*end != '\0'
      || *res < 0
      || (*res == LONG_MAX && errno == ERANGE))
    {
      delete[] buf;
      return false;
    }
  delete[] buf;
  return true;
}

// Read the header at OFF.  Set *PNAME to the name, *SIZE to the size,
// *NESTED_OFF to the nested offset, and *NEXT_OFF to the next member offset.

bool
Archive_file::read_header(off_t off, std::string* pname, off_t* size,
			  off_t* nested_off, off_t* next_off)
{
  if (::lseek(this->fd_, off, SEEK_SET) < 0)
    {
      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
      return false;
    }
  if (this->is_big_archive_)
    return this->read_big_archive_header(off, pname, size, next_off);
  else
    return this->read_archive_header(off, pname, size, nested_off, next_off);
}

// Read the big archive header at OFF, setting *PNAME, *SIZE and *NEXT_OFF.

bool
Archive_file::read_big_archive_header(off_t off, std::string* pname,
                                      off_t* size, off_t* next_off)
{
  Archive_big_header hdr;
  ssize_t got;

  got = ::read(this->fd_, &hdr, sizeof hdr);
  if (got != sizeof hdr)
    {
      if (got < 0)
        go_error_at(this->location_, "%s: %m", this->filename_.c_str());
      else if (got > 0)
        go_error_at(this->location_, "%s: short entry header at %ld",
                    this->filename_.c_str(), static_cast<long>(off));
      else
        go_error_at(this->location_, "%s: unexpected EOF at %ld",
                    this->filename_.c_str(), static_cast<long>(off));
    }

  long local_size;
  if (!this->parse_decimal(hdr.ar_size, sizeof(hdr.ar_size), &local_size))
    {
      char* buf = new char[sizeof(hdr.ar_size) + 1];
      memcpy(buf, hdr.ar_size, sizeof(hdr.ar_size));
      go_error_at(this->location_,
                  ("%s: malformed size in entry header at %ld"
                   " (expected decimal, got %s)"),
                  this->filename_.c_str(), static_cast<long>(off), buf);
      delete[] buf;
      return false;
    }
  *size = local_size;

  long namlen;
  if (!this->parse_decimal(hdr.ar_namlen, sizeof(hdr.ar_namlen), &namlen))
    {
      char* buf = new char[sizeof(hdr.ar_namlen) + 1];
      memcpy(buf, hdr.ar_namlen, sizeof(hdr.ar_namlen));
      go_error_at(this->location_,
                  ("%s: malformed name length in entry header at %ld"
                   " (expected decimal, got %s)"),
                  this->filename_.c_str(), static_cast<long>(off), buf);
      delete[] buf;
      return false;
    }
  // Read member name following member header.
  char* rdbuf = new char[namlen];
  got = ::read(this->fd_, rdbuf, namlen);
  if (got != namlen)
    {
      go_error_at(this->location_,
                  "%s: malformed member name in entry header at %ld",
                  this->filename_.c_str(), static_cast<long>(off));
      delete[] rdbuf;
      return false;
    }
  pname->assign(rdbuf, namlen);
  delete[] rdbuf;

  long local_next_off;
  if (!this->parse_decimal(hdr.ar_nxtmem, sizeof(hdr.ar_nxtmem), &local_next_off))
    {
      char* buf = new char[sizeof(hdr.ar_nxtmem) + 1];
      memcpy(buf, hdr.ar_nxtmem, sizeof(hdr.ar_nxtmem));
      go_error_at(this->location_,
                  ("%s: malformed next member offset in entry header at %ld"
                   " (expected decimal, got %s)"),
                  this->filename_.c_str(), static_cast<long>(off), buf);
      delete[] buf;
      return false;
    }
  if (next_off != NULL)
    {
      if (local_next_off == 0) // Last member.
        *next_off = this->filesize_;
      else
        *next_off = local_next_off;
    }
  return true;
}

// Read the normal archive header at OFF, setting *PNAME, *SIZE,
// *NESTED_OFF and *NEXT_OFF.

bool
Archive_file::read_archive_header(off_t off, std::string* pname, off_t* size,
                                  off_t* nested_off, off_t* next_off)
{
  Archive_header hdr;
  ssize_t got = ::read(this->fd_, &hdr, sizeof hdr);
  if (got != sizeof hdr)
    {
      if (got < 0)
	go_error_at(this->location_, "%s: %m", this->filename_.c_str());
      else if (got > 0)
	go_error_at(this->location_, "%s: short archive header at %ld",
		    this->filename_.c_str(), static_cast<long>(off));
      else
	go_error_at(this->location_, "%s: unexpected EOF at %ld",
		    this->filename_.c_str(), static_cast<long>(off));
    }
  off_t local_nested_off;
  if (!this->interpret_header(&hdr, off, pname, size, &local_nested_off))
    return false;
  if (nested_off != NULL)
    *nested_off = local_nested_off;

  off_t local_next_off;
  local_next_off = off + sizeof(Archive_header);
  if (!this->is_thin_archive_ || pname->empty() || *pname == "/")
    local_next_off += *size;
  if ((local_next_off & 1) != 0)
    ++local_next_off;
  if (local_next_off > this->filesize_) // Last member.
    local_next_off = this->filesize_;
  if (next_off != NULL)
    *next_off = local_next_off;
  return true;
}

// Interpret the header of HDR, the header of the archive member at
// file offset OFF.

bool
Archive_file::interpret_header(const Archive_header* hdr, off_t off,
			       std::string* pname, off_t* size,
			       off_t* nested_off) const
{
  if (memcmp(hdr->ar_fmag, arfmag, sizeof arfmag) != 0)
    {
      go_error_at(this->location_, "%s: malformed archive header at %lu",
		  this->filename_.c_str(), static_cast<unsigned long>(off));
      return false;
    }

  long local_size;
  if (!this->parse_decimal(hdr->ar_size, sizeof hdr->ar_size, &local_size))
    {
      go_error_at(this->location_, "%s: malformed archive header size at %lu",
		  this->filename_.c_str(), static_cast<unsigned long>(off));
      return false;
    }
  *size = local_size;

  *nested_off = 0;
  if (hdr->ar_name[0] != '/')
    {
      const char* name_end = strchr(hdr->ar_name, '/');
      if (name_end == NULL
	  || name_end - hdr->ar_name >= static_cast<int>(sizeof hdr->ar_name))
	{
	  go_error_at(this->location_,
		      "%s: malformed archive header name at %lu",
		      this->filename_.c_str(), static_cast<unsigned long>(off));
	  return false;
	}
      pname->assign(hdr->ar_name, name_end - hdr->ar_name);
    }
  else if (hdr->ar_name[1] == ' ')
    {
      // This is the symbol table.
      pname->clear();
    }
  else if (hdr->ar_name[1] == 'S' && hdr->ar_name[2] == 'Y'
	   && hdr->ar_name[3] == 'M' && hdr->ar_name[4] == '6'
	   && hdr->ar_name[5] == '4' && hdr->ar_name[6] == '/'
	   && hdr->ar_name[7] == ' '
	  )
    {
      // 64-bit symbol table.
      pname->clear();
    }
  else if (hdr->ar_name[1] == '/')
    {
      // This is the extended name table.
      pname->assign(1, '/');
    }
  else
    {
      char* end;
      errno = 0;
      long x = strtol(hdr->ar_name + 1, &end, 10);
      long y = 0;
      if (*end == ':')
        y = strtol(end + 1, &end, 10);
      if (*end != ' '
	  || x < 0
	  || (x == LONG_MAX && errno == ERANGE)
	  || static_cast<size_t>(x) >= this->extended_names_.size())
	{
	  go_error_at(this->location_, "%s: bad extended name index at %lu",
		      this->filename_.c_str(), static_cast<unsigned long>(off));
	  return false;
	}

      const char* name = this->extended_names_.data() + x;
      const char* name_end = strchr(name, '\n');
      if (static_cast<size_t>(name_end - name) > this->extended_names_.size()
	  || name_end[-1] != '/')
	{
	  go_error_at(this->location_,
		      "%s: bad extended name entry at header %lu",
		      this->filename_.c_str(), static_cast<unsigned long>(off));
	  return false;
	}
      pname->assign(name, name_end - 1 - name);
      *nested_off = y;
    }

  return true;
}

// Get the file and offset for an archive member.

bool
Archive_file::get_file_and_offset(off_t off, const std::string& hdrname,
				  off_t nested_off, int* memfd, off_t* memoff,
				  std::string* memname)
{
  if (this->is_big_archive_)
    {
      *memfd = this->fd_;
      *memoff = (off + sizeof(Archive_big_header) + hdrname.length()
                 + sizeof(arfmag));
      if ((*memoff & 1) != 0)
        ++*memoff;
      *memname = this->filename_ + '(' + hdrname + ')';
      return true;
    }
  else if (!this->is_thin_archive_)
    {
      *memfd = this->fd_;
      *memoff = off + sizeof(Archive_header);
      *memname = this->filename_ + '(' + hdrname + ')';
      return true;
    }

  std::string filename = hdrname;
  if (!IS_ABSOLUTE_PATH(filename.c_str()))
    {
      const char* archive_path = this->filename_.c_str();
      const char* basename = lbasename(archive_path);
      if (basename > archive_path)
	filename.replace(0, 0,
			 this->filename_.substr(0, basename - archive_path));
    }

  if (nested_off > 0)
    {
      // This is a member of a nested archive.
      Archive_file* nfile;
      Nested_archive_table::const_iterator p =
	this->nested_archives_.find(filename);
      if (p != this->nested_archives_.end())
	nfile = p->second;
      else
	{
	  int nfd = open(filename.c_str(), O_RDONLY | O_BINARY);
	  if (nfd < 0)
	    {
	      go_error_at(this->location_, "%s: cannot open nested archive %s",
			  this->filename_.c_str(), filename.c_str());
	      return false;
	    }
	  nfile = new Archive_file(filename, nfd, this->location_);
	  if (!nfile->initialize())
	    {
	      delete nfile;
	      return false;
	    }
	  this->nested_archives_[filename] = nfile;
	}

      std::string nname;
      off_t nsize;
      off_t nnested_off;
      if (!nfile->read_header(nested_off, &nname, &nsize, &nnested_off, NULL))
	return false;
      return nfile->get_file_and_offset(nested_off, nname, nnested_off,
					memfd, memoff, memname);
    }

  // An external member of a thin archive.
  *memfd = open(filename.c_str(), O_RDONLY | O_BINARY);
  if (*memfd < 0)
    {
      go_error_at(this->location_, "%s: %m", filename.c_str());
      return false;
    }
  *memoff = 0;
  *memname = filename;
  return true;
}

// An archive member iterator.  This is more-or-less copied from gold.

class Archive_iterator
{
 public:
  // The header of an archive member.  This is what this iterator
  // points to.
  struct Header
  {
    // The name of the member.
    std::string name;
    // The file offset of the member.
    off_t off;
    // The file offset of a nested archive member.
    off_t nested_off;
    // The size of the member.
    off_t size;
  };

  Archive_iterator(Archive_file* afile, off_t off)
    : afile_(afile), off_(off)
  { this->read_next_header(); }

  const Header&
  operator*() const
  { return this->header_; }

  const Header*
  operator->() const
  { return &this->header_; }

  Archive_iterator&
  operator++()
  {
    if (this->off_ == this->afile_->filesize())
      return *this;
    this->off_ = this->next_off_;
    this->read_next_header();
    return *this;
  }

  Archive_iterator
  operator++(int)
  {
    Archive_iterator ret = *this;
    ++*this;
    return ret;
  }

  bool
  operator==(const Archive_iterator& p) const
  { return this->off_ == p->off; }

  bool
  operator!=(const Archive_iterator& p) const
  { return this->off_ != p->off; }

 private:
  void
  read_next_header();

  // The underlying archive file.
  Archive_file* afile_;
  // The current offset in the file.
  off_t off_;
  // The offset of the next member.
  off_t next_off_;
  // The current archive header.
  Header header_;
};

// Read the next archive header.

void
Archive_iterator::read_next_header()
{
  off_t filesize = this->afile_->filesize();
  while (true)
    {
      if (this->off_ == filesize)
	{
	  this->header_.off = filesize;
	  return;
	}

      if (!this->afile_->read_header(this->off_, &this->header_.name,
                                     &this->header_.size,
                                     &this->header_.nested_off,
                                     &this->next_off_))
	{
	  this->header_.off = filesize;
	  this->off_ = filesize;
	  return;
	}
      this->header_.off = this->off_;

      // Skip special members.
      if (!this->header_.name.empty() && this->header_.name != "/")
	return;

      this->off_ = this->next_off_;
    }
}

// Initial iterator.

Archive_iterator
archive_begin(Archive_file* afile)
{
  return Archive_iterator(afile, afile->first_member_offset());
}

// Final iterator.

Archive_iterator
archive_end(Archive_file* afile)
{
  return Archive_iterator(afile, afile->filesize());
}

// A type of Import_stream which concatenates other Import_streams
// together.

class Stream_concatenate : public Import::Stream
{
 public:
  Stream_concatenate()
    : inputs_()
  { }

  // Add a new stream.
  void
  add(Import::Stream* is)
  { this->inputs_.push_back(is); }

 protected:
  bool
  do_peek(size_t, const char**);

  void
  do_advance(size_t);

 private:
  std::list<Import::Stream*> inputs_;
};

// Peek ahead.

bool
Stream_concatenate::do_peek(size_t length, const char** bytes)
{
  while (true)
    {
      if (this->inputs_.empty())
	return false;
      if (this->inputs_.front()->peek(length, bytes))
	return true;
      delete this->inputs_.front();
      this->inputs_.pop_front();
    }
}

// Advance.

void
Stream_concatenate::do_advance(size_t skip)
{
  while (true)
    {
      if (this->inputs_.empty())
	return;
      if (!this->inputs_.front()->at_eof())
	{
	  // We just assume that this will do the right thing.  It
	  // should be OK since we should never want to skip past
	  // multiple streams.
	  this->inputs_.front()->advance(skip);
	  return;
	}
      delete this->inputs_.front();
      this->inputs_.pop_front();
    }
}

// Import data from an archive.  We walk through the archive and
// import data from each member.

Import::Stream*
Import::find_archive_export_data(const std::string& filename, int fd,
				 Location location)
{
  Archive_file afile(filename, fd, location);
  if (!afile.initialize())
    return NULL;

  Stream_concatenate* ret = new Stream_concatenate;

  bool any_data = false;
  bool any_members = false;
  Archive_iterator pend = archive_end(&afile);
  for (Archive_iterator p = archive_begin(&afile); p != pend; p++)
    {
      any_members = true;
      int member_fd;
      off_t member_off;
      std::string member_name;
      if (!afile.get_file_and_offset(p->off, p->name, p->nested_off,
				     &member_fd, &member_off, &member_name))
	return NULL;

      Import::Stream* is = Import::find_object_export_data(member_name,
							   member_fd,
							   member_off,
							   location);
      if (is != NULL)
	{
	  ret->add(is);
	  any_data = true;
	}
    }

  if (!any_members)
    {
      // It's normal to have an empty archive file when using gobuild.
      return new Stream_from_string("");
    }

  if (!any_data)
    {
      delete ret;
      return NULL;
    }

  return ret;
}
