/* elfcomm.c -- common code for ELF format file.
   Copyright 2010-2013 Free Software Foundation, Inc.

   Originally developed by Eric Youngdale <eric@andante.jic.com>
   Modifications by Nick Clifton <nickc@redhat.com>

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */

#include "sysdep.h"
#include "libiberty.h"
#include "filenames.h"
#include "bfd.h"
#include "aout/ar.h"
#include "bucomm.h"
#include "elfcomm.h"
#include <assert.h>

void
error (const char *message, ...)
{
  va_list args;

  /* Try to keep error messages in sync with the program's normal output.  */
  fflush (stdout);

  va_start (args, message);
  fprintf (stderr, _("%s: Error: "), program_name);
  vfprintf (stderr, message, args);
  va_end (args);
}

void
warn (const char *message, ...)
{
  va_list args;

  /* Try to keep warning messages in sync with the program's normal output.  */
  fflush (stdout);
  
  va_start (args, message);
  fprintf (stderr, _("%s: Warning: "), program_name);
  vfprintf (stderr, message, args);
  va_end (args);
}

void (*byte_put) (unsigned char *, elf_vma, int);

void
byte_put_little_endian (unsigned char * field, elf_vma value, int size)
{
  switch (size)
    {
    case 8:
      field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
      field[6] = ((value >> 24) >> 24) & 0xff;
      field[5] = ((value >> 24) >> 16) & 0xff;
      field[4] = ((value >> 24) >> 8) & 0xff;
      /* Fall through.  */
    case 4:
      field[3] = (value >> 24) & 0xff;
      /* Fall through.  */
    case 3:
      field[2] = (value >> 16) & 0xff;
      /* Fall through.  */
    case 2:
      field[1] = (value >> 8) & 0xff;
      /* Fall through.  */
    case 1:
      field[0] = value & 0xff;
      break;

    default:
      error (_("Unhandled data length: %d\n"), size);
      abort ();
    }
}

void
byte_put_big_endian (unsigned char * field, elf_vma value, int size)
{
  switch (size)
    {
    case 8:
      field[7] = value & 0xff;
      field[6] = (value >> 8) & 0xff;
      field[5] = (value >> 16) & 0xff;
      field[4] = (value >> 24) & 0xff;
      value >>= 16;
      value >>= 16;
      /* Fall through.  */
    case 4:
      field[3] = value & 0xff;
      value >>= 8;
      /* Fall through.  */
    case 3:
      field[2] = value & 0xff;
      value >>= 8;
      /* Fall through.  */
    case 2:
      field[1] = value & 0xff;
      value >>= 8;
      /* Fall through.  */
    case 1:
      field[0] = value & 0xff;
      break;

    default:
      error (_("Unhandled data length: %d\n"), size);
      abort ();
    }
}

elf_vma (*byte_get) (unsigned char *, int);

elf_vma
byte_get_little_endian (unsigned char *field, int size)
{
  switch (size)
    {
    case 1:
      return *field;

    case 2:
      return  ((unsigned int) (field[0]))
	|    (((unsigned int) (field[1])) << 8);

    case 3:
      return  ((unsigned long) (field[0]))
	|    (((unsigned long) (field[1])) << 8)
	|    (((unsigned long) (field[2])) << 16);

    case 4:
      return  ((unsigned long) (field[0]))
	|    (((unsigned long) (field[1])) << 8)
	|    (((unsigned long) (field[2])) << 16)
	|    (((unsigned long) (field[3])) << 24);

    case 8:
      if (sizeof (elf_vma) == 8)
	return  ((elf_vma) (field[0]))
	  |    (((elf_vma) (field[1])) << 8)
	  |    (((elf_vma) (field[2])) << 16)
	  |    (((elf_vma) (field[3])) << 24)
	  |    (((elf_vma) (field[4])) << 32)
	  |    (((elf_vma) (field[5])) << 40)
	  |    (((elf_vma) (field[6])) << 48)
	  |    (((elf_vma) (field[7])) << 56);
      else if (sizeof (elf_vma) == 4)
	/* We want to extract data from an 8 byte wide field and
	   place it into a 4 byte wide field.  Since this is a little
	   endian source we can just use the 4 byte extraction code.  */
	return  ((unsigned long) (field[0]))
	  |    (((unsigned long) (field[1])) << 8)
	  |    (((unsigned long) (field[2])) << 16)
	  |    (((unsigned long) (field[3])) << 24);

    default:
      error (_("Unhandled data length: %d\n"), size);
      abort ();
    }
}

