Exemplo n.º 1
0
Arquivo: cache.c Projeto: 0mp/freebsd
static file_ptr
cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
{
  file_ptr nwrite;
  FILE *f = bfd_cache_lookup (abfd, 0);
  if (f == NULL)
    return 0;
  nwrite = fwrite (where, 1, nbytes, f);
  if (nwrite < nbytes && ferror (f))
    {
      bfd_set_error (bfd_error_system_call);
      return -1;
    }
  return nwrite;
}
Exemplo n.º 2
0
/*
FUNCTION
	bfd_canonicalize_reloc

SYNOPSIS
	long bfd_canonicalize_reloc
	  (bfd *abfd, asection *sec, arelent **loc, asymbol **syms);

DESCRIPTION
	Call the back end associated with the open BFD
	@var{abfd} and translate the external form of the relocation
	information attached to @var{sec} into the internal canonical
	form.  Place the table into memory at @var{loc}, which has
	been preallocated, usually by a call to
	<<bfd_get_reloc_upper_bound>>.  Returns the number of relocs, or
	-1 on error.

	The @var{syms} table is also needed for horrible internal magic
	reasons.

*/
long
bfd_canonicalize_reloc (bfd *abfd,
			sec_ptr asect,
			arelent **location,
			asymbol **symbols)
{
  if (abfd->format != bfd_object)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  return BFD_SEND (abfd, _bfd_canonicalize_reloc,
		   (abfd, asect, location, symbols));
}
Exemplo n.º 3
0
bfd_boolean
bfd_set_file_flags (bfd *abfd, flagword flags)
{
  if (abfd->format != bfd_object)
    {
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }

  if (bfd_read_p (abfd))
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  bfd_get_file_flags (abfd) = flags;
  if ((flags & bfd_applicable_file_flags (abfd)) != flags)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  return TRUE;
}
Exemplo n.º 4
0
static file_ptr
cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
{
  file_ptr nwrite;
  FILE *f = bfd_cache_lookup (abfd, 0);
  if (f == NULL)
    return 0;
#if defined(__BEOS__) || defined(__HAIKU__)
  {
    if (_bfdio_files[fileno(f)] == 1)
      {
        file_ptr eof;
        file_ptr pos;

        pos = ftell (f);
        fseek (f, 0L, SEEK_END);
        eof = ftell(f);

        if (eof < pos)
          {
            file_ptr diff;
            static char zeros[512];

            diff = pos - eof;

            while (diff >= sizeof (zeros))
              {
                fwrite(zeros, sizeof (zeros), 1, f);
                diff -= sizeof (zeros);
              }
            if (diff > 0)
              fwrite(zeros, diff, 1, f);
          }
        else
          fseek (f, pos, SEEK_SET);

        _bfdio_files[fileno(f)] = 0;
      }
  }
#endif
  nwrite = fwrite (where, 1, nbytes, f);
  if (nwrite < nbytes && ferror (f))
    {
      bfd_set_error (bfd_error_system_call);
      return -1;
    }
  return nwrite;
}
Exemplo n.º 5
0
static file_ptr
spu_bfd_iovec_pread (bfd *abfd, void *stream, void *buf,
                     file_ptr nbytes, file_ptr offset)
{
  CORE_ADDR addr = *(CORE_ADDR *)stream;
  int ret;

  ret = target_read_memory (addr + offset, buf, nbytes);
  if (ret != 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  return nbytes;
}
Exemplo n.º 6
0
static int
input_file_get (char *buf, int buflen)
{
  int size;

  size = fread (buf, sizeof (char), buflen, f_in);
  if (size < 0)
    {
#ifdef BFD_ASSEMBLER
      bfd_set_error (bfd_error_system_call);
#endif
      as_perror (_("Can't read from %s"), file_name);
      size = 0;
    }
  return size;
}
Exemplo n.º 7
0
/* Returns 0 for success, negative value for failure (in which case
   bfd_get_error can retrieve the error code).  */
int
bfd_stat (bfd *abfd, struct stat *statbuf)
{
  int result;

  if ((abfd->flags & BFD_IN_MEMORY) != 0)
    abort ();

  if (abfd->iovec)
    result = abfd->iovec->bstat (abfd, statbuf);
  else
    result = -1;

  if (result < 0)
    bfd_set_error (bfd_error_system_call);
  return result;
}
Exemplo n.º 8
0
static bfd_boolean
elf32_sparc_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;
  bfd_boolean error;
  unsigned long ibfd_mach;
  /* FIXME: This should not be static.  */
  static unsigned long previous_ibfd_e_flags = (unsigned long) -1;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  error = FALSE;

  ibfd_mach = bfd_get_mach (ibfd);
  if (bfd_mach_sparc_64bit_p (ibfd_mach))
    {
      error = TRUE;
      _bfd_error_handler
	(_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd);
    }
  else if ((ibfd->flags & DYNAMIC) == 0)
    {
      if (bfd_get_mach (obfd) < ibfd_mach)
	bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach);
    }

  if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA)
       != previous_ibfd_e_flags)
      && previous_ibfd_e_flags != (unsigned long) -1)
    {
      _bfd_error_handler
	(_("%B: linking little endian files with big endian files"), ibfd);
      error = TRUE;
    }
  previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA;

  if (error)
    {
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  return _bfd_sparc_elf_merge_private_bfd_data (ibfd, info);
}
Exemplo n.º 9
0
bfd *
_bfd_new_bfd ()
{
  bfd *nbfd;

  nbfd = (bfd *) bfd_zmalloc ((bfd_size_type) sizeof (bfd));
  if (nbfd == NULL)
    return NULL;

  nbfd->id = _bfd_id_counter++;

  nbfd->memory = (PTR) objalloc_create ();
  if (nbfd->memory == NULL)
    {
      bfd_set_error (bfd_error_no_memory);
      free (nbfd);
      return NULL;
    }

  nbfd->arch_info = &bfd_default_arch_struct;

  nbfd->direction = no_direction;
  nbfd->iostream = NULL;
  nbfd->where = 0;
  if (!bfd_hash_table_init_n (&nbfd->section_htab,
			      bfd_section_hash_newfunc,
			      251))
    {
      free (nbfd);
      return NULL;
    }
  nbfd->sections = (asection *) NULL;
  nbfd->section_tail = &nbfd->sections;
  nbfd->format = bfd_unknown;
  nbfd->my_archive = (bfd *) NULL;
  nbfd->origin = 0;
  nbfd->opened_once = FALSE;
  nbfd->output_has_begun = FALSE;
  nbfd->section_count = 0;
  nbfd->usrdata = (PTR) NULL;
  nbfd->cacheable = FALSE;
  nbfd->flags = BFD_NO_FLAGS;
  nbfd->mtime_set = FALSE;

  return nbfd;
}
Exemplo n.º 10
0
asection *
bfd_make_section_old_way (bfd *abfd, const char *name)
{
  asection *newsect;

  if (abfd->output_has_begun)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return NULL;
    }

  if (strcmp (name, BFD_ABS_SECTION_NAME) == 0)
    newsect = bfd_abs_section_ptr;
  else if (strcmp (name, BFD_COM_SECTION_NAME) == 0)
    newsect = bfd_com_section_ptr;
  else if (strcmp (name, BFD_UND_SECTION_NAME) == 0)
    newsect = bfd_und_section_ptr;
  else if (strcmp (name, BFD_IND_SECTION_NAME) == 0)
    newsect = bfd_ind_section_ptr;
  else
    {
      struct section_hash_entry *sh;

      sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
      if (sh == NULL)
	return NULL;

      newsect = &sh->section;
      if (newsect->name != NULL)
	{
	  /* Section already exists.  */
	  return newsect;
	}

      newsect->name = name;
      return bfd_section_init (abfd, newsect);
    }

  /* Call new_section_hook when "creating" the standard abs, com, und
     and ind sections to tack on format specific section data.
     Also, create a proper section symbol.  */
  if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
    return NULL;
  return newsect;
}
Exemplo n.º 11
0
bfd_size_type
bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
{
  size_t nread;

  /* If this is an archive element, don't read past the end of
     this element.  */
  if (abfd->arelt_data != NULL)
    {
      size_t maxbytes = ((struct areltdata *) abfd->arelt_data)->parsed_size;
      if (size > maxbytes)
	size = maxbytes;
    }

  if ((abfd->flags & BFD_IN_MEMORY) != 0)
    {
      struct bfd_in_memory *bim;
      bfd_size_type get;

      bim = abfd->iostream;
      get = size;
      if (abfd->where + get > bim->size)
	{
	  if (bim->size < (bfd_size_type) abfd->where)
	    get = 0;
	  else
	    get = bim->size - abfd->where;
	  bfd_set_error (bfd_error_file_truncated);
	}
      memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
      abfd->where += get;
      return get;
    }

  if (abfd->iovec)
    nread = abfd->iovec->bread (abfd, ptr, size);
  else
    nread = 0;
  if (nread != (size_t) -1)
    abfd->where += nread;

  return nread;
}
Exemplo n.º 12
0
static file_ptr
memory_bread (bfd *abfd, void *ptr, file_ptr size)
{
  struct bfd_in_memory *bim;
  bfd_size_type get;

  bim = (struct bfd_in_memory *) abfd->iostream;
  get = size;
  if (abfd->where + get > bim->size)
    {
      if (bim->size < (bfd_size_type) abfd->where)
        get = 0;
      else
        get = bim->size - abfd->where;
      bfd_set_error (bfd_error_file_truncated);
    }
  memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
  return get;
}
Exemplo n.º 13
0
static void
ldfile_open_command_file_1 (const char *name, bfd_boolean default_only)
{
    FILE *ldlex_input_stack;
    ldlex_input_stack = ldfile_find_command_file (name, "", default_only);

    if (ldlex_input_stack == NULL)
    {
        bfd_set_error (bfd_error_system_call);
        einfo (_("%P%F: cannot open linker script file %s: %E\n"), name);
    }

    lex_push_file (ldlex_input_stack, name);

    ldfile_input_filename = name;
    lineno = 1;

    saved_script_handle = ldlex_input_stack;
}
Exemplo n.º 14
0
Arquivo: hash.c Projeto: 5kg/gdb
struct bfd_hash_entry *
bfd_hash_lookup (struct bfd_hash_table *table,
		 const char *string,
		 bfd_boolean create,
		 bfd_boolean copy)
{
  unsigned long hash;
  struct bfd_hash_entry *hashp;
  unsigned int len;
  unsigned int _index;

  hash = bfd_hash_hash (string, &len);
  _index = hash % table->size;
  for (hashp = table->table[_index];
       hashp != NULL;
       hashp = hashp->next)
    {
      if (hashp->hash == hash
	  && strcmp (hashp->string, string) == 0)
	return hashp;
    }

  if (! create)
    return NULL;

  if (copy)
    {
      char *new_string;

      new_string = (char *) objalloc_alloc ((struct objalloc *) table->memory,
                                            len + 1);
      if (!new_string)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return NULL;
	}
      memcpy (new_string, string, len + 1);
      string = new_string;
    }

  return bfd_hash_insert (table, string, hash);
}
Exemplo n.º 15
0
static bfd_boolean
bfd_cache_delete (bfd *abfd)
{
  bfd_boolean ret;

  if (fclose ((FILE *) abfd->iostream) == 0)
    ret = TRUE;
  else
    {
      ret = FALSE;
      bfd_set_error (bfd_error_system_call);
    }

  snip (abfd);

  abfd->iostream = NULL;
  --open_files;

  return ret;
}
Exemplo n.º 16
0
static bfd_boolean
mcore_emit_base_file_entry (struct bfd_link_info *info,
			    bfd *output_bfd,
			    asection *input_section,
			    bfd_vma reloc_offset)
{
  bfd_vma addr = reloc_offset
                 - input_section->vma
                 + input_section->output_offset
                 + input_section->output_section->vma;

  if (coff_data (output_bfd)->pe)
     addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;

  if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
    return TRUE;

  bfd_set_error (bfd_error_system_call);
  return FALSE;
}
Exemplo n.º 17
0
long
_bfd_generic_read_minisymbols (bfd *abfd,
			       bfd_boolean dynamic,
			       void **minisymsp,
			       unsigned int *sizep)
{
  long storage;
  asymbol **syms = NULL;
  long symcount;

  if (dynamic)
    storage = bfd_get_dynamic_symtab_upper_bound (abfd);
  else
    storage = bfd_get_symtab_upper_bound (abfd);
  if (storage < 0)
    goto error_return;
  if (storage == 0)
    return 0;

  syms = (asymbol **) bfd_malloc (storage);
  if (syms == NULL)
    goto error_return;

  if (dynamic)
    symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
  else
    symcount = bfd_canonicalize_symtab (abfd, syms);
  if (symcount < 0)
    goto error_return;

  *minisymsp = syms;
  *sizep = sizeof (asymbol *);

  return symcount;

 error_return:
  bfd_set_error (bfd_error_no_symbols);
  if (syms != NULL)
    free (syms);
  return -1;
}
Exemplo n.º 18
0
bfd_size_type
bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
{
  size_t nwrote;

  if (abfd->iovec)
    nwrote = abfd->iovec->bwrite (abfd, ptr, size);
  else
    nwrote = 0;

  if (nwrote != (size_t) -1)
    abfd->where += nwrote;
  if (nwrote != size)
    {
#ifdef ENOSPC
      errno = ENOSPC;
#endif
      bfd_set_error (bfd_error_system_call);
    }
  return nwrote;
}
Exemplo n.º 19
0
bfd_boolean
bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
{
  bfd_size_type uncompressed_size = sec->size;

  /* Error if not opened for write.  */
  if (abfd->direction != write_direction
      || uncompressed_size == 0
      || uncompressed_buffer == NULL
      || sec->contents != NULL
      || sec->compressed_size != 0
      || sec->compress_status != COMPRESS_SECTION_NONE)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  /* Compress it.  */
  return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
					uncompressed_size) != 0;
}
Exemplo n.º 20
0
void
as_perror (const char *gripe,		/* Unpunctuated error theme.  */
	   const char *filename)
{
  const char *errtxt;
  int saved_errno = errno;

  as_show_where ();
  fprintf (stderr, gripe, filename);
  errno = saved_errno;
#ifdef BFD_ASSEMBLER
  errtxt = bfd_errmsg (bfd_get_error ());
#else
  errtxt = xstrerror (errno);
#endif
  fprintf (stderr, ": %s\n", errtxt);
  errno = 0;
#ifdef BFD_ASSEMBLER
  bfd_set_error (bfd_error_no_error);
#endif
}
Exemplo n.º 21
0
void *
bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
	  int prot, int flags, file_ptr offset,
	  void **map_addr, bfd_size_type *map_len)
{
  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    {
      offset += abfd->origin;
      abfd = abfd->my_archive;
    }

  if (abfd->iovec == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return (void *) -1;
    }

  return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset,
			     map_addr, map_len);
}
Exemplo n.º 22
0
static FILE *
bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
{
  bfd *orig_bfd = abfd;
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
    abort ();

  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    abfd = abfd->my_archive;

  if (abfd->iostream != NULL)
    {
      /* Move the file to the start of the cache.  */
      if (abfd != bfd_last_cache)
	{
	  snip (abfd);
	  insert (abfd);
	}
      return (FILE *) abfd->iostream;
    }

  if (flag & CACHE_NO_OPEN)
    return NULL;

  if (bfd_open_file (abfd) == NULL)
    ;
  else if (!(flag & CACHE_NO_SEEK)
	   && _bfd_real_fseek ((FILE *) abfd->iostream,
			       abfd->where, SEEK_SET) != 0
	   && !(flag & CACHE_NO_SEEK_ERROR))
    bfd_set_error (bfd_error_system_call);
  else
    return (FILE *) abfd->iostream;

  /* xgettext:c-format */
  _bfd_error_handler (_("reopening %B: %s\n"),
		      orig_bfd, bfd_errmsg (bfd_get_error ()));
  return NULL;
}
Exemplo n.º 23
0
sec_ptr
bfd_make_section_anyway_with_flags (bfd *abfd, const char *name,
				    flagword flags)
{
  struct section_hash_entry *sh;
  asection *newsect;

  if (abfd->output_has_begun)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return NULL;
    }

  sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
  if (sh == NULL)
    return NULL;

  newsect = &sh->section;
  if (newsect->name != NULL)
    {
      /* We are making a section of the same name.  Put it in the
	 section hash table.  Even though we can't find it directly by a
	 hash lookup, we'll be able to find the section by traversing
	 sh->root.next quicker than looking at all the bfd sections.  */
      struct section_hash_entry *new_sh;
      new_sh = (struct section_hash_entry *)
	bfd_section_hash_newfunc (NULL, &abfd->section_htab, name);
      if (new_sh == NULL)
	return NULL;

      new_sh->root = sh->root;
      sh->root.next = &new_sh->root;
      newsect = &new_sh->section;
    }

  newsect->flags = flags;
  newsect->name = name;
  return bfd_section_init (abfd, newsect);
}
Exemplo n.º 24
0
bfd_boolean
bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
{
  unsigned int in  = bfd_get_mach (ibfd);
  unsigned int out = bfd_get_mach (obfd);

  /* If the output architecture is unknown, we now have a value to set.  */
  if (out == bfd_mach_arm_unknown)
    bfd_set_arch_mach (obfd, bfd_arch_arm, in);

  /* If the input architecture is unknown,
     then so must be the output architecture.  */
  else if (in == bfd_mach_arm_unknown)
    /* FIXME: We ought to have some way to
       override this on the command line.  */
    bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);

  /* If they are the same then nothing needs to be done.  */
  else if (out == in)
    ;

  /* Otherwise the general principle that a earlier architecture can be
     linked with a later architecture to produce a binary that will execute
     on the later architecture.

     We fail however if we attempt to link a Cirrus EP9312 binary with an
     Intel XScale binary, since these architecture have co-processors which
     will not both be present on the same physical hardware.  */
  else if (in == bfd_mach_arm_ep9312
	   && (out == bfd_mach_arm_XScale
	       || out == bfd_mach_arm_iWMMXt
	       || out == bfd_mach_arm_iWMMXt2))
    {
      _bfd_error_handler (_("\
error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
			  ibfd, obfd);
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }
Exemplo n.º 25
0
asection *
bfd_make_section_old_way (bfd *abfd, const char *name)
{
  struct section_hash_entry *sh;
  asection *newsect;

  if (abfd->output_has_begun)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return NULL;
    }

  if (strcmp (name, BFD_ABS_SECTION_NAME) == 0)
    return bfd_abs_section_ptr;

  if (strcmp (name, BFD_COM_SECTION_NAME) == 0)
    return bfd_com_section_ptr;

  if (strcmp (name, BFD_UND_SECTION_NAME) == 0)
    return bfd_und_section_ptr;

  if (strcmp (name, BFD_IND_SECTION_NAME) == 0)
    return bfd_ind_section_ptr;

  sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
  if (sh == NULL)
    return NULL;

  newsect = &sh->section;
  if (newsect->name != NULL)
    {
      /* Section already exists.  */
      return newsect;
    }

  newsect->name = name;
  return bfd_section_init (abfd, newsect);
}
Exemplo n.º 26
0
Arquivo: format.c Projeto: DonCN/haiku
bfd_boolean
bfd_set_format (bfd *abfd, bfd_format format)
{
  if (bfd_read_p (abfd)
      || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  if (abfd->format != bfd_unknown)
    return abfd->format == format;

  /* Presume the answer is yes.  */
  abfd->format = format;

  if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
    {
      abfd->format = bfd_unknown;
      return FALSE;
    }

  return TRUE;
}
Exemplo n.º 27
0
bfd *
_bfd_new_bfd (void)
{
  bfd *nbfd;

  nbfd = (bfd *) bfd_zmalloc (sizeof (bfd));
  if (nbfd == NULL)
    return NULL;

  if (bfd_use_reserved_id)
    {
      nbfd->id = --bfd_reserved_id_counter;
      --bfd_use_reserved_id;
    }
  else
    nbfd->id = bfd_id_counter++;

  nbfd->memory = objalloc_create ();
  if (nbfd->memory == NULL)
    {
      bfd_set_error (bfd_error_no_memory);
      free (nbfd);
      return NULL;
    }

  nbfd->arch_info = &bfd_default_arch_struct;

  if (!bfd_hash_table_init_n (& nbfd->section_htab, bfd_section_hash_newfunc,
			      sizeof (struct section_hash_entry), 13))
    {
      free (nbfd);
      return NULL;
    }

  return nbfd;
}
Exemplo n.º 28
0
static const bfd_target *
aout_adobe_callback (bfd *abfd)
{
  struct internal_exec *execp = exec_hdr (abfd);
  asection *sect;
  struct external_segdesc ext[1];
  char *section_name;
  char try_again[30];	/* Name and number.  */
  char *newname;
  int trynum;
  flagword flags;

  /* Architecture and machine type -- unknown in this format.  */
  bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L);

  /* The positions of the string table and symbol table.  */
  obj_str_filepos (abfd) = N_STROFF (*execp);
  obj_sym_filepos (abfd) = N_SYMOFF (*execp);

  /* Suck up the section information from the file, one section at a time.  */
  for (;;)
    {
      bfd_size_type amt = sizeof (*ext);
      if (bfd_bread ( ext, amt, abfd) != amt)
	{
	  if (bfd_get_error () != bfd_error_system_call)
	    bfd_set_error (bfd_error_wrong_format);

	  return NULL;
	}
      switch (ext->e_type[0])
	{
	case N_TEXT:
	  section_name = ".text";
	  flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
	  break;

	case N_DATA:
	  section_name = ".data";
	  flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
	  break;

	case N_BSS:
	  section_name = ".bss";
	  flags = SEC_DATA | SEC_HAS_CONTENTS;
	  break;

	case 0:
	  goto no_more_sections;

	default:
	  (*_bfd_error_handler)
	    (_("%B: Unknown section type in a.out.adobe file: %x\n"),
	     abfd, ext->e_type[0]);
	  goto no_more_sections;
	}

      /* First one is called ".text" or whatever; subsequent ones are
	 ".text1", ".text2", ...  */
      bfd_set_error (bfd_error_no_error);
      sect = bfd_make_section_with_flags (abfd, section_name, flags);
      trynum = 0;

      while (!sect)
	{
	  if (bfd_get_error () != bfd_error_no_error)
	    /* Some other error -- slide into the sunset.  */
	    return NULL;
	  sprintf (try_again, "%s%d", section_name, ++trynum);
	  sect = bfd_make_section_with_flags (abfd, try_again, flags);
	}

      /* Fix the name, if it is a sprintf'd name.  */
      if (sect->name == try_again)
	{
	  amt = strlen (sect->name);
	  newname = bfd_zalloc (abfd, amt);
	  if (newname == NULL)
	    return NULL;
	  strcpy (newname, sect->name);
	  sect->name = newname;
	}

      /* Assumed big-endian.  */
      sect->size = ((ext->e_size[0] << 8)
		    | ext->e_size[1] << 8
		    | ext->e_size[2]);
      sect->vma = H_GET_32 (abfd, ext->e_virtbase);
      sect->filepos = H_GET_32 (abfd, ext->e_filebase);
      /* FIXME XXX alignment?  */

      /* Set relocation information for first section of each type.  */
      if (trynum == 0)
	switch (ext->e_type[0])
	  {
	  case N_TEXT:
	    sect->rel_filepos = N_TRELOFF (*execp);
	    sect->reloc_count = execp->a_trsize;
	    break;

	  case N_DATA:
	    sect->rel_filepos = N_DRELOFF (*execp);
	    sect->reloc_count = execp->a_drsize;
	    break;

	  default:
	    break;
	  }
    }
 no_more_sections:

  adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
  adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
  adata (abfd).page_size = 1; /* Not applicable.  */
  adata (abfd).segment_size = 1; /* Not applicable.  */
  adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;

  return abfd->xvec;
}
Exemplo n.º 29
0
static const bfd_target *
irix_core_core_file_p (bfd *abfd)
{
  int val;
  struct coreout coreout;
  struct idesc *idg, *idf, *ids;
  bfd_size_type amt;

  val = bfd_bread ((PTR) &coreout, (bfd_size_type) sizeof coreout, abfd);
  if (val != sizeof coreout)
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      return 0;
    }

  if (coreout.c_version != CORE_VERSION1)
    return 0;

  /* Have we got a corefile?  */
  switch (coreout.c_magic)
    {
    case CORE_MAGIC:	break;
#ifdef CORE_MAGIC64
    case CORE_MAGIC64:	break;
#endif
#ifdef CORE_MAGICN32
    case CORE_MAGICN32:	break;
#endif
    default:		return 0;	/* Un-identifiable or not corefile.  */
    }

  amt = sizeof (struct sgi_core_struct);
  core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, amt);
  if (!core_hdr (abfd))
    return NULL;

  strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
  core_signal (abfd) = coreout.c_sigcause;

  if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0)
    goto fail;

  /* Process corefile sections.  */
