/* BFD semi-generic back-end for a.out binaries.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Written by Cygnus Support.
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 2 of the License, or
+ 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,
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. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
/*
SECTION
#define KEEPIT udata.i
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "safe-ctype.h"
#include "bfdlink.h"
#include "aout/stab_gnu.h"
#include "aout/ar.h"
-reloc_howto_type * NAME (aout, reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
-
/*
SUBSECTION
Relocations
int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
if (code == BFD_RELOC_CTOR)
- switch (bfd_get_arch_info (abfd)->bits_per_address)
+ switch (bfd_arch_bits_per_address (abfd))
{
case 32:
code = BFD_RELOC_32;
}
}
+reloc_howto_type *
+NAME (aout, reloc_name_lookup) (bfd *abfd, const char *r_name)
+{
+ unsigned int i, size;
+ reloc_howto_type *howto_table;
+
+ if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
+ {
+ howto_table = howto_table_ext;
+ size = sizeof (howto_table_ext) / sizeof (howto_table_ext[0]);
+ }
+ else
+ {
+ howto_table = howto_table_std;
+ size = sizeof (howto_table_std) / sizeof (howto_table_std[0]);
+ }
+
+ for (i = 0; i < size; i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
/*
SUBSECTION
Internal entry points
const bfd_target *result;
bfd_size_type amt = sizeof (* rawptr);
- rawptr = bfd_zalloc (abfd, amt);
+ rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
if (rawptr == NULL)
return NULL;
if (execp->a_entry != 0
|| (execp->a_entry >= obj_textsec (abfd)->vma
&& execp->a_entry < (obj_textsec (abfd)->vma
- + obj_textsec (abfd)->size)))
+ + obj_textsec (abfd)->size)
+ && execp->a_trsize == 0
+ && execp->a_drsize == 0))
abfd->flags |= EXEC_P;
#ifdef STAT_FOR_EXEC
else
bfd_set_error (bfd_error_system_call);
- rawptr = bfd_zalloc (abfd, amt);
+ rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
if (rawptr == NULL)
return FALSE;
case bfd_mach_mips9000:
case bfd_mach_mips10000:
case bfd_mach_mips12000:
+ case bfd_mach_mips14000:
+ case bfd_mach_mips16000:
case bfd_mach_mips16:
case bfd_mach_mipsisa32:
case bfd_mach_mipsisa32r2:
case bfd_mach_mipsisa64:
case bfd_mach_mipsisa64r2:
case bfd_mach_mips_sb1:
+ case bfd_mach_mips_xlr:
/* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc. */
arch_flags = M_MIPS2;
break;
{
obj_textsec (abfd)= newsect;
newsect->target_index = N_TEXT;
- return TRUE;
}
-
- if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
+ else if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
{
obj_datasec (abfd) = newsect;
newsect->target_index = N_DATA;
- return TRUE;
}
-
- if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
+ else if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
{
obj_bsssec (abfd) = newsect;
newsect->target_index = N_BSS;
- return TRUE;
}
}
/* We allow more than three sections internally. */
- return TRUE;
+ return _bfd_generic_new_section_hook (abfd, newsect);
}
bfd_boolean
{
bfd_size_type count;
struct external_nlist *syms;
- bfd_size_type amt;
count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
+ if (count == 0)
+ return TRUE; /* Nothing to do. */
#ifdef USE_MMAP
if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
/* We allocate using malloc to make the values easy to free
later on. If we put them on the objalloc it might not be
possible to free them. */
- syms = bfd_malloc (count * EXTERNAL_NLIST_SIZE);
- if (syms == NULL && count != 0)
+ syms = (struct external_nlist *) bfd_malloc (count * EXTERNAL_NLIST_SIZE);
+ if (syms == NULL)
return FALSE;
- amt = exec_hdr (abfd)->a_syms;
- if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
- || bfd_bread (syms, amt, abfd) != amt)
- {
- free (syms);
- return FALSE;
- }
+ {
+ bfd_size_type amt;
+ amt = exec_hdr (abfd)->a_syms;
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_bread (syms, amt, abfd) != amt)
+ {
+ free (syms);
+ return FALSE;
+ }
+ }
#endif
obj_aout_external_syms (abfd) = syms;
return FALSE;
strings = (char *) obj_aout_string_window (abfd).data;
#else
- strings = bfd_malloc (stringsize + 1);
+ strings = (char *) bfd_malloc (stringsize + 1);
if (strings == NULL)
return FALSE;
{
bfd_size_type amt = sizeof (aout_symbol_type);
- aout_symbol_type *new = bfd_zalloc (abfd, amt);
- if (!new)
+ aout_symbol_type *new_symbol = (aout_symbol_type *) bfd_zalloc (abfd, amt);
+ if (!new_symbol)
return NULL;
- new->symbol.the_bfd = abfd;
+ new_symbol->symbol.the_bfd = abfd;
- return &new->symbol;
+ return &new_symbol->symbol;
}
/* Translate a set of internal symbols into external symbols. */
return FALSE;
cached_size = obj_aout_external_sym_count (abfd);
+ if (cached_size == 0)
+ return TRUE; /* Nothing to do. */
+
cached_size *= sizeof (aout_symbol_type);
- cached = bfd_zmalloc (cached_size);
- if (cached == NULL && cached_size != 0)
+ cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
+ if (cached == NULL)
return FALSE;
/* Convert from external symbol information to internal. */
bfd_boolean copy)
{
bfd_boolean hash;
- bfd_size_type index;
+ bfd_size_type str_index;
/* An index of 0 always means the empty string. */
if (str == 0 || *str == '\0')
if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
hash = FALSE;
- index = _bfd_stringtab_add (tab, str, hash, copy);
+ str_index = _bfd_stringtab_add (tab, str, hash, copy);
- if (index != (bfd_size_type) -1)
+ if (str_index != (bfd_size_type) -1)
/* Add BYTES_IN_WORD to the return value to account for the
space taken up by the string table size. */
- index += BYTES_IN_WORD;
+ str_index += BYTES_IN_WORD;
- return index;
+ return str_index;
}
/* Write out a strtab. ABFD is already at the right location in the
if (bfd_is_com_section (output_section)
|| bfd_is_abs_section (output_section)
- || bfd_is_und_section (output_section))
+ || bfd_is_und_section (output_section)
+ /* PR gas/3041 a.out relocs against weak symbols
+ must be treated as if they were against externs. */
+ || (sym->flags & BSF_WEAK))
{
if (bfd_abs_section_ptr->symbol == sym)
{
>> RELOC_EXT_BITS_TYPE_SH_LITTLE);
}
- cache_ptr->howto = howto_table_ext + r_type;
+ if (r_type < TABLE_SIZE (howto_table_ext))
+ cache_ptr->howto = howto_table_ext + r_type;
+ else
+ cache_ptr->howto = NULL;
/* Base relative relocs are always against the symbol table,
regardless of the setting of r_extern. r_extern just reflects
howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
+ 16 * r_jmptable + 32 * r_relative);
- BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
- cache_ptr->howto = howto_table_std + howto_idx;
- BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
+ if (howto_idx < TABLE_SIZE (howto_table_std))
+ {
+ cache_ptr->howto = howto_table_std + howto_idx;
+ if (cache_ptr->howto->type == (unsigned int) -1)
+ cache_ptr->howto = NULL;
+ }
+ else
+ cache_ptr->howto = NULL;
/* Base relative relocs are always against the symbol table,
regardless of the setting of r_extern. r_extern just reflects
return FALSE;
}
+ if (reloc_size == 0)
+ return TRUE; /* Nothing to be done. */
+
if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
return FALSE;
each_size = obj_reloc_entry_size (abfd);
count = reloc_size / each_size;
+ if (count == 0)
+ return TRUE; /* Nothing to be done. */
amt = count * sizeof (arelent);
- reloc_cache = bfd_zmalloc (amt);
- if (reloc_cache == NULL && count != 0)
+ reloc_cache = (arelent *) bfd_zmalloc (amt);
+ if (reloc_cache == NULL)
return FALSE;
relocs = bfd_malloc (reloc_size);
- if (relocs == NULL && reloc_size != 0)
+ if (relocs == NULL)
{
free (reloc_cache);
return FALSE;
each_size = obj_reloc_entry_size (abfd);
natsize = (bfd_size_type) each_size * count;
- native = bfd_zalloc (abfd, natsize);
+ native = (unsigned char *) bfd_zalloc (abfd, natsize);
if (!native)
return FALSE;
adata (abfd).line_buf = buf = NULL;
else
{
- buf = bfd_malloc (filelen + funclen + 3);
+ buf = (char *) bfd_malloc (filelen + funclen + 3);
adata (abfd).line_buf = buf;
if (buf == NULL)
return FALSE;
}
int
-NAME (aout, sizeof_headers) (bfd *abfd, bfd_boolean execable ATTRIBUTE_UNUSED)
+NAME (aout, sizeof_headers) (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
return adata (abfd).exec_bytes_size;
}
/* Allocate the structure if it has not already been allocated by a
subclass. */
if (ret == NULL)
- ret = bfd_hash_allocate (table, sizeof (* ret));
+ ret = (struct aout_link_hash_entry *) bfd_hash_allocate (table,
+ sizeof (* ret));
if (ret == NULL)
return NULL;
bfd *abfd,
struct bfd_hash_entry *(*newfunc)
(struct bfd_hash_entry *, struct bfd_hash_table *,
- const char *))
+ const char *),
+ unsigned int entsize)
{
- return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
+ return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
}
/* Create an a.out link hash table. */
struct aout_link_hash_table *ret;
bfd_size_type amt = sizeof (* ret);
- ret = bfd_malloc (amt);
+ ret = (struct aout_link_hash_table *) bfd_malloc (amt);
if (ret == NULL)
return NULL;
- if (! NAME (aout, link_hash_table_init) (ret, abfd,
- NAME (aout, link_hash_newfunc)))
+ if (!NAME (aout, link_hash_table_init) (ret, abfd,
+ NAME (aout, link_hash_newfunc),
+ sizeof (struct aout_link_hash_entry)))
{
free (ret);
return NULL;
return FALSE;
}
+ if (sym_count == 0)
+ return TRUE; /* Nothing to do. */
+
/* We keep a list of the linker hash table entries that correspond
to particular symbols. We could just look them up in the hash
table, but keeping the list is more efficient. Perhaps this
should be conditional on info->keep_memory. */
amt = sym_count * sizeof (struct aout_link_hash_entry *);
- sym_hash = bfd_alloc (abfd, amt);
- if (sym_hash == NULL && sym_count != 0)
+ sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
+ if (sym_hash == NULL)
return FALSE;
obj_aout_sym_hashes (abfd) = sym_hash;
static bfd_boolean
aout_link_check_ar_symbols (bfd *abfd,
struct bfd_link_info *info,
- bfd_boolean *pneeded)
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
{
struct external_nlist *p;
struct external_nlist *pend;
{
int skip = 0;
- switch (info->common_skip_ar_aymbols)
+ switch (info->common_skip_ar_symbols)
{
case bfd_link_common_skip_text:
skip = (type == (N_TEXT | N_EXT));
continue;
}
- if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
return FALSE;
*pneeded = TRUE;
return TRUE;
outside BFD. We assume that we should link
in the object file. This is done for the -u
option in the linker. */
- if (! (*info->callbacks->add_archive_element) (info,
- abfd,
- name))
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
return FALSE;
*pneeded = TRUE;
return TRUE;
/* Turn the current link symbol into a common
symbol. It is already on the undefs list. */
h->type = bfd_link_hash_common;
- h->u.c.p = bfd_hash_allocate (&info->hash->table,
- sizeof (struct bfd_link_hash_common_entry));
+ h->u.c.p = (struct bfd_link_hash_common_entry *)
+ bfd_hash_allocate (&info->hash->table,
+ sizeof (struct bfd_link_hash_common_entry));
if (h->u.c.p == NULL)
return FALSE;
it if the current link symbol is common. */
if (h->type == bfd_link_hash_undefined)
{
- if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
return FALSE;
*pneeded = TRUE;
return TRUE;
struct bfd_link_info *info,
bfd_boolean *pneeded)
{
- if (! aout_get_external_symbols (abfd))
+ bfd *oldbfd;
+ bfd_boolean needed;
+
+ if (!aout_get_external_symbols (abfd))
return FALSE;
- if (! aout_link_check_ar_symbols (abfd, info, pneeded))
+ oldbfd = abfd;
+ if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
return FALSE;
- if (*pneeded)
+ needed = *pneeded;
+ if (needed)
{
- if (! aout_link_add_symbols (abfd, info))
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ if (abfd != oldbfd)
+ {
+ if (!info->keep_memory
+ && !aout_link_free_symbols (oldbfd))
+ return FALSE;
+ if (!aout_get_external_symbols (abfd))
+ return FALSE;
+ }
+ if (!aout_link_add_symbols (abfd, info))
return FALSE;
}
- if (! info->keep_memory || ! *pneeded)
+ if (!info->keep_memory || !needed)
{
- if (! aout_link_free_symbols (abfd))
+ if (!aout_link_free_symbols (abfd))
return FALSE;
}
/* Allocate the structure if it has not already been allocated by a
subclass. */
if (ret == NULL)
- ret = bfd_hash_allocate (table, sizeof (* ret));
+ ret = (struct aout_link_includes_entry *)
+ bfd_hash_allocate (table, sizeof (* ret));
if (ret == NULL)
return NULL;
object. */
static bfd_boolean
-aout_link_write_other_symbol (struct aout_link_hash_entry *h, void * data)
+aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
{
- struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
+ struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
+ struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
bfd *output_bfd;
int type;
bfd_vma val;
return TRUE;
}
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
{
if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
- (output_bfd, finfo->info, h)))
+ (output_bfd, flaginfo->info, h)))
{
/* FIXME: No way to handle errors. */
abort ();
/* An indx of -2 means the symbol must be written. */
if (h->indx != -2
- && (finfo->info->strip == strip_all
- || (finfo->info->strip == strip_some
- && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
+ && (flaginfo->info->strip == strip_all
+ || (flaginfo->info->strip == strip_some
+ && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
FALSE, FALSE) == NULL)))
return TRUE;
case bfd_link_hash_undefweak:
type = N_WEAKU;
val = 0;
+ break;
case bfd_link_hash_indirect:
/* We ignore these symbols, since the indirected symbol is
already in the hash table. */
H_PUT_8 (output_bfd, type, outsym.e_type);
H_PUT_8 (output_bfd, 0, outsym.e_other);
H_PUT_16 (output_bfd, 0, outsym.e_desc);
- indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
+ indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string,
FALSE);
if (indx == - (bfd_size_type) 1)
/* FIXME: No way to handle errors. */
PUT_WORD (output_bfd, val, outsym.e_value);
amt = EXTERNAL_NLIST_SIZE;
- if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
|| bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
/* FIXME: No way to handle errors. */
abort ();
- finfo->symoff += EXTERNAL_NLIST_SIZE;
+ flaginfo->symoff += EXTERNAL_NLIST_SIZE;
h->indx = obj_aout_external_sym_count (output_bfd);
++obj_aout_external_sym_count (output_bfd);
/* Handle a link order which is supposed to generate a reloc. */
static bfd_boolean
-aout_link_reloc_link_order (struct aout_final_link_info *finfo,
+aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
asection *o,
struct bfd_link_order *p)
{
r_index = N_ABS | N_EXT;
else
{
- BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
+ BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd);
r_index = pr->u.section->target_index;
}
}
BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
r_extern = 1;
h = ((struct aout_link_hash_entry *)
- bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
+ bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info,
pr->u.name, FALSE, FALSE, TRUE));
if (h != NULL
&& h->indx >= 0)
symbol. */
h->indx = -2;
h->written = FALSE;
- if (! aout_link_write_other_symbol (h, (void *) finfo))
+ if (!aout_link_write_other_symbol (&h->root.root, flaginfo))
return FALSE;
r_index = h->indx;
}
else
{
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
return FALSE;
r_index = 0;
}
}
- howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
+ howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
if (howto == 0)
{
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
- if (o == obj_textsec (finfo->output_bfd))
- reloff_ptr = &finfo->treloff;
- else if (o == obj_datasec (finfo->output_bfd))
- reloff_ptr = &finfo->dreloff;
+ if (o == obj_textsec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->treloff;
+ else if (o == obj_datasec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->dreloff;
else
abort ();
- if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
+ if (obj_reloc_entry_size (flaginfo->output_bfd) == RELOC_STD_SIZE)
{
#ifdef MY_put_reloc
- MY_put_reloc (finfo->output_bfd, r_extern, r_index, p->offset, howto,
+ MY_put_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset, howto,
&srel);
#else
{
r_relative = (howto->type & 32) != 0;
r_length = howto->size;
- PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
- if (bfd_header_big_endian (finfo->output_bfd))
+ PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
+ if (bfd_header_big_endian (flaginfo->output_bfd))
{
srel.r_index[0] = r_index >> 16;
srel.r_index[1] = r_index >> 8;
bfd_boolean ok;
size = bfd_get_reloc_size (howto);
- buf = bfd_zmalloc (size);
+ buf = (bfd_byte *) bfd_zmalloc (size);
if (buf == NULL)
return FALSE;
- r = MY_relocate_contents (howto, finfo->output_bfd,
+ r = MY_relocate_contents (howto, flaginfo->output_bfd,
(bfd_vma) pr->addend, buf);
switch (r)
{
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, NULL,
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, NULL,
(p->type == bfd_section_reloc_link_order
- ? bfd_section_name (finfo->output_bfd,
+ ? bfd_section_name (flaginfo->output_bfd,
pr->u.section)
: pr->u.name),
howto->name, pr->addend, NULL, NULL, (bfd_vma) 0)))
}
break;
}
- ok = bfd_set_section_contents (finfo->output_bfd, o, (void *) buf,
+ ok = bfd_set_section_contents (flaginfo->output_bfd, o, (void *) buf,
(file_ptr) p->offset, size);
free (buf);
if (! ok)
else
{
#ifdef MY_put_ext_reloc
- MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
+ MY_put_ext_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset,
howto, &erel, pr->addend);
#else
- PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
+ PUT_WORD (flaginfo->output_bfd, p->offset, erel.r_address);
- if (bfd_header_big_endian (finfo->output_bfd))
+ if (bfd_header_big_endian (flaginfo->output_bfd))
{
erel.r_index[0] = r_index >> 16;
erel.r_index[1] = r_index >> 8;
| (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
}
- PUT_WORD (finfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
+ PUT_WORD (flaginfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
#endif /* MY_put_ext_reloc */
rel_ptr = (void *) &erel;
}
- amt = obj_reloc_entry_size (finfo->output_bfd);
- if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
- || bfd_bwrite (rel_ptr, amt, finfo->output_bfd) != amt)
+ amt = obj_reloc_entry_size (flaginfo->output_bfd);
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
+ || bfd_bwrite (rel_ptr, amt, flaginfo->output_bfd) != amt)
return FALSE;
- *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
+ *reloff_ptr += obj_reloc_entry_size (flaginfo->output_bfd);
/* Assert that the relocs have not run into the symbols, and that n
the text relocs have not run into the data relocs. */
- BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
- && (reloff_ptr != &finfo->treloff
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
|| (*reloff_ptr
- <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
return TRUE;
}
/* Relocate an a.out section using standard a.out relocs. */
static bfd_boolean
-aout_link_input_section_std (struct aout_final_link_info *finfo,
+aout_link_input_section_std (struct aout_final_link_info *flaginfo,
bfd *input_bfd,
asection *input_section,
struct reloc_std_external *relocs,
struct reloc_std_external *rel;
struct reloc_std_external *rel_end;
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
BFD_ASSERT (input_bfd->xvec->header_byteorder
== output_bfd->xvec->header_byteorder);
- relocatable = finfo->info->relocatable;
+ relocatable = flaginfo->info->relocatable;
syms = obj_aout_external_syms (input_bfd);
strings = obj_aout_external_strings (input_bfd);
sym_hashes = obj_aout_sym_hashes (input_bfd);
- symbol_map = finfo->symbol_map;
+ symbol_map = flaginfo->symbol_map;
reloc_count = rel_size / RELOC_STD_SIZE;
rel = relocs;
howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
+ 16 * r_jmptable + 32 * r_relative);
- BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
- howto = howto_table_std + howto_idx;
+ if (howto_idx < TABLE_SIZE (howto_table_std))
+ howto = howto_table_std + howto_idx;
+ else
+ howto = NULL;
}
#endif
+ if (howto == NULL)
+ {
+ (*flaginfo->info->callbacks->einfo)
+ (_("%P: %B: unexpected relocation type\n"), input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
if (relocatable)
{
/* We are generating a relocatable output file, and must
{
h->indx = -2;
h->written = FALSE;
- if (! aout_link_write_other_symbol (h,
- (void *) finfo))
+ if (!aout_link_write_other_symbol (&h->root.root,
+ flaginfo))
return FALSE;
}
r_index = h->indx;
name = strings + GET_WORD (input_bfd,
syms[r_index].e_strx);
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, name, input_bfd, input_section,
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, name, input_bfd, input_section,
r_addr)))
return FALSE;
r_index = 0;
bfd_boolean skip;
if (! ((*check_dynamic_reloc)
- (finfo->info, input_bfd, input_section, h,
+ (flaginfo->info, input_bfd, input_section, h,
(void *) rel, contents, &skip, &relocation)))
return FALSE;
if (skip)
/* Now warn if a global symbol is undefined. We could not
do this earlier, because check_dynamic_reloc might want
to skip this reloc. */
- if (hundef && ! finfo->info->shared && ! r_baserel)
+ if (hundef && ! flaginfo->info->shared && ! r_baserel)
{
const char *name;
name = h->root.root.string;
else
name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
- if (! ((*finfo->info->callbacks->undefined_symbol)
- (finfo->info, name, input_bfd, input_section,
+ if (! ((*flaginfo->info->callbacks->undefined_symbol)
+ (flaginfo->info, name, input_bfd, input_section,
r_addr, TRUE)))
return FALSE;
}
s = aout_reloc_index_to_section (input_bfd, r_index);
name = bfd_section_name (input_bfd, s);
}
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, (h ? &h->root : NULL), name,
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, (h ? &h->root : NULL), name,
howto->name, (bfd_vma) 0, input_bfd,
input_section, r_addr)))
return FALSE;
/* Relocate an a.out section using extended a.out relocs. */
static bfd_boolean
-aout_link_input_section_ext (struct aout_final_link_info *finfo,
+aout_link_input_section_ext (struct aout_final_link_info *flaginfo,
bfd *input_bfd,
asection *input_section,
struct reloc_ext_external *relocs,
struct reloc_ext_external *rel;
struct reloc_ext_external *rel_end;
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
BFD_ASSERT (input_bfd->xvec->header_byteorder
== output_bfd->xvec->header_byteorder);
- relocatable = finfo->info->relocatable;
+ relocatable = flaginfo->info->relocatable;
syms = obj_aout_external_syms (input_bfd);
strings = obj_aout_external_strings (input_bfd);
sym_hashes = obj_aout_sym_hashes (input_bfd);
- symbol_map = finfo->symbol_map;
+ symbol_map = flaginfo->symbol_map;
reloc_count = rel_size / RELOC_EXT_SIZE;
rel = relocs;
r_addend = GET_SWORD (input_bfd, rel->r_addend);
- BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
+ if (r_type >= TABLE_SIZE (howto_table_ext))
+ {
+ (*flaginfo->info->callbacks->einfo)
+ (_("%P: %B: unexpected relocation type\n"), input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
if (relocatable)
{
{
h->indx = -2;
h->written = FALSE;
- if (! aout_link_write_other_symbol (h,
- (void *) finfo))
+ if (!aout_link_write_other_symbol (&h->root.root,
+ flaginfo))
return FALSE;
}
r_index = h->indx;
name = strings + GET_WORD (input_bfd,
syms[r_index].e_strx);
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, name, input_bfd, input_section,
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, name, input_bfd, input_section,
r_addr)))
return FALSE;
r_index = 0;
bfd_boolean skip;
if (! ((*check_dynamic_reloc)
- (finfo->info, input_bfd, input_section, h,
+ (flaginfo->info, input_bfd, input_section, h,
(void *) rel, contents, &skip, &relocation)))
return FALSE;
if (skip)
do this earlier, because check_dynamic_reloc might want
to skip this reloc. */
if (hundef
- && ! finfo->info->shared
+ && ! flaginfo->info->shared
&& r_type != (unsigned int) RELOC_BASE10
&& r_type != (unsigned int) RELOC_BASE13
&& r_type != (unsigned int) RELOC_BASE22)
name = h->root.root.string;
else
name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
- if (! ((*finfo->info->callbacks->undefined_symbol)
- (finfo->info, name, input_bfd, input_section,
+ if (! ((*flaginfo->info->callbacks->undefined_symbol)
+ (flaginfo->info, name, input_bfd, input_section,
r_addr, TRUE)))
return FALSE;
}
s = aout_reloc_index_to_section (input_bfd, r_index);
name = bfd_section_name (input_bfd, s);
}
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, (h ? &h->root : NULL), name,
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, (h ? &h->root : NULL), name,
howto_table_ext[r_type].name,
r_addend, input_bfd, input_section, r_addr)))
return FALSE;
/* Link an a.out section into the output file. */
static bfd_boolean
-aout_link_input_section (struct aout_final_link_info *finfo,
+aout_link_input_section (struct aout_final_link_info *flaginfo,
bfd *input_bfd,
asection *input_section,
file_ptr *reloff_ptr,
/* Get the section contents. */
input_size = input_section->size;
if (! bfd_get_section_contents (input_bfd, input_section,
- (void *) finfo->contents,
+ (void *) flaginfo->contents,
(file_ptr) 0, input_size))
return FALSE;
relocs = aout_section_data (input_section)->relocs;
else
{
- relocs = finfo->relocs;
+ relocs = flaginfo->relocs;
if (rel_size > 0)
{
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
/* Relocate the section contents. */
if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
{
- if (! aout_link_input_section_std (finfo, input_bfd, input_section,
+ if (! aout_link_input_section_std (flaginfo, input_bfd, input_section,
(struct reloc_std_external *) relocs,
- rel_size, finfo->contents))
+ rel_size, flaginfo->contents))
return FALSE;
}
else
{
- if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
+ if (! aout_link_input_section_ext (flaginfo, input_bfd, input_section,
(struct reloc_ext_external *) relocs,
- rel_size, finfo->contents))
+ rel_size, flaginfo->contents))
return FALSE;
}
/* Write out the section contents. */
- if (! bfd_set_section_contents (finfo->output_bfd,
+ if (! bfd_set_section_contents (flaginfo->output_bfd,
input_section->output_section,
- (void *) finfo->contents,
+ (void *) flaginfo->contents,
(file_ptr) input_section->output_offset,
input_size))
return FALSE;
/* If we are producing relocatable output, the relocs were
modified, and we now write them out. */
- if (finfo->info->relocatable && rel_size > 0)
+ if (flaginfo->info->relocatable && rel_size > 0)
{
- if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
return FALSE;
- if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
+ if (bfd_bwrite (relocs, rel_size, flaginfo->output_bfd) != rel_size)
return FALSE;
*reloff_ptr += rel_size;
/* Assert that the relocs have not run into the symbols, and
that if these are the text relocs they have not run into the
data relocs. */
- BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
- && (reloff_ptr != &finfo->treloff
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
|| (*reloff_ptr
- <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
}
return TRUE;
symbol indices into a symbol_map. */
static bfd_boolean
-aout_link_write_symbols (struct aout_final_link_info *finfo, bfd *input_bfd)
+aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
{
bfd *output_bfd;
bfd_size_type sym_count;
bfd_boolean pass;
bfd_boolean skip_next;
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
sym_count = obj_aout_external_sym_count (input_bfd);
strings = obj_aout_external_strings (input_bfd);
- strip = finfo->info->strip;
- discard = finfo->info->discard;
- outsym = finfo->output_syms;
+ strip = flaginfo->info->strip;
+ discard = flaginfo->info->discard;
+ outsym = flaginfo->output_syms;
/* First write out a symbol for this object file, unless we are
discarding such symbols. */
if (strip != strip_all
&& (strip != strip_some
- || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
+ || bfd_hash_lookup (flaginfo->info->keep_hash, input_bfd->filename,
FALSE, FALSE) != NULL)
&& discard != discard_all)
{
H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
H_PUT_8 (output_bfd, 0, outsym->e_other);
H_PUT_16 (output_bfd, 0, outsym->e_desc);
- strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
input_bfd->filename, FALSE);
if (strtab_index == (bfd_size_type) -1)
return FALSE;
sym = obj_aout_external_syms (input_bfd);
sym_end = sym + sym_count;
sym_hash = obj_aout_sym_hashes (input_bfd);
- symbol_map = finfo->symbol_map;
+ symbol_map = flaginfo->symbol_map;
memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
{
skip = TRUE;
break;
case strip_some:
- if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
+ if (bfd_hash_lookup (flaginfo->info->keep_hash, name, FALSE, FALSE)
== NULL)
skip = TRUE;
break;
/* If we have already included a header file with the
same value, then replace this one with an N_EXCL
symbol. */
- copy = (bfd_boolean) (! finfo->info->keep_memory);
- incl_entry = aout_link_includes_lookup (&finfo->includes,
+ copy = (bfd_boolean) (! flaginfo->info->keep_memory);
+ incl_entry = aout_link_includes_lookup (&flaginfo->includes,
name, TRUE, copy);
if (incl_entry == NULL)
return FALSE;
{
/* This is the first time we have seen this header
file with this set of stabs strings. */
- t = bfd_hash_allocate (&finfo->includes.root,
+ t = (struct aout_link_includes_totals *)
+ bfd_hash_allocate (&flaginfo->includes.root,
sizeof *t);
if (t == NULL)
return FALSE;
H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
copy = FALSE;
- if (! finfo->info->keep_memory)
+ if (! flaginfo->info->keep_memory)
{
/* name points into a string table which we are going to
free. If there is a hash table entry, use that string.
else
copy = TRUE;
}
- strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
name, copy);
if (strtab_index == (bfd_size_type) -1)
return FALSE;
}
/* Write out the output symbols we have just constructed. */
- if (outsym > finfo->output_syms)
+ if (outsym > flaginfo->output_syms)
{
bfd_size_type outsym_size;
- if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
return FALSE;
- outsym_size = outsym - finfo->output_syms;
+ outsym_size = outsym - flaginfo->output_syms;
outsym_size *= EXTERNAL_NLIST_SIZE;
- if (bfd_bwrite ((void *) finfo->output_syms, outsym_size, output_bfd)
+ if (bfd_bwrite ((void *) flaginfo->output_syms, outsym_size, output_bfd)
!= outsym_size)
return FALSE;
- finfo->symoff += outsym_size;
+ flaginfo->symoff += outsym_size;
}
return TRUE;
/* Link an a.out input BFD into the output file. */
static bfd_boolean
-aout_link_input_bfd (struct aout_final_link_info *finfo, bfd *input_bfd)
+aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
{
- bfd_size_type sym_count;
-
BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
/* If this is a dynamic object, it may need special handling. */
if ((input_bfd->flags & DYNAMIC) != 0
&& aout_backend_info (input_bfd)->link_dynamic_object != NULL)
return ((*aout_backend_info (input_bfd)->link_dynamic_object)
- (finfo->info, input_bfd));
+ (flaginfo->info, input_bfd));
/* Get the symbols. We probably have them already, unless
- finfo->info->keep_memory is FALSE. */
+ flaginfo->info->keep_memory is FALSE. */
if (! aout_get_external_symbols (input_bfd))
return FALSE;
- sym_count = obj_aout_external_sym_count (input_bfd);
-
/* Write out the symbols and get a map of the new indices. The map
- is placed into finfo->symbol_map. */
- if (! aout_link_write_symbols (finfo, input_bfd))
+ is placed into flaginfo->symbol_map. */
+ if (! aout_link_write_symbols (flaginfo, input_bfd))
return FALSE;
/* Relocate and write out the sections. These functions use the
link, which will normally be the case. */
if (obj_textsec (input_bfd)->linker_mark)
{
- if (! aout_link_input_section (finfo, input_bfd,
+ if (! aout_link_input_section (flaginfo, input_bfd,
obj_textsec (input_bfd),
- &finfo->treloff,
+ &flaginfo->treloff,
exec_hdr (input_bfd)->a_trsize))
return FALSE;
}
if (obj_datasec (input_bfd)->linker_mark)
{
- if (! aout_link_input_section (finfo, input_bfd,
+ if (! aout_link_input_section (flaginfo, input_bfd,
obj_datasec (input_bfd),
- &finfo->dreloff,
+ &flaginfo->dreloff,
exec_hdr (input_bfd)->a_drsize))
return FALSE;
}
/* If we are not keeping memory, we don't need the symbols any
longer. We still need them if we are keeping memory, because the
strings in the hash table point into them. */
- if (! finfo->info->keep_memory)
+ if (! flaginfo->info->keep_memory)
{
if (! aout_link_free_symbols (input_bfd))
return FALSE;
aout_info.symbol_map = NULL;
aout_info.output_syms = NULL;
- if (! bfd_hash_table_init_n (&aout_info.includes.root,
- aout_link_includes_newfunc,
- 251))
+ if (!bfd_hash_table_init_n (&aout_info.includes.root,
+ aout_link_includes_newfunc,
+ sizeof (struct aout_link_includes_entry),
+ 251))
goto error_return;
includes_hash_initialized = TRUE;
goto error_return;
/* Allocate buffers to hold section contents and relocs. */
- aout_info.contents = bfd_malloc (max_contents_size);
+ aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
aout_info.relocs = bfd_malloc (max_relocs_size);
- aout_info.symbol_map = bfd_malloc (max_sym_count * sizeof (int *));
- aout_info.output_syms = bfd_malloc ((max_sym_count + 1)
- * sizeof (struct external_nlist));
+ aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int));
+ aout_info.output_syms = (struct external_nlist *)
+ bfd_malloc ((max_sym_count + 1) * sizeof (struct external_nlist));
if ((aout_info.contents == NULL && max_contents_size != 0)
|| (aout_info.relocs == NULL && max_relocs_size != 0)
|| (aout_info.symbol_map == NULL && max_sym_count != 0)
h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
FALSE, FALSE, FALSE);
if (h != NULL)
- aout_link_write_other_symbol (h, &aout_info);
+ aout_link_write_other_symbol (&h->root.root, &aout_info);
}
/* The most time efficient way to do the link would be to read all
}
/* Write out any symbols that we have not already written out. */
- aout_link_hash_traverse (aout_hash_table (info),
- aout_link_write_other_symbol,
- (void *) &aout_info);
+ bfd_hash_traverse (&info->hash->table,
+ aout_link_write_other_symbol,
+ &aout_info);
/* Now handle any relocs we were asked to create by the linker.
These did not come from any input file. We must do these after
exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
/* Write out the string table, unless there are no symbols. */
+ if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
+ goto error_return;
if (abfd->symcount > 0)
{
- if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
- || ! emit_stringtab (abfd, aout_info.strtab))
+ if (!emit_stringtab (abfd, aout_info.strtab))
goto error_return;
}
- else if (obj_textsec (abfd)->reloc_count == 0
- && obj_datasec (abfd)->reloc_count == 0)
+ else
{
- bfd_byte b;
- file_ptr pos;
+ bfd_byte b[BYTES_IN_WORD];
- b = 0;
- pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
+ memset (b, 0, BYTES_IN_WORD);
+ if (bfd_bwrite (b, (bfd_size_type) BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
goto error_return;
}