elf_vma
byte_get_big_endian (unsigned char *field, int size)
{
  switch (size)
    {
    case 1:
      return *field;

    case 2:
      return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);

    case 3:
      return ((unsigned long) (field[2]))
	|   (((unsigned long) (field[1])) << 8)
	|   (((unsigned long) (field[0])) << 16);

    case 4:
      return ((unsigned long) (field[3]))
	|   (((unsigned long) (field[2])) << 8)
	|   (((unsigned long) (field[1])) << 16)
	|   (((unsigned long) (field[0])) << 24);

    case 8:
      if (sizeof (elf_vma) == 8)
	return ((elf_vma) (field[7]))
	  |   (((elf_vma) (field[6])) << 8)
	  |   (((elf_vma) (field[5])) << 16)
	  |   (((elf_vma) (field[4])) << 24)
	  |   (((elf_vma) (field[3])) << 32)
	  |   (((elf_vma) (field[2])) << 40)
	  |   (((elf_vma) (field[1])) << 48)
	  |   (((elf_vma) (field[0])) << 56);
      else if (sizeof (elf_vma) == 4)
	{
	  /* Although we are extracing data from an 8 byte wide field,
	     we are returning only 4 bytes of data.  */
	  field += 4;
	  return ((unsigned long) (field[3]))
	    |   (((unsigned long) (field[2])) << 8)
	    |   (((unsigned long) (field[1])) << 16)
	    |   (((unsigned long) (field[0])) << 24);
	}

    default:
      error (_("Unhandled data length: %d\n"), size);
      abort ();
    }
}

elf_vma
byte_get_signed (unsigned char *field, int size)
{
  elf_vma x = byte_get (field, size);

  switch (size)
    {
    case 1:
      return (x ^ 0x80) - 0x80;
    case 2:
      return (x ^ 0x8000) - 0x8000;
    case 4:
      return (x ^ 0x80000000) - 0x80000000;
    case 8:
      return x;
    default:
      abort ();
    }
}

/* Return the high-order 32-bits and the low-order 32-bits
   of an 8-byte value separately.  */

void
byte_get_64 (unsigned char *field, elf_vma *high, elf_vma *low)
{
  if (byte_get == byte_get_big_endian)
    {
      *high = byte_get_big_endian (field, 4);
      *low = byte_get_big_endian (field + 4, 4);
    }
  else
    {
      *high = byte_get_little_endian (field + 4, 4);
      *low = byte_get_little_endian (field, 4);
    }
  return;
}

/* Return the path name for a proxy entry in a thin archive, adjusted
   relative to the path name of the thin archive itself if necessary.
   Always returns a pointer to malloc'ed memory.  */

char *
adjust_relative_path (const char *file_name, const char *name,
		      int name_len)
{
  char * member_file_name;
  const char * base_name = lbasename (file_name);

  /* This is a proxy entry for a thin archive member.
     If the extended name table contains an absolute path
     name, or if the archive is in the current directory,
     use the path name as given.  Otherwise, we need to
     find the member relative to the directory where the
     archive is located.  */
  if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
    {
      member_file_name = (char *) malloc (name_len + 1);
      if (member_file_name == NULL)
        {
          error (_("Out of memory\n"));
          return NULL;
        }
      memcpy (member_file_name, name, name_len);
      member_file_name[name_len] = '\0';
    }
  else
    {
      /* Concatenate the path components of the archive file name
         to the relative path name from the extended name table.  */
      size_t prefix_len = base_name - file_name;
      member_file_name = (char *) malloc (prefix_len + name_len + 1);
      if (member_file_name == NULL)
        {
          error (_("Out of memory\n"));
          return NULL;
        }
      memcpy (member_file_name, file_name, prefix_len);
      memcpy (member_file_name + prefix_len, name, name_len);
      member_file_name[prefix_len + name_len] = '\0';
    }
  return member_file_name;
}

