* aoutx.h (translate_to_native_sym_flags): Use the output_section
(and output_offset) if there is one. * aoutx.h (aout_link_check_archive_element): Discard the symbols if the archive element was not needed. * aoutx.h (aout_get_external_symbols): Ensure that a zero string index yields an empty string. (aout_link_write_symbols): If info->keep_memory is false, use name from original hash table entry, not from entry in *sym_hash. * aoutx.h (struct aout_final_link_info): Add fields contents, relocs, symbol_map and output_syms. (NAME(aout,final_link)): Work out the largest section size, reloc size, and number of symbols. Use them to preallocate buffers that are large enough for all cases. (aout_link_input_bfd): Use preallocated symbol_map. (aout_link_write_symbols): Remove symbol_map argument; use preallocated symbol_map instead. Change all callers. Use preallocated output_syms. (aout_link_input_section): Remove symbol_map argument. Change all callers. Use preallocated contents and relocs. (aout_link_input_section_std): Remove symbol_map argument; use preallocated symbol_map instead. Change all callers. (aout_link_input_section_ext): Likewise.
This commit is contained in:
parent
70bcd4bc7e
commit
1afd2380ea
|
@ -1,3 +1,37 @@
|
||||||
|
Wed Aug 24 11:49:19 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
||||||
|
|
||||||
|
* aoutx.h (translate_to_native_sym_flags): Use the output_section
|
||||||
|
(and output_offset) if there is one.
|
||||||
|
|
||||||
|
* aoutx.h (aout_link_check_archive_element): Discard the symbols
|
||||||
|
if the archive element was not needed.
|
||||||
|
|
||||||
|
* aoutx.h (aout_get_external_symbols): Ensure that a zero string
|
||||||
|
index yields an empty string.
|
||||||
|
(aout_link_write_symbols): If info->keep_memory is false, use name
|
||||||
|
from original hash table entry, not from entry in *sym_hash.
|
||||||
|
|
||||||
|
* aoutx.h (struct aout_final_link_info): Add fields contents,
|
||||||
|
relocs, symbol_map and output_syms.
|
||||||
|
(NAME(aout,final_link)): Work out the largest section size, reloc
|
||||||
|
size, and number of symbols. Use them to preallocate buffers that
|
||||||
|
are large enough for all cases.
|
||||||
|
(aout_link_input_bfd): Use preallocated symbol_map.
|
||||||
|
(aout_link_write_symbols): Remove symbol_map argument; use
|
||||||
|
preallocated symbol_map instead. Change all callers. Use
|
||||||
|
preallocated output_syms.
|
||||||
|
(aout_link_input_section): Remove symbol_map argument. Change all
|
||||||
|
callers. Use preallocated contents and relocs.
|
||||||
|
(aout_link_input_section_std): Remove symbol_map argument; use
|
||||||
|
preallocated symbol_map instead. Change all callers.
|
||||||
|
(aout_link_input_section_ext): Likewise.
|
||||||
|
|
||||||
|
Tue Aug 23 10:51:09 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
||||||
|
|
||||||
|
* archive.c (_bfd_write_archive_contents): Don't update the
|
||||||
|
symbol map timestamp if there is no symbol map. From
|
||||||
|
schwab@issan.informatik.uni-dortmund.de (Andreas Schwab).
|
||||||
|
|
||||||
Mon Aug 22 12:26:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
Mon Aug 22 12:26:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
|
||||||
|
|
||||||
* targets.c (BFD_JUMP_TABLE_ARCHIVE): Add _update_armap_timestamp.
|
* targets.c (BFD_JUMP_TABLE_ARCHIVE): Add _update_armap_timestamp.
|
||||||
|
|
480
bfd/aoutx.h
480
bfd/aoutx.h
|
@ -1237,6 +1237,9 @@ aout_get_external_symbols (abfd)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure that a zero index yields an empty string. */
|
||||||
|
strings[0] = '\0';
|
||||||
|
|
||||||
/* Sanity preservation. */
|
/* Sanity preservation. */
|
||||||
strings[stringsize] = '\0';
|
strings[stringsize] = '\0';
|
||||||
|
|
||||||
|
@ -1553,7 +1556,11 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn the symbol from section relative to absolute again */
|
/* Turn the symbol from section relative to absolute again */
|
||||||
value += cache_ptr->section->vma;
|
if (cache_ptr->section->output_section != NULL)
|
||||||
|
value += (cache_ptr->section->output_section->vma
|
||||||
|
+ cache_ptr->section->output_offset);
|
||||||
|
else
|
||||||
|
value += cache_ptr->section->vma;
|
||||||
|
|
||||||
if ((cache_ptr->flags & BSF_WARNING) != 0)
|
if ((cache_ptr->flags & BSF_WARNING) != 0)
|
||||||
sym_pointer->e_type[0] = N_WARNING;
|
sym_pointer->e_type[0] = N_WARNING;
|
||||||
|
@ -1739,168 +1746,38 @@ NAME(aout,slurp_symbol_table) (abfd)
|
||||||
contributing object file tends to have many duplicate stabs
|
contributing object file tends to have many duplicate stabs
|
||||||
strings.
|
strings.
|
||||||
|
|
||||||
Possible improvements:
|
|
||||||
+ look for strings matching trailing substrings of other strings
|
|
||||||
+ better data structures? balanced trees?
|
|
||||||
+ look at reducing memory use elsewhere -- maybe if we didn't have
|
|
||||||
to construct the entire symbol table at once, we could get by
|
|
||||||
with smaller amounts of VM? (What effect does that have on the
|
|
||||||
string table reductions?)
|
|
||||||
|
|
||||||
This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
|
This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
|
||||||
if BFD_TRADITIONAL_FORMAT is set. */
|
if BFD_TRADITIONAL_FORMAT is set. */
|
||||||
|
|
||||||
/* An entry in the strtab hash table. */
|
|
||||||
|
|
||||||
struct strtab_hash_entry
|
|
||||||
{
|
|
||||||
struct bfd_hash_entry root;
|
|
||||||
/* Index in string table. */
|
|
||||||
bfd_size_type index;
|
|
||||||
/* Next string in strtab. */
|
|
||||||
struct strtab_hash_entry *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The strtab hash table. */
|
|
||||||
|
|
||||||
struct strtab_hash
|
|
||||||
{
|
|
||||||
struct bfd_hash_table table;
|
|
||||||
/* Size of strtab--also next available index. */
|
|
||||||
bfd_size_type size;
|
|
||||||
/* First string in strtab. */
|
|
||||||
struct strtab_hash_entry *first;
|
|
||||||
/* Last string in strtab. */
|
|
||||||
struct strtab_hash_entry *last;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct bfd_hash_entry *strtab_hash_newfunc
|
|
||||||
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
|
|
||||||
static boolean stringtab_init PARAMS ((struct strtab_hash *));
|
|
||||||
static bfd_size_type add_to_stringtab
|
static bfd_size_type add_to_stringtab
|
||||||
PARAMS ((bfd *, struct strtab_hash *, const char *, boolean));
|
PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
|
||||||
static boolean emit_stringtab PARAMS ((bfd *, struct strtab_hash *));
|
static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
|
||||||
|
|
||||||
/* Routine to create an entry in a strtab. */
|
|
||||||
|
|
||||||
static struct bfd_hash_entry *
|
|
||||||
strtab_hash_newfunc (entry, table, string)
|
|
||||||
struct bfd_hash_entry *entry;
|
|
||||||
struct bfd_hash_table *table;
|
|
||||||
const char *string;
|
|
||||||
{
|
|
||||||
struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry;
|
|
||||||
|
|
||||||
/* Allocate the structure if it has not already been allocated by a
|
|
||||||
subclass. */
|
|
||||||
if (ret == (struct strtab_hash_entry *) NULL)
|
|
||||||
ret = ((struct strtab_hash_entry *)
|
|
||||||
bfd_hash_allocate (table, sizeof (struct strtab_hash_entry)));
|
|
||||||
if (ret == (struct strtab_hash_entry *) NULL)
|
|
||||||
{
|
|
||||||
bfd_set_error (bfd_error_no_memory);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call the allocation method of the superclass. */
|
|
||||||
ret = ((struct strtab_hash_entry *)
|
|
||||||
bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
/* Initialize the local fields. */
|
|
||||||
ret->index = (bfd_size_type) -1;
|
|
||||||
ret->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (struct bfd_hash_entry *) ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look up an entry in an strtab. */
|
|
||||||
|
|
||||||
#define strtab_hash_lookup(t, string, create, copy) \
|
|
||||||
((struct strtab_hash_entry *) \
|
|
||||||
bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
|
|
||||||
|
|
||||||
/* Create a new strtab. */
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
stringtab_init (table)
|
|
||||||
struct strtab_hash *table;
|
|
||||||
{
|
|
||||||
if (! bfd_hash_table_init (&table->table, strtab_hash_newfunc))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Leave space for the size of the string table. */
|
|
||||||
table->size = BYTES_IN_WORD;
|
|
||||||
|
|
||||||
table->first = NULL;
|
|
||||||
table->last = NULL;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free a strtab. */
|
|
||||||
|
|
||||||
#define stringtab_free(tab) bfd_hash_table_free (&(tab)->table)
|
|
||||||
|
|
||||||
/* Get the index of a string in a strtab, adding it if it is not
|
/* Get the index of a string in a strtab, adding it if it is not
|
||||||
already present. If HASH is false, we don't really use the hash
|
already present. */
|
||||||
table, and we don't eliminate duplicate strings. */
|
|
||||||
|
|
||||||
static INLINE bfd_size_type
|
static INLINE bfd_size_type
|
||||||
add_to_stringtab (abfd, tab, str, copy)
|
add_to_stringtab (abfd, tab, str, copy)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
struct strtab_hash *tab;
|
struct bfd_strtab_hash *tab;
|
||||||
const char *str;
|
const char *str;
|
||||||
boolean copy;
|
boolean copy;
|
||||||
{
|
{
|
||||||
register struct strtab_hash_entry *entry;
|
boolean hash;
|
||||||
|
|
||||||
/* An index of 0 always means the empty string. */
|
/* An index of 0 always means the empty string. */
|
||||||
if (*str == '\0')
|
if (*str == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((abfd->flags & BFD_TRADITIONAL_FORMAT) == 0)
|
/* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
|
||||||
{
|
doesn't understand a hashed string table. */
|
||||||
entry = strtab_hash_lookup (tab, str, true, copy);
|
hash = true;
|
||||||
if (entry == NULL)
|
if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
|
||||||
return (bfd_size_type) -1;
|
hash = false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry = ((struct strtab_hash_entry *)
|
|
||||||
bfd_hash_allocate (&tab->table,
|
|
||||||
sizeof (struct strtab_hash_entry)));
|
|
||||||
if (entry == NULL)
|
|
||||||
return (bfd_size_type) -1;
|
|
||||||
if (! copy)
|
|
||||||
entry->root.string = str;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *n;
|
|
||||||
|
|
||||||
n = (char *) bfd_hash_allocate (&tab->table, strlen (str) + 1);
|
/* Add BYTES_IN_WORD to the return value to account for the space
|
||||||
if (n == NULL)
|
taken up by the count. */
|
||||||
return (bfd_size_type) -1;
|
return BYTES_IN_WORD + _bfd_stringtab_add (tab, str, hash, copy);
|
||||||
entry->root.string = n;
|
|
||||||
}
|
|
||||||
entry->index = (bfd_size_type) -1;
|
|
||||||
entry->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry->index == (bfd_size_type) -1)
|
|
||||||
{
|
|
||||||
entry->index = tab->size;
|
|
||||||
tab->size += strlen (str) + 1;
|
|
||||||
if (tab->first == NULL)
|
|
||||||
tab->first = entry;
|
|
||||||
else
|
|
||||||
tab->last->next = entry;
|
|
||||||
tab->last = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry->index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out a strtab. ABFD is already at the right location in the
|
/* Write out a strtab. ABFD is already at the right location in the
|
||||||
|
@ -1909,27 +1786,16 @@ add_to_stringtab (abfd, tab, str, copy)
|
||||||
static boolean
|
static boolean
|
||||||
emit_stringtab (abfd, tab)
|
emit_stringtab (abfd, tab)
|
||||||
register bfd *abfd;
|
register bfd *abfd;
|
||||||
struct strtab_hash *tab;
|
struct bfd_strtab_hash *tab;
|
||||||
{
|
{
|
||||||
bfd_byte buffer[BYTES_IN_WORD];
|
bfd_byte buffer[BYTES_IN_WORD];
|
||||||
register struct strtab_hash_entry *entry;
|
|
||||||
|
|
||||||
PUT_WORD (abfd, tab->size, buffer);
|
/* The string table starts with the size. */
|
||||||
|
PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
|
||||||
if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
|
if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (entry = tab->first; entry != NULL; entry = entry->next)
|
return _bfd_stringtab_emit (abfd, tab);
|
||||||
{
|
|
||||||
register const char *str;
|
|
||||||
register size_t len;
|
|
||||||
|
|
||||||
str = entry->root.string;
|
|
||||||
len = strlen (str) + 1;
|
|
||||||
if (bfd_write ((PTR) str, 1, len, abfd) != len)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
|
@ -1938,9 +1804,10 @@ NAME(aout,write_syms) (abfd)
|
||||||
{
|
{
|
||||||
unsigned int count ;
|
unsigned int count ;
|
||||||
asymbol **generic = bfd_get_outsymbols (abfd);
|
asymbol **generic = bfd_get_outsymbols (abfd);
|
||||||
struct strtab_hash strtab;
|
struct bfd_strtab_hash *strtab;
|
||||||
|
|
||||||
if (! stringtab_init (&strtab))
|
strtab = _bfd_stringtab_init ();
|
||||||
|
if (strtab == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (count = 0; count < bfd_get_symcount (abfd); count++)
|
for (count = 0; count < bfd_get_symcount (abfd); count++)
|
||||||
|
@ -1949,7 +1816,7 @@ NAME(aout,write_syms) (abfd)
|
||||||
bfd_size_type indx;
|
bfd_size_type indx;
|
||||||
struct external_nlist nsp;
|
struct external_nlist nsp;
|
||||||
|
|
||||||
indx = add_to_stringtab (abfd, &strtab, g->name, false);
|
indx = add_to_stringtab (abfd, strtab, g->name, false);
|
||||||
if (indx == (bfd_size_type) -1)
|
if (indx == (bfd_size_type) -1)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
|
PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
|
||||||
|
@ -1979,15 +1846,15 @@ NAME(aout,write_syms) (abfd)
|
||||||
g->KEEPIT = count;
|
g->KEEPIT = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! emit_stringtab (abfd, &strtab))
|
if (! emit_stringtab (abfd, strtab))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
stringtab_free (&strtab);
|
_bfd_stringtab_free (strtab);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
stringtab_free (&strtab);
|
_bfd_stringtab_free (strtab);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2905,11 +2772,7 @@ aout_link_check_archive_element (abfd, info, pneeded)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We keep around the symbols even if we aren't going to use this
|
if (! info->keep_memory || ! *pneeded)
|
||||||
object file, because we may want to reread it. This doesn't
|
|
||||||
waste too much memory, because it isn't all that common to read
|
|
||||||
an archive element but not need it. */
|
|
||||||
if (! info->keep_memory)
|
|
||||||
{
|
{
|
||||||
if (! aout_link_free_symbols (abfd))
|
if (! aout_link_free_symbols (abfd))
|
||||||
return false;
|
return false;
|
||||||
|
@ -3343,27 +3206,35 @@ struct aout_final_link_info
|
||||||
/* File position of symbols. */
|
/* File position of symbols. */
|
||||||
file_ptr symoff;
|
file_ptr symoff;
|
||||||
/* String table. */
|
/* String table. */
|
||||||
struct strtab_hash strtab;
|
struct bfd_strtab_hash *strtab;
|
||||||
|
/* A buffer large enough to hold the contents of any section. */
|
||||||
|
bfd_byte *contents;
|
||||||
|
/* A buffer large enough to hold the relocs of any section. */
|
||||||
|
PTR relocs;
|
||||||
|
/* A buffer large enough to hold the symbol map of any input BFD. */
|
||||||
|
int *symbol_map;
|
||||||
|
/* A buffer large enough to hold output symbols of any input BFD. */
|
||||||
|
struct external_nlist *output_syms;
|
||||||
};
|
};
|
||||||
|
|
||||||
static boolean aout_link_input_bfd
|
static boolean aout_link_input_bfd
|
||||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
|
PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
|
||||||
static boolean aout_link_write_symbols
|
static boolean aout_link_write_symbols
|
||||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd, int *symbol_map));
|
PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
|
||||||
static boolean aout_link_write_other_symbol
|
static boolean aout_link_write_other_symbol
|
||||||
PARAMS ((struct aout_link_hash_entry *, PTR));
|
PARAMS ((struct aout_link_hash_entry *, PTR));
|
||||||
static boolean aout_link_input_section
|
static boolean aout_link_input_section
|
||||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
||||||
asection *input_section, file_ptr *reloff_ptr,
|
asection *input_section, file_ptr *reloff_ptr,
|
||||||
bfd_size_type rel_size, int *symbol_map));
|
bfd_size_type rel_size));
|
||||||
static boolean aout_link_input_section_std
|
static boolean aout_link_input_section_std
|
||||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
||||||
asection *input_section, struct reloc_std_external *,
|
asection *input_section, struct reloc_std_external *,
|
||||||
bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
|
bfd_size_type rel_size, bfd_byte *contents));
|
||||||
static boolean aout_link_input_section_ext
|
static boolean aout_link_input_section_ext
|
||||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
||||||
asection *input_section, struct reloc_ext_external *,
|
asection *input_section, struct reloc_ext_external *,
|
||||||
bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
|
bfd_size_type rel_size, bfd_byte *contents));
|
||||||
static INLINE asection *aout_reloc_index_to_section
|
static INLINE asection *aout_reloc_index_to_section
|
||||||
PARAMS ((bfd *, int));
|
PARAMS ((bfd *, int));
|
||||||
static boolean aout_link_reloc_link_order
|
static boolean aout_link_reloc_link_order
|
||||||
|
@ -3385,6 +3256,10 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
{
|
{
|
||||||
struct aout_final_link_info aout_info;
|
struct aout_final_link_info aout_info;
|
||||||
register bfd *sub;
|
register bfd *sub;
|
||||||
|
bfd_size_type trsize, drsize;
|
||||||
|
size_t max_contents_size;
|
||||||
|
size_t max_relocs_size;
|
||||||
|
size_t max_sym_count;
|
||||||
bfd_size_type text_size;
|
bfd_size_type text_size;
|
||||||
file_ptr text_end;
|
file_ptr text_end;
|
||||||
register struct bfd_link_order *p;
|
register struct bfd_link_order *p;
|
||||||
|
@ -3393,20 +3268,21 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
|
|
||||||
aout_info.info = info;
|
aout_info.info = info;
|
||||||
aout_info.output_bfd = abfd;
|
aout_info.output_bfd = abfd;
|
||||||
|
aout_info.contents = NULL;
|
||||||
|
aout_info.relocs = NULL;
|
||||||
|
|
||||||
if (! info->relocateable)
|
/* Figure out the largest section size. Also, if generating
|
||||||
|
relocateable output, count the relocs. */
|
||||||
|
trsize = 0;
|
||||||
|
drsize = 0;
|
||||||
|
max_contents_size = 0;
|
||||||
|
max_relocs_size = 0;
|
||||||
|
max_sym_count = 0;
|
||||||
|
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
|
||||||
{
|
{
|
||||||
exec_hdr (abfd)->a_trsize = 0;
|
size_t sz;
|
||||||
exec_hdr (abfd)->a_drsize = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bfd_size_type trsize, drsize;
|
|
||||||
|
|
||||||
/* Count up the relocation sizes. */
|
if (info->relocateable)
|
||||||
trsize = 0;
|
|
||||||
drsize = 0;
|
|
||||||
for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
|
|
||||||
{
|
{
|
||||||
if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
|
if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
|
||||||
{
|
{
|
||||||
|
@ -3422,25 +3298,48 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sz = bfd_section_size (sub, obj_textsec (sub));
|
||||||
|
if (sz > max_contents_size)
|
||||||
|
max_contents_size = sz;
|
||||||
|
sz = bfd_section_size (sub, obj_datasec (sub));
|
||||||
|
if (sz > max_contents_size)
|
||||||
|
max_contents_size = sz;
|
||||||
|
|
||||||
|
sz = exec_hdr (sub)->a_trsize;
|
||||||
|
if (sz > max_relocs_size)
|
||||||
|
max_relocs_size = sz;
|
||||||
|
sz = exec_hdr (sub)->a_drsize;
|
||||||
|
if (sz > max_relocs_size)
|
||||||
|
max_relocs_size = sz;
|
||||||
|
|
||||||
|
sz = obj_aout_external_sym_count (sub);
|
||||||
|
if (sz > max_sym_count)
|
||||||
|
max_sym_count = sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->relocateable)
|
||||||
|
{
|
||||||
if (obj_textsec (abfd) != (asection *) NULL)
|
if (obj_textsec (abfd) != (asection *) NULL)
|
||||||
trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
|
trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
|
||||||
->link_order_head)
|
->link_order_head)
|
||||||
* obj_reloc_entry_size (abfd));
|
* obj_reloc_entry_size (abfd));
|
||||||
exec_hdr (abfd)->a_trsize = trsize;
|
|
||||||
if (obj_datasec (abfd) != (asection *) NULL)
|
if (obj_datasec (abfd) != (asection *) NULL)
|
||||||
drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
|
drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
|
||||||
->link_order_head)
|
->link_order_head)
|
||||||
* obj_reloc_entry_size (abfd));
|
* obj_reloc_entry_size (abfd));
|
||||||
exec_hdr (abfd)->a_drsize = drsize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exec_hdr (abfd)->a_trsize = trsize;
|
||||||
|
exec_hdr (abfd)->a_drsize = drsize;
|
||||||
|
|
||||||
exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
|
exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
|
||||||
|
|
||||||
/* Adjust the section sizes and vmas according to the magic number.
|
/* Adjust the section sizes and vmas according to the magic number.
|
||||||
This sets a_text, a_data and a_bss in the exec_hdr and sets the
|
This sets a_text, a_data and a_bss in the exec_hdr and sets the
|
||||||
filepos for each section. */
|
filepos for each section. */
|
||||||
if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
|
if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
|
||||||
return false;
|
goto error_return;
|
||||||
|
|
||||||
/* The relocation and symbol file positions differ among a.out
|
/* The relocation and symbol file positions differ among a.out
|
||||||
targets. We are passed a callback routine from the backend
|
targets. We are passed a callback routine from the backend
|
||||||
|
@ -3460,8 +3359,25 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
obj_aout_external_sym_count (abfd) = 0;
|
obj_aout_external_sym_count (abfd) = 0;
|
||||||
|
|
||||||
/* We accumulate the string table as we write out the symbols. */
|
/* We accumulate the string table as we write out the symbols. */
|
||||||
if (! stringtab_init (&aout_info.strtab))
|
aout_info.strtab = _bfd_stringtab_init ();
|
||||||
return false;
|
if (aout_info.strtab == NULL)
|
||||||
|
goto error_return;
|
||||||
|
|
||||||
|
/* Allocate buffers to hold section contents and relocs. */
|
||||||
|
aout_info.contents = (bfd_byte *) malloc (max_contents_size);
|
||||||
|
aout_info.relocs = (PTR) malloc (max_relocs_size);
|
||||||
|
aout_info.symbol_map = (int *) malloc (max_sym_count * sizeof (int *));
|
||||||
|
aout_info.output_syms = ((struct external_nlist *)
|
||||||
|
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)
|
||||||
|
|| aout_info.output_syms == NULL)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_no_memory);
|
||||||
|
goto error_return;
|
||||||
|
}
|
||||||
|
|
||||||
/* The most time efficient way to do the link would be to read all
|
/* The most time efficient way to do the link would be to read all
|
||||||
the input object files into memory and then sort out the
|
the input object files into memory and then sort out the
|
||||||
|
@ -3504,7 +3420,7 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
if (! input_bfd->output_has_begun)
|
if (! input_bfd->output_has_begun)
|
||||||
{
|
{
|
||||||
if (! aout_link_input_bfd (&aout_info, input_bfd))
|
if (! aout_link_input_bfd (&aout_info, input_bfd))
|
||||||
return false;
|
goto error_return;
|
||||||
input_bfd->output_has_begun = true;
|
input_bfd->output_has_begun = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3517,7 +3433,7 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (! _bfd_default_link_order (abfd, info, o, p))
|
if (! _bfd_default_link_order (abfd, info, o, p))
|
||||||
return false;
|
goto error_return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3543,17 +3459,38 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
|| p->type == bfd_symbol_reloc_link_order)
|
|| p->type == bfd_symbol_reloc_link_order)
|
||||||
{
|
{
|
||||||
if (! aout_link_reloc_link_order (&aout_info, o, p))
|
if (! aout_link_reloc_link_order (&aout_info, o, p))
|
||||||
return false;
|
goto error_return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aout_info.contents != NULL)
|
||||||
|
{
|
||||||
|
free (aout_info.contents);
|
||||||
|
aout_info.contents = NULL;
|
||||||
|
}
|
||||||
|
if (aout_info.relocs != NULL)
|
||||||
|
{
|
||||||
|
free (aout_info.relocs);
|
||||||
|
aout_info.relocs = NULL;
|
||||||
|
}
|
||||||
|
if (aout_info.symbol_map != NULL)
|
||||||
|
{
|
||||||
|
free (aout_info.symbol_map);
|
||||||
|
aout_info.symbol_map = NULL;
|
||||||
|
}
|
||||||
|
if (aout_info.output_syms != NULL)
|
||||||
|
{
|
||||||
|
free (aout_info.output_syms);
|
||||||
|
aout_info.output_syms = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Finish up any dynamic linking we may be doing. */
|
/* Finish up any dynamic linking we may be doing. */
|
||||||
if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
|
if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
|
||||||
{
|
{
|
||||||
if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
|
if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
|
||||||
return false;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the header information. */
|
/* Update the header information. */
|
||||||
|
@ -3567,8 +3504,19 @@ NAME(aout,final_link) (abfd, info, callback)
|
||||||
|
|
||||||
/* Write out the string table. */
|
/* Write out the string table. */
|
||||||
if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
|
if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
|
||||||
return false;
|
goto error_return;
|
||||||
return emit_stringtab (abfd, &aout_info.strtab);
|
return emit_stringtab (abfd, aout_info.strtab);
|
||||||
|
|
||||||
|
error_return:
|
||||||
|
if (aout_info.contents != NULL)
|
||||||
|
free (aout_info.contents);
|
||||||
|
if (aout_info.relocs != NULL)
|
||||||
|
free (aout_info.relocs);
|
||||||
|
if (aout_info.symbol_map != NULL)
|
||||||
|
free (aout_info.symbol_map);
|
||||||
|
if (aout_info.output_syms != NULL)
|
||||||
|
free (aout_info.output_syms);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link an a.out input BFD into the output file. */
|
/* Link an a.out input BFD into the output file. */
|
||||||
|
@ -3579,7 +3527,6 @@ aout_link_input_bfd (finfo, input_bfd)
|
||||||
bfd *input_bfd;
|
bfd *input_bfd;
|
||||||
{
|
{
|
||||||
bfd_size_type sym_count;
|
bfd_size_type sym_count;
|
||||||
int *symbol_map = NULL;
|
|
||||||
|
|
||||||
BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
|
BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
|
||||||
|
|
||||||
|
@ -3597,29 +3544,23 @@ aout_link_input_bfd (finfo, input_bfd)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sym_count = obj_aout_external_sym_count (input_bfd);
|
sym_count = obj_aout_external_sym_count (input_bfd);
|
||||||
symbol_map = (int *) malloc ((size_t) sym_count * sizeof (int));
|
|
||||||
if (symbol_map == NULL && sym_count != 0)
|
|
||||||
{
|
|
||||||
bfd_set_error (bfd_error_no_memory);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write out the symbols and get a map of the new indices. */
|
/* Write out the symbols and get a map of the new indices. The map
|
||||||
if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
|
is placed into finfo->symbol_map. */
|
||||||
goto error_return;
|
if (! aout_link_write_symbols (finfo, input_bfd))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Relocate and write out the sections. */
|
/* Relocate and write out the sections. These functions use the
|
||||||
|
symbol map created by aout_link_write_symbols. */
|
||||||
if (! aout_link_input_section (finfo, input_bfd,
|
if (! aout_link_input_section (finfo, input_bfd,
|
||||||
obj_textsec (input_bfd),
|
obj_textsec (input_bfd),
|
||||||
&finfo->treloff,
|
&finfo->treloff,
|
||||||
exec_hdr (input_bfd)->a_trsize,
|
exec_hdr (input_bfd)->a_trsize)
|
||||||
symbol_map)
|
|
||||||
|| ! aout_link_input_section (finfo, input_bfd,
|
|| ! aout_link_input_section (finfo, input_bfd,
|
||||||
obj_datasec (input_bfd),
|
obj_datasec (input_bfd),
|
||||||
&finfo->dreloff,
|
&finfo->dreloff,
|
||||||
exec_hdr (input_bfd)->a_drsize,
|
exec_hdr (input_bfd)->a_drsize))
|
||||||
symbol_map))
|
return false;
|
||||||
goto error_return;
|
|
||||||
|
|
||||||
/* If we are not keeping memory, we don't need the symbols any
|
/* 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
|
longer. We still need them if we are keeping memory, because the
|
||||||
|
@ -3627,38 +3568,31 @@ aout_link_input_bfd (finfo, input_bfd)
|
||||||
if (! finfo->info->keep_memory)
|
if (! finfo->info->keep_memory)
|
||||||
{
|
{
|
||||||
if (! aout_link_free_symbols (input_bfd))
|
if (! aout_link_free_symbols (input_bfd))
|
||||||
goto error_return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol_map != NULL)
|
|
||||||
free (symbol_map);
|
|
||||||
return true;
|
return true;
|
||||||
error_return:
|
|
||||||
if (symbol_map != NULL)
|
|
||||||
free (symbol_map);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust and write out the symbols for an a.out file. Set the new
|
/* Adjust and write out the symbols for an a.out file. Set the new
|
||||||
symbol indices into a symbol_map. */
|
symbol indices into a symbol_map. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
aout_link_write_symbols (finfo, input_bfd)
|
||||||
struct aout_final_link_info *finfo;
|
struct aout_final_link_info *finfo;
|
||||||
bfd *input_bfd;
|
bfd *input_bfd;
|
||||||
int *symbol_map;
|
|
||||||
{
|
{
|
||||||
bfd *output_bfd;
|
bfd *output_bfd;
|
||||||
bfd_size_type sym_count;
|
bfd_size_type sym_count;
|
||||||
char *strings;
|
char *strings;
|
||||||
enum bfd_link_strip strip;
|
enum bfd_link_strip strip;
|
||||||
enum bfd_link_discard discard;
|
enum bfd_link_discard discard;
|
||||||
struct external_nlist *output_syms = NULL;
|
|
||||||
struct external_nlist *outsym;
|
struct external_nlist *outsym;
|
||||||
bfd_size_type strtab_index;
|
bfd_size_type strtab_index;
|
||||||
register struct external_nlist *sym;
|
register struct external_nlist *sym;
|
||||||
struct external_nlist *sym_end;
|
struct external_nlist *sym_end;
|
||||||
struct aout_link_hash_entry **sym_hash;
|
struct aout_link_hash_entry **sym_hash;
|
||||||
|
int *symbol_map;
|
||||||
boolean pass;
|
boolean pass;
|
||||||
boolean skip_indirect;
|
boolean skip_indirect;
|
||||||
|
|
||||||
|
@ -3667,14 +3601,7 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
||||||
strings = obj_aout_external_strings (input_bfd);
|
strings = obj_aout_external_strings (input_bfd);
|
||||||
strip = finfo->info->strip;
|
strip = finfo->info->strip;
|
||||||
discard = finfo->info->discard;
|
discard = finfo->info->discard;
|
||||||
output_syms = ((struct external_nlist *)
|
outsym = finfo->output_syms;
|
||||||
malloc ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
|
|
||||||
if (output_syms == NULL)
|
|
||||||
{
|
|
||||||
bfd_set_error (bfd_error_no_memory);
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
outsym = output_syms;
|
|
||||||
|
|
||||||
/* First write out a symbol for this object file, unless we are
|
/* First write out a symbol for this object file, unless we are
|
||||||
discarding such symbols. */
|
discarding such symbols. */
|
||||||
|
@ -3687,10 +3614,10 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
||||||
bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
|
bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
|
||||||
bfd_h_put_8 (output_bfd, 0, outsym->e_other);
|
bfd_h_put_8 (output_bfd, 0, outsym->e_other);
|
||||||
bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
|
bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
|
||||||
strtab_index = add_to_stringtab (output_bfd, &finfo->strtab,
|
strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
|
||||||
input_bfd->filename, false);
|
input_bfd->filename, false);
|
||||||
if (strtab_index == (bfd_size_type) -1)
|
if (strtab_index == (bfd_size_type) -1)
|
||||||
goto error_return;
|
return false;
|
||||||
PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
|
PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
|
||||||
PUT_WORD (output_bfd,
|
PUT_WORD (output_bfd,
|
||||||
(bfd_get_section_vma (output_bfd,
|
(bfd_get_section_vma (output_bfd,
|
||||||
|
@ -3706,6 +3633,7 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
||||||
sym = obj_aout_external_syms (input_bfd);
|
sym = obj_aout_external_syms (input_bfd);
|
||||||
sym_end = sym + sym_count;
|
sym_end = sym + sym_count;
|
||||||
sym_hash = obj_aout_sym_hashes (input_bfd);
|
sym_hash = obj_aout_sym_hashes (input_bfd);
|
||||||
|
symbol_map = finfo->symbol_map;
|
||||||
for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
|
for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -3970,14 +3898,14 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
||||||
free. If there is a hash table entry, use that string.
|
free. If there is a hash table entry, use that string.
|
||||||
Otherwise, copy name into memory. */
|
Otherwise, copy name into memory. */
|
||||||
if (h != (struct aout_link_hash_entry *) NULL)
|
if (h != (struct aout_link_hash_entry *) NULL)
|
||||||
name = (*sym_hash)->root.root.string;
|
name = h->root.root.string;
|
||||||
else
|
else
|
||||||
copy = true;
|
copy = true;
|
||||||
}
|
}
|
||||||
strtab_index = add_to_stringtab (output_bfd, &finfo->strtab,
|
strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
|
||||||
name, copy);
|
name, copy);
|
||||||
if (strtab_index == (bfd_size_type) -1)
|
if (strtab_index == (bfd_size_type) -1)
|
||||||
goto error_return;
|
return false;
|
||||||
PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
|
PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
|
||||||
PUT_WORD (output_bfd, val, outsym->e_value);
|
PUT_WORD (output_bfd, val, outsym->e_value);
|
||||||
*symbol_map = obj_aout_external_sym_count (output_bfd);
|
*symbol_map = obj_aout_external_sym_count (output_bfd);
|
||||||
|
@ -3986,27 +3914,22 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out the output symbols we have just constructed. */
|
/* Write out the output symbols we have just constructed. */
|
||||||
if (outsym > output_syms)
|
if (outsym > finfo->output_syms)
|
||||||
{
|
{
|
||||||
bfd_size_type outsym_count;
|
bfd_size_type outsym_count;
|
||||||
|
|
||||||
if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
|
if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
|
||||||
goto error_return;
|
return false;
|
||||||
outsym_count = outsym - output_syms;
|
outsym_count = outsym - finfo->output_syms;
|
||||||
if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE,
|
if (bfd_write ((PTR) finfo->output_syms,
|
||||||
|
(bfd_size_type) EXTERNAL_NLIST_SIZE,
|
||||||
(bfd_size_type) outsym_count, output_bfd)
|
(bfd_size_type) outsym_count, output_bfd)
|
||||||
!= outsym_count * EXTERNAL_NLIST_SIZE)
|
!= outsym_count * EXTERNAL_NLIST_SIZE)
|
||||||
goto error_return;
|
return false;
|
||||||
finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
|
finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_syms != NULL)
|
|
||||||
free (output_syms);
|
|
||||||
return true;
|
return true;
|
||||||
error_return:
|
|
||||||
if (output_syms != NULL)
|
|
||||||
free (output_syms);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out a symbol that was not associated with an a.out input
|
/* Write out a symbol that was not associated with an a.out input
|
||||||
|
@ -4098,7 +4021,7 @@ aout_link_write_other_symbol (h, data)
|
||||||
bfd_h_put_8 (output_bfd, type, outsym.e_type);
|
bfd_h_put_8 (output_bfd, type, outsym.e_type);
|
||||||
bfd_h_put_8 (output_bfd, 0, outsym.e_other);
|
bfd_h_put_8 (output_bfd, 0, outsym.e_other);
|
||||||
bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
|
bfd_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, finfo->strtab, h->root.root.string,
|
||||||
false);
|
false);
|
||||||
if (indx == (bfd_size_type) -1)
|
if (indx == (bfd_size_type) -1)
|
||||||
{
|
{
|
||||||
|
@ -4127,30 +4050,22 @@ aout_link_write_other_symbol (h, data)
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
|
aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
|
||||||
rel_size, symbol_map)
|
rel_size)
|
||||||
struct aout_final_link_info *finfo;
|
struct aout_final_link_info *finfo;
|
||||||
bfd *input_bfd;
|
bfd *input_bfd;
|
||||||
asection *input_section;
|
asection *input_section;
|
||||||
file_ptr *reloff_ptr;
|
file_ptr *reloff_ptr;
|
||||||
bfd_size_type rel_size;
|
bfd_size_type rel_size;
|
||||||
int *symbol_map;
|
|
||||||
{
|
{
|
||||||
bfd_size_type input_size;
|
bfd_size_type input_size;
|
||||||
bfd_byte *contents = NULL;
|
|
||||||
PTR relocs;
|
PTR relocs;
|
||||||
PTR free_relocs = NULL;
|
|
||||||
|
|
||||||
/* Get the section contents. */
|
/* Get the section contents. */
|
||||||
input_size = bfd_section_size (input_bfd, input_section);
|
input_size = bfd_section_size (input_bfd, input_section);
|
||||||
contents = (bfd_byte *) malloc (input_size);
|
if (! bfd_get_section_contents (input_bfd, input_section,
|
||||||
if (contents == NULL && input_size != 0)
|
(PTR) finfo->contents,
|
||||||
{
|
|
||||||
bfd_set_error (bfd_error_no_memory);
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents,
|
|
||||||
(file_ptr) 0, input_size))
|
(file_ptr) 0, input_size))
|
||||||
goto error_return;
|
return false;
|
||||||
|
|
||||||
/* Read in the relocs if we haven't already done it. */
|
/* Read in the relocs if we haven't already done it. */
|
||||||
if (aout_section_data (input_section) != NULL
|
if (aout_section_data (input_section) != NULL
|
||||||
|
@ -4158,15 +4073,10 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
|
||||||
relocs = aout_section_data (input_section)->relocs;
|
relocs = aout_section_data (input_section)->relocs;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
relocs = free_relocs = (PTR) malloc (rel_size);
|
relocs = finfo->relocs;
|
||||||
if (relocs == NULL && rel_size != 0)
|
|
||||||
{
|
|
||||||
bfd_set_error (bfd_error_no_memory);
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
|
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
|
||||||
|| bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
|
|| bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
|
||||||
goto error_return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Relocate the section contents. */
|
/* Relocate the section contents. */
|
||||||
|
@ -4174,34 +4084,34 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
|
||||||
{
|
{
|
||||||
if (! aout_link_input_section_std (finfo, input_bfd, input_section,
|
if (! aout_link_input_section_std (finfo, input_bfd, input_section,
|
||||||
(struct reloc_std_external *) relocs,
|
(struct reloc_std_external *) relocs,
|
||||||
rel_size, contents, symbol_map))
|
rel_size, finfo->contents))
|
||||||
goto error_return;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
|
if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
|
||||||
(struct reloc_ext_external *) relocs,
|
(struct reloc_ext_external *) relocs,
|
||||||
rel_size, contents, symbol_map))
|
rel_size, finfo->contents))
|
||||||
goto error_return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out the section contents. */
|
/* Write out the section contents. */
|
||||||
if (! bfd_set_section_contents (finfo->output_bfd,
|
if (! bfd_set_section_contents (finfo->output_bfd,
|
||||||
input_section->output_section,
|
input_section->output_section,
|
||||||
(PTR) contents,
|
(PTR) finfo->contents,
|
||||||
input_section->output_offset,
|
input_section->output_offset,
|
||||||
input_size))
|
input_size))
|
||||||
goto error_return;
|
return false;
|
||||||
|
|
||||||
/* If we are producing relocateable output, the relocs were
|
/* If we are producing relocateable output, the relocs were
|
||||||
modified, and we now write them out. */
|
modified, and we now write them out. */
|
||||||
if (finfo->info->relocateable)
|
if (finfo->info->relocateable)
|
||||||
{
|
{
|
||||||
if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
|
if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
|
||||||
goto error_return;
|
return false;
|
||||||
if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
|
if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
|
||||||
!= rel_size)
|
!= rel_size)
|
||||||
goto error_return;
|
return false;
|
||||||
*reloff_ptr += rel_size;
|
*reloff_ptr += rel_size;
|
||||||
|
|
||||||
/* Assert that the relocs have not run into the symbols, and
|
/* Assert that the relocs have not run into the symbols, and
|
||||||
|
@ -4213,17 +4123,7 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
|
||||||
<= obj_datasec (finfo->output_bfd)->rel_filepos)));
|
<= obj_datasec (finfo->output_bfd)->rel_filepos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (free_relocs != NULL)
|
|
||||||
free (free_relocs);
|
|
||||||
if (contents != NULL)
|
|
||||||
free (contents);
|
|
||||||
return true;
|
return true;
|
||||||
error_return:
|
|
||||||
if (free_relocs != NULL)
|
|
||||||
free (free_relocs);
|
|
||||||
if (contents != NULL)
|
|
||||||
free (contents);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the section corresponding to a reloc index. */
|
/* Get the section corresponding to a reloc index. */
|
||||||
|
@ -4253,14 +4153,13 @@ aout_reloc_index_to_section (abfd, indx)
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||||
rel_size, contents, symbol_map)
|
rel_size, contents)
|
||||||
struct aout_final_link_info *finfo;
|
struct aout_final_link_info *finfo;
|
||||||
bfd *input_bfd;
|
bfd *input_bfd;
|
||||||
asection *input_section;
|
asection *input_section;
|
||||||
struct reloc_std_external *relocs;
|
struct reloc_std_external *relocs;
|
||||||
bfd_size_type rel_size;
|
bfd_size_type rel_size;
|
||||||
bfd_byte *contents;
|
bfd_byte *contents;
|
||||||
int *symbol_map;
|
|
||||||
{
|
{
|
||||||
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
|
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
|
||||||
bfd *, asection *,
|
bfd *, asection *,
|
||||||
|
@ -4271,6 +4170,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||||
struct external_nlist *syms;
|
struct external_nlist *syms;
|
||||||
char *strings;
|
char *strings;
|
||||||
struct aout_link_hash_entry **sym_hashes;
|
struct aout_link_hash_entry **sym_hashes;
|
||||||
|
int *symbol_map;
|
||||||
bfd_size_type reloc_count;
|
bfd_size_type reloc_count;
|
||||||
register struct reloc_std_external *rel;
|
register struct reloc_std_external *rel;
|
||||||
struct reloc_std_external *rel_end;
|
struct reloc_std_external *rel_end;
|
||||||
|
@ -4286,6 +4186,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||||
syms = obj_aout_external_syms (input_bfd);
|
syms = obj_aout_external_syms (input_bfd);
|
||||||
strings = obj_aout_external_strings (input_bfd);
|
strings = obj_aout_external_strings (input_bfd);
|
||||||
sym_hashes = obj_aout_sym_hashes (input_bfd);
|
sym_hashes = obj_aout_sym_hashes (input_bfd);
|
||||||
|
symbol_map = finfo->symbol_map;
|
||||||
|
|
||||||
reloc_count = rel_size / RELOC_STD_SIZE;
|
reloc_count = rel_size / RELOC_STD_SIZE;
|
||||||
rel = relocs;
|
rel = relocs;
|
||||||
|
@ -4551,14 +4452,13 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
||||||
rel_size, contents, symbol_map)
|
rel_size, contents)
|
||||||
struct aout_final_link_info *finfo;
|
struct aout_final_link_info *finfo;
|
||||||
bfd *input_bfd;
|
bfd *input_bfd;
|
||||||
asection *input_section;
|
asection *input_section;
|
||||||
struct reloc_ext_external *relocs;
|
struct reloc_ext_external *relocs;
|
||||||
bfd_size_type rel_size;
|
bfd_size_type rel_size;
|
||||||
bfd_byte *contents;
|
bfd_byte *contents;
|
||||||
int *symbol_map;
|
|
||||||
{
|
{
|
||||||
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
|
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
|
||||||
bfd *, asection *,
|
bfd *, asection *,
|
||||||
|
@ -4569,6 +4469,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
||||||
struct external_nlist *syms;
|
struct external_nlist *syms;
|
||||||
char *strings;
|
char *strings;
|
||||||
struct aout_link_hash_entry **sym_hashes;
|
struct aout_link_hash_entry **sym_hashes;
|
||||||
|
int *symbol_map;
|
||||||
bfd_size_type reloc_count;
|
bfd_size_type reloc_count;
|
||||||
register struct reloc_ext_external *rel;
|
register struct reloc_ext_external *rel;
|
||||||
struct reloc_ext_external *rel_end;
|
struct reloc_ext_external *rel_end;
|
||||||
|
@ -4584,6 +4485,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
||||||
syms = obj_aout_external_syms (input_bfd);
|
syms = obj_aout_external_syms (input_bfd);
|
||||||
strings = obj_aout_external_strings (input_bfd);
|
strings = obj_aout_external_strings (input_bfd);
|
||||||
sym_hashes = obj_aout_sym_hashes (input_bfd);
|
sym_hashes = obj_aout_sym_hashes (input_bfd);
|
||||||
|
symbol_map = finfo->symbol_map;
|
||||||
|
|
||||||
reloc_count = rel_size / RELOC_EXT_SIZE;
|
reloc_count = rel_size / RELOC_EXT_SIZE;
|
||||||
rel = relocs;
|
rel = relocs;
|
||||||
|
|
Loading…
Reference in New Issue