#ifdef CORE_MAGIC64
  if (coreout.c_magic == (int) CORE_MAGIC64)
    {
      if (! do_sections64 (abfd, & coreout))
	goto fail;
    }
  else
#endif
    if (! do_sections (abfd, & coreout))
      goto fail;

  /* Make sure that the regs are contiguous within the core file.  */

  idg = &coreout.c_idesc[I_GPREGS];
  idf = &coreout.c_idesc[I_FPREGS];
  ids = &coreout.c_idesc[I_SPECREGS];

  if (idg->i_offset + idg->i_len != idf->i_offset
      || idf->i_offset + idf->i_len != ids->i_offset)
    goto fail;			/* Can't deal with non-contig regs */

  if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0)
    goto fail;

  if (!make_bfd_asection (abfd, ".reg",
			  SEC_HAS_CONTENTS,
			  idg->i_len + idf->i_len + ids->i_len,
			  0,
			  idg->i_offset))
    goto fail;

  /* OK, we believe you.  You're a core file (sure, sure).  */
  bfd_default_set_arch_mach (abfd, bfd_arch_mips, 0);

  return abfd->xvec;

 fail:
  bfd_release (abfd, core_hdr (abfd));
  core_hdr (abfd) = NULL;
  bfd_section_list_clear (abfd);
  return NULL;
}
Exemplo n.º 30
0
int
main (int argc, char **argv)
{
  char *emulation;
  long start_time = get_run_time ();

#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
  setlocale (LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
  setlocale (LC_CTYPE, "");
#endif
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  program_name = argv[0];
  xmalloc_set_program_name (program_name);

  START_PROGRESS (program_name, 0);

  expandargv (&argc, &argv);

  bfd_init ();

  bfd_set_error_program_name (program_name);

  xatexit (ld_cleanup);

  /* Set up the sysroot directory.  */
  ld_sysroot = get_sysroot (argc, argv);
  if (*ld_sysroot)
    {
      if (*TARGET_SYSTEM_ROOT == 0)
	{
	  einfo ("%P%F: this linker was not configured to use sysroots\n");
	  ld_sysroot = "";
	}
      else
	ld_canon_sysroot = lrealpath (ld_sysroot);
    }
  if (ld_canon_sysroot)
    ld_canon_sysroot_len = strlen (ld_canon_sysroot);
  else
    ld_canon_sysroot_len = -1;

  /* Set the default BFD target based on the configured target.  Doing
     this permits the linker to be configured for a particular target,
     and linked against a shared BFD library which was configured for
     a different target.  The macro TARGET is defined by Makefile.  */
  if (! bfd_set_default_target (TARGET))
    {
      einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
      xexit (1);
    }

#if YYDEBUG
  {
    extern int yydebug;
    yydebug = 1;
  }
#endif

  config.build_constructors = TRUE;
  config.rpath_separator = ':';
  config.split_by_reloc = (unsigned) -1;
  config.split_by_file = (bfd_size_type) -1;
  config.make_executable = TRUE;
  config.magic_demand_paged = TRUE;
  config.text_read_only = TRUE;

  command_line.warn_mismatch = TRUE;
  command_line.warn_search_mismatch = TRUE;
  command_line.check_section_addresses = -1;
  command_line.disable_target_specific_optimizations = -1;

  /* We initialize DEMANGLING based on the environment variable
     COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
     output of the linker, unless COLLECT_NO_DEMANGLE is set in the
     environment.  Acting the same way here lets us provide the same
     interface by default.  */
  demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;

  link_info.allow_undefined_version = TRUE;
  link_info.keep_memory = TRUE;
  link_info.combreloc = TRUE;
  link_info.strip_discarded = TRUE;
  link_info.emit_hash = TRUE;
  link_info.callbacks = &link_callbacks;
  link_info.input_bfds_tail = &link_info.input_bfds;
  /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
     and _fini symbols.  We are compatible.  */
  link_info.init_function = "_init";
  link_info.fini_function = "_fini";
  link_info.relax_pass = 1;
  link_info.pei386_auto_import = -1;
  link_info.spare_dynamic_tags = 5;
  link_info.path_separator = ':';

  ldfile_add_arch ("");
  emulation = get_emulation (argc, argv);
  ldemul_choose_mode (emulation);
  default_target = ldemul_choose_target (argc, argv);
  config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
  config.commonpagesize = bfd_emul_get_commonpagesize (default_target);
  lang_init ();
  ldemul_before_parse ();
  lang_has_input_file = FALSE;
  parse_args (argc, argv);

  if (config.hash_table_size != 0)
    bfd_hash_set_default_size (config.hash_table_size);

  ldemul_set_symbols ();

  if (link_info.relocatable)
    {
      if (command_line.check_section_addresses < 0)
	command_line.check_section_addresses = 0;
      if (link_info.shared)
	einfo (_("%P%F: -r and -shared may not be used together\n"));
    }

  /* We may have -Bsymbolic, -Bsymbolic-functions, --dynamic-list-data,
     --dynamic-list-cpp-new, --dynamic-list-cpp-typeinfo and
     --dynamic-list FILE.  -Bsymbolic and -Bsymbolic-functions are
     for shared libraries.  -Bsymbolic overrides all others and vice
     versa.  */
  switch (command_line.symbolic)
    {
    case symbolic_unset:
      break;
    case symbolic:
      /* -Bsymbolic is for shared library only.  */
      if (link_info.shared)
	{
	  link_info.symbolic = TRUE;
	  /* Should we free the unused memory?  */
	  link_info.dynamic_list = NULL;
	  command_line.dynamic_list = dynamic_list_unset;
	}
      break;
    case symbolic_functions:
      /* -Bsymbolic-functions is for shared library only.  */
      if (link_info.shared)
	command_line.dynamic_list = dynamic_list_data;
      break;
    }

  switch (command_line.dynamic_list)
    {
    case dynamic_list_unset:
      break;
    case dynamic_list_data:
      link_info.dynamic_data = TRUE;
    case dynamic_list:
      link_info.dynamic = TRUE;
      break;
    }

  if (! link_info.shared)
    {
      if (command_line.filter_shlib)
	einfo (_("%P%F: -F may not be used without -shared\n"));
      if (command_line.auxiliary_filters)
	einfo (_("%P%F: -f may not be used without -shared\n"));
    }

  if (! link_info.shared || link_info.pie)
    link_info.executable = TRUE;

  /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols).  I
     don't see how else this can be handled, since in this case we
     must preserve all externally visible symbols.  */
  if (link_info.relocatable && link_info.strip == strip_all)
    {
      link_info.strip = strip_debugger;
      if (link_info.discard == discard_sec_merge)
	link_info.discard = discard_all;
    }

  /* If we have not already opened and parsed a linker script,
     try the default script from command line first.  */
  if (saved_script_handle == NULL
      && command_line.default_script != NULL)
    {
      ldfile_open_command_file (command_line.default_script);
      parser_input = input_script;
      yyparse ();
    }

  /* If we have not already opened and parsed a linker script
     read the emulation's appropriate default script.  */
  if (saved_script_handle == NULL)
    {
      int isfile;
      char *s = ldemul_get_script (&isfile);

      if (isfile)
	ldfile_open_default_command_file (s);
      else
	{
	  lex_string = s;
	  lex_redirect (s);
	}
      parser_input = input_script;
      yyparse ();
      lex_string = NULL;
    }

  if (trace_file_tries)
    {
      if (saved_script_handle)
	info_msg (_("using external linker script:"));
      else
	info_msg (_("using internal linker script:"));
      info_msg ("\n==================================================\n");

      if (saved_script_handle)
	{
	  static const int ld_bufsz = 8193;
	  size_t n;
	  char *buf = (char *) xmalloc (ld_bufsz);

	  rewind (saved_script_handle);
	  while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0)
	    {
	      buf[n] = 0;
	      info_msg (buf);
	    }
	  rewind (saved_script_handle);
	  free (buf);
	}
      else
	{
	  int isfile;

	  info_msg (ldemul_get_script (&isfile));
	}

      info_msg ("\n==================================================\n");
    }

  lang_final ();

  if (!lang_has_input_file)
    {
      if (version_printed)
	xexit (0);
      einfo (_("%P%F: no input files\n"));
    }

  if (trace_files)
    info_msg (_("%P: mode %s\n"), emulation);

  ldemul_after_parse ();

  if (config.map_filename)
    {
      if (strcmp (config.map_filename, "-") == 0)
	{
	  config.map_file = stdout;
	}
      else
	{
	  config.map_file = fopen (config.map_filename, FOPEN_WT);
	  if (config.map_file == (FILE *) NULL)
	    {
	      bfd_set_error (bfd_error_system_call);
	      einfo (_("%P%F: cannot open map file %s: %E\n"),
		     config.map_filename);
	    }
	}
    }

  lang_process ();

  /* Print error messages for any missing symbols, for any warning
     symbols, and possibly multiple definitions.  */
  if (link_info.relocatable)
    link_info.output_bfd->flags &= ~EXEC_P;
  else
    link_info.output_bfd->flags |= EXEC_P;

  ldwrite ();

  if (config.map_file != NULL)
    lang_map ();
  if (command_line.cref)
    output_cref (config.map_file != NULL ? config.map_file : stdout);
  if (nocrossref_list != NULL)
    check_nocrossrefs ();

  lang_finish ();

  /* Even if we're producing relocatable output, some non-fatal errors should
     be reported in the exit status.  (What non-fatal errors, if any, do we
     want to ignore for relocatable output?)  */
  if (!config.make_executable && !force_make_executable)
    {
      if (trace_files)
	einfo (_("%P: link errors found, deleting executable `%s'\n"),
	       output_filename);

      /* The file will be removed by remove_output.  */
      xexit (1);
    }
  else
    {
      if (! bfd_close (link_info.output_bfd))
	einfo (_("%F%B: final close failed: %E\n"), link_info.output_bfd);

      /* If the --force-exe-suffix is enabled, and we're making an
	 executable file and it doesn't end in .exe, copy it to one
	 which does.  */
      if (! link_info.relocatable && command_line.force_exe_suffix)
	{
	  int len = strlen (output_filename);

	  if (len < 4
	      || (strcasecmp (output_filename + len - 4, ".exe") != 0
		  && strcasecmp (output_filename + len - 4, ".dll") != 0))
	    {
	      FILE *src;
	      FILE *dst;
	      const int bsize = 4096;
	      char *buf = (char *) xmalloc (bsize);
	      int l;
	      char *dst_name = (char *) xmalloc (len + 5);

	      strcpy (dst_name, output_filename);
	      strcat (dst_name, ".exe");
	      src = fopen (output_filename, FOPEN_RB);
	      dst = fopen (dst_name, FOPEN_WB);

	      if (!src)
		einfo (_("%X%P: unable to open for source of copy `%s'\n"),
		       output_filename);
	      if (!dst)
		einfo (_("%X%P: unable to open for destination of copy `%s'\n"),
		       dst_name);
	      while ((l = fread (buf, 1, bsize, src)) > 0)
		{
		  int done = fwrite (buf, 1, l, dst);

		  if (done != l)
		    einfo (_("%P: Error writing file `%s'\n"), dst_name);
		}

	      fclose (src);
	      if (fclose (dst) == EOF)
		einfo (_("%P: Error closing file `%s'\n"), dst_name);
	      free (dst_name);
	      free (buf);
	    }
	}
    }

  END_PROGRESS (program_name);

  if (config.stats)
    {
#ifdef HAVE_SBRK
      char *lim = (char *) sbrk (0);
#endif
      long run_time = get_run_time () - start_time;

      fflush (stdout);
      fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
	       program_name, run_time / 1000000, run_time % 1000000);
#ifdef HAVE_SBRK
      fprintf (stderr, _("%s: data size %ld\n"), program_name,
	       (long) (lim - (char *) &environ));
#endif
      fflush (stderr);
    }

  /* Prevent remove_output from doing anything, after a successful link.  */
  output_filename = NULL;

  xexit (0);
  return 0;
}