/* Processes the archive index table and symbol table in ARCH.
   Entries in the index table are SIZEOF_AR_INDEX bytes long.
   Fills in ARCH->next_arhdr_offset and ARCH->arhdr.
   If READ_SYMBOLS is true then fills in ARCH->index_num, ARCH->index_array,
    ARCH->sym_size and ARCH->sym_table.
   It is the caller's responsibility to free ARCH->index_array and
    ARCH->sym_table.
   Returns TRUE upon success, FALSE otherwise.
   If failure occurs an error message is printed.  */

static bfd_boolean
process_archive_index_and_symbols (struct archive_info *  arch,
				   unsigned int           sizeof_ar_index,
				   bfd_boolean            read_symbols)
{
  size_t got;
  unsigned long size;

  size = strtoul (arch->arhdr.ar_size, NULL, 10);
  size = size + (size & 1);

  arch->next_arhdr_offset += sizeof arch->arhdr + size;

  if (! read_symbols)
    {
      if (fseek (arch->file, size, SEEK_CUR) != 0)
	{
	  error (_("%s: failed to skip archive symbol table\n"),
		 arch->file_name);
	  return FALSE;
	}
    }
  else
    {
      unsigned long i;
      /* A buffer used to hold numbers read in from an archive index.
	 These are always SIZEOF_AR_INDEX bytes long and stored in
	 big-endian format.  */
      unsigned char integer_buffer[sizeof arch->index_num];
      unsigned char * index_buffer;

      assert (sizeof_ar_index <= sizeof integer_buffer);
  
      /* Check the size of the archive index.  */
      if (size < sizeof_ar_index)
	{
	  error (_("%s: the archive index is empty\n"), arch->file_name);
	  return FALSE;
	}

      /* Read the number of entries in the archive index.  */
      got = fread (integer_buffer, 1, sizeof_ar_index, arch->file);
      if (got != sizeof_ar_index)
	{
	  error (_("%s: failed to read archive index\n"), arch->file_name);
	  return FALSE;
	}

      arch->index_num = byte_get_big_endian (integer_buffer, sizeof_ar_index);
      size -= sizeof_ar_index;

      if (size < arch->index_num * sizeof_ar_index)
	{
	  error (_("%s: the archive index is supposed to have %ld entries of %d bytes, but the size is only %ld\n"),
		 arch->file_name, (long) arch->index_num, sizeof_ar_index, size);
	  return FALSE;
	}

      /* Read in the archive index.  */
      index_buffer = (unsigned char *)
	malloc (arch->index_num * sizeof_ar_index);
      if (index_buffer == NULL)
	{
	  error (_("Out of memory whilst trying to read archive symbol index\n"));
	  return FALSE;
	}

      got = fread (index_buffer, sizeof_ar_index, arch->index_num, arch->file);
      if (got != arch->index_num)
	{
	  free (index_buffer);
	  error (_("%s: failed to read archive index\n"), arch->file_name);
	  return FALSE;
	}

      size -= arch->index_num * sizeof_ar_index;

      /* Convert the index numbers into the host's numeric format.  */
      arch->index_array = (elf_vma *)
	malloc (arch->index_num * sizeof (* arch->index_array));
      if (arch->index_array == NULL)
	{
	  free (index_buffer);
	  error (_("Out of memory whilst trying to convert the archive symbol index\n"));
	  return FALSE;
	}

      for (i = 0; i < arch->index_num; i++)
	arch->index_array[i] =
	  byte_get_big_endian ((unsigned char *) (index_buffer + (i * sizeof_ar_index)),
			       sizeof_ar_index);
      free (index_buffer);

      /* The remaining space in the header is taken up by the symbol table.  */
      if (size < 1)
	{
	  error (_("%s: the archive has an index but no symbols\n"),
		 arch->file_name);
	  return FALSE;
	}

      arch->sym_table = (char *) malloc (size);
      if (arch->sym_table == NULL)
	{
	  error (_("Out of memory whilst trying to read archive index symbol table\n"));
	  return FALSE;
	}

      arch->sym_size = size;
      got = fread (arch->sym_table, 1, size, arch->file);
      if (got != size)
	{
	  error (_("%s: failed to read archive index symbol table\n"),
		 arch->file_name);
	  return FALSE;
	}
    }

  /* Read the next archive header.  */
  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
  if (got != sizeof arch->arhdr && got != 0)
    {
      error (_("%s: failed to read archive header following archive index\n"),
	     arch->file_name);
      return FALSE;
    }

  return TRUE;
}

