// 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 ar_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 ar_namlen 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 ar_nxtmem 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: can't 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;
}