/* Read the symbol table and long-name table from an archive.  */

int
setup_archive (struct archive_info *arch, const char *file_name,
	       FILE *file, bfd_boolean is_thin_archive,
	       bfd_boolean read_symbols)
{
  size_t got;

  arch->file_name = strdup (file_name);
  arch->file = file;
  arch->index_num = 0;
  arch->index_array = NULL;
  arch->sym_table = NULL;
  arch->sym_size = 0;
  arch->longnames = NULL;
  arch->longnames_size = 0;
  arch->nested_member_origin = 0;
  arch->is_thin_archive = is_thin_archive;
  arch->uses_64bit_indicies = FALSE;
  arch->next_arhdr_offset = SARMAG;

  /* Read the first archive member header.  */
  if (fseek (file, SARMAG, SEEK_SET) != 0)
    {
      error (_("%s: failed to seek to first archive header\n"), file_name);
      return 1;
    }
  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
  if (got != sizeof arch->arhdr)
    {
      if (got == 0)
	return 0;

      error (_("%s: failed to read archive header\n"), file_name);
      return 1;
    }

  /* See if this is the archive symbol table.  */
  if (const_strneq (arch->arhdr.ar_name, "/               "))
    {
      if (! process_archive_index_and_symbols (arch, 4, read_symbols))
	return 1;
    }
  else if (const_strneq (arch->arhdr.ar_name, "/SYM64/         "))
    {
      arch->uses_64bit_indicies = TRUE;
      if (! process_archive_index_and_symbols (arch, 8, read_symbols))
	return 1;
    }
  else if (read_symbols)
    printf (_("%s has no archive index\n"), file_name);

  if (const_strneq (arch->arhdr.ar_name, "//              "))
    {
      /* This is the archive string table holding long member names.  */
      arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
      arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;

      arch->longnames = (char *) malloc (arch->longnames_size);
      if (arch->longnames == NULL)
	{
	  error (_("Out of memory reading long symbol names in archive\n"));
	  return 1;
	}

      if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
	{
	  free (arch->longnames);
	  arch->longnames = NULL;
	  error (_("%s: failed to read long symbol name string table\n"),
		 file_name);
	  return 1;
	}

      if ((arch->longnames_size & 1) != 0)
	getc (file);
    }

  return 0;
}

/* Open and setup a nested archive, if not already open.  */

int
setup_nested_archive (struct archive_info *nested_arch,
		      const char *member_file_name)
{
  FILE * member_file;

  /* Have we already setup this archive?  */
  if (nested_arch->file_name != NULL
      && streq (nested_arch->file_name, member_file_name))
    return 0;

  /* Close previous file and discard cached information.  */
  if (nested_arch->file != NULL)
    fclose (nested_arch->file);
  release_archive (nested_arch);

  member_file = fopen (member_file_name, "rb");
  if (member_file == NULL)
    return 1;
  return setup_archive (nested_arch, member_file_name, member_file,
			FALSE, FALSE);
}

/* Release the memory used for the archive information.  */

void
release_archive (struct archive_info * arch)
{
  if (arch->file_name != NULL)
    free (arch->file_name);
  if (arch->index_array != NULL)
    free (arch->index_array);
  if (arch->sym_table != NULL)
    free (arch->sym_table);
  if (arch->longnames != NULL)
    free (arch->longnames);
}

/* Get the name of an archive member from the current archive header.
   For simple names, this will modify the ar_name field of the current
   archive header.  For long names, it will return a pointer to the
   longnames table.  For nested archives, it will open the nested archive
   and get the name recursively.  NESTED_ARCH is a single-entry cache so
   we don't keep rereading the same information from a nested archive.  */

char *
get_archive_member_name (struct archive_info *arch,
                         struct archive_info *nested_arch)
{
  unsigned long j, k;

  if (arch->arhdr.ar_name[0] == '/')
    {
      /* We have a long name.  */
      char *endp;
      char *member_file_name;
      char *member_name;

      if (arch->longnames == NULL || arch->longnames_size == 0)
	{
	  error (_("Archive member uses long names, but no longname table found\n"));
	  return NULL;
	}
      
      arch->nested_member_origin = 0;
      k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
      if (arch->is_thin_archive && endp != NULL && * endp == ':')
        arch->nested_member_origin = strtoul (endp + 1, NULL, 10);

      while ((j < arch->longnames_size)
             && (arch->longnames[j] != '\n')
             && (arch->longnames[j] != '\0'))
        j++;
      if (arch->longnames[j-1] == '/')
        j--;
      arch->longnames[j] = '\0';

      if (!arch->is_thin_archive || arch->nested_member_origin == 0)
        return arch->longnames + k;

      /* This is a proxy for a member of a nested archive.
         Find the name of the member in that archive.  */
      member_file_name = adjust_relative_path (arch->file_name,
					       arch->longnames + k, j - k);
      if (member_file_name != NULL
          && setup_nested_archive (nested_arch, member_file_name) == 0)
	{
          member_name = get_archive_member_name_at (nested_arch,
						    arch->nested_member_origin,
						    NULL);
	  if (member_name != NULL)
	    {
	      free (member_file_name);
	      return member_name;
	    }
	}
      free (member_file_name);

      /* Last resort: just return the name of the nested archive.  */
      return arch->longnames + k;
    }

  /* We have a normal (short) name.  */
  for (j = 0; j < sizeof (arch->arhdr.ar_name); j++)
    if (arch->arhdr.ar_name[j] == '/')
      {
	arch->arhdr.ar_name[j] = '\0';
	return arch->arhdr.ar_name;
      }

  /* The full ar_name field is used.  Don't rely on ar_date starting
     with a zero byte.  */
  {
    char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1);
    memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name));
    name[sizeof (arch->arhdr.ar_name)] = '\0';
    return name;
  }
}

/* Get the name of an archive member at a given OFFSET within an archive
   ARCH.  */

char *
get_archive_member_name_at (struct archive_info *arch,
                            unsigned long offset,
			    struct archive_info *nested_arch)
{
  size_t got;

  if (fseek (arch->file, offset, SEEK_SET) != 0)
    {
      error (_("%s: failed to seek to next file name\n"), arch->file_name);
      return NULL;
    }
  got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
  if (got != sizeof arch->arhdr)
    {
      error (_("%s: failed to read archive header\n"), arch->file_name);
      return NULL;
    }
  if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
    {
      error (_("%s: did not find a valid archive header\n"),
	     arch->file_name);
      return NULL;
    }

  return get_archive_member_name (arch, nested_arch);
}

/* Construct a string showing the name of the archive member, qualified
   with the name of the containing archive file.  For thin archives, we
   use square brackets to denote the indirection.  For nested archives,
   we show the qualified name of the external member inside the square
   brackets (e.g., "thin.a[normal.a(foo.o)]").  */

char *
make_qualified_name (struct archive_info * arch,
		     struct archive_info * nested_arch,
		     const char *member_name)
{
  const char * error_name = _("<corrupt>");
  size_t len;
  char * name;

  len = strlen (arch->file_name) + strlen (member_name) + 3;
  if (arch->is_thin_archive
      && arch->nested_member_origin != 0)
    {
      /* PR 15140: Allow for corrupt thin archives.  */
      if (nested_arch->file_name)
	len += strlen (nested_arch->file_name) + 2;
      else
	len += strlen (error_name) + 2;
    }

  name = (char *) malloc (len);
  if (name == NULL)
    {
      error (_("Out of memory\n"));
      return NULL;
    }

  if (arch->is_thin_archive
      && arch->nested_member_origin != 0)
    {
      if (nested_arch->file_name)
	snprintf (name, len, "%s[%s(%s)]", arch->file_name,
		  nested_arch->file_name, member_name);
      else
	snprintf (name, len, "%s[%s(%s)]", arch->file_name,
		  error_name, member_name);	
    }
  else if (arch->is_thin_archive)
    snprintf (name, len, "%s[%s]", arch->file_name, member_name);
  else
    snprintf (name, len, "%s(%s)", arch->file_name, member_name);

  return name;
}
