* 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)
|
||||
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* Ensure that a zero index yields an empty string. */
|
||||
strings[0] = '\0';
|
||||
|
||||
/* Sanity preservation. */
|
||||
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 */
|
||||
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)
|
||||
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
|
||||
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
|
||||
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
|
||||
PARAMS ((bfd *, struct strtab_hash *, const char *, boolean));
|
||||
static boolean emit_stringtab PARAMS ((bfd *, struct 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)
|
||||
PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
|
||||
static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
|
||||
|
||||
/* 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
|
||||
table, and we don't eliminate duplicate strings. */
|
||||
already present. */
|
||||
|
||||
static INLINE bfd_size_type
|
||||
add_to_stringtab (abfd, tab, str, copy)
|
||||
bfd *abfd;
|
||||
struct strtab_hash *tab;
|
||||
struct bfd_strtab_hash *tab;
|
||||
const char *str;
|
||||
boolean copy;
|
||||
{
|
||||
register struct strtab_hash_entry *entry;
|
||||
boolean hash;
|
||||
|
||||
/* An index of 0 always means the empty string. */
|
||||
if (*str == '\0')
|
||||
return 0;
|
||||
|
||||
if ((abfd->flags & BFD_TRADITIONAL_FORMAT) == 0)
|
||||
{
|
||||
entry = strtab_hash_lookup (tab, str, true, copy);
|
||||
if (entry == NULL)
|
||||
return (bfd_size_type) -1;
|
||||
}
|
||||
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;
|
||||
/* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
|
||||
doesn't understand a hashed string table. */
|
||||
hash = true;
|
||||
if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
|
||||
hash = false;
|
||||
|
||||
n = (char *) bfd_hash_allocate (&tab->table, strlen (str) + 1);
|
||||
if (n == NULL)
|
||||
return (bfd_size_type) -1;
|
||||
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;
|
||||
/* Add BYTES_IN_WORD to the return value to account for the space
|
||||
taken up by the count. */
|
||||
return BYTES_IN_WORD + _bfd_stringtab_add (tab, str, hash, copy);
|
||||
}
|
||||
|
||||
/* 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
|
||||
emit_stringtab (abfd, tab)
|
||||
register bfd *abfd;
|
||||
struct strtab_hash *tab;
|
||||
struct bfd_strtab_hash *tab;
|
||||
{
|
||||
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)
|
||||
return false;
|
||||
|
||||
for (entry = tab->first; entry != NULL; entry = entry->next)
|
||||
{
|
||||
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;
|
||||
return _bfd_stringtab_emit (abfd, tab);
|
||||
}
|
||||
|
||||
boolean
|
||||
|
@ -1938,9 +1804,10 @@ NAME(aout,write_syms) (abfd)
|
|||
{
|
||||
unsigned int count ;
|
||||
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;
|
||||
|
||||
for (count = 0; count < bfd_get_symcount (abfd); count++)
|
||||
|
@ -1949,7 +1816,7 @@ NAME(aout,write_syms) (abfd)
|
|||
bfd_size_type indx;
|
||||
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)
|
||||
goto error_return;
|
||||
PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
|
||||
|
@ -1979,15 +1846,15 @@ NAME(aout,write_syms) (abfd)
|
|||
g->KEEPIT = count;
|
||||
}
|
||||
|
||||
if (! emit_stringtab (abfd, &strtab))
|
||||
if (! emit_stringtab (abfd, strtab))
|
||||
goto error_return;
|
||||
|
||||
stringtab_free (&strtab);
|
||||
_bfd_stringtab_free (strtab);
|
||||
|
||||
return true;
|
||||
|
||||
error_return:
|
||||
stringtab_free (&strtab);
|
||||
_bfd_stringtab_free (strtab);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2905,11 +2772,7 @@ aout_link_check_archive_element (abfd, info, pneeded)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* We keep around the symbols even if we aren't going to use this
|
||||
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 (! info->keep_memory || ! *pneeded)
|
||||
{
|
||||
if (! aout_link_free_symbols (abfd))
|
||||
return false;
|
||||
|
@ -3343,27 +3206,35 @@ struct aout_final_link_info
|
|||
/* File position of symbols. */
|
||||
file_ptr symoff;
|
||||
/* 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
|
||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
|
||||
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
|
||||
PARAMS ((struct aout_link_hash_entry *, PTR));
|
||||
static boolean aout_link_input_section
|
||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
||||
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
|
||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
||||
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
|
||||
PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
|
||||
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
|
||||
PARAMS ((bfd *, int));
|
||||
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;
|
||||
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;
|
||||
file_ptr text_end;
|
||||
register struct bfd_link_order *p;
|
||||
|
@ -3393,20 +3268,21 @@ NAME(aout,final_link) (abfd, info, callback)
|
|||
|
||||
aout_info.info = info;
|
||||
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;
|
||||
exec_hdr (abfd)->a_drsize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_size_type trsize, drsize;
|
||||
size_t sz;
|
||||
|
||||
/* Count up the relocation sizes. */
|
||||
trsize = 0;
|
||||
drsize = 0;
|
||||
for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
|
||||
if (info->relocateable)
|
||||
{
|
||||
if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
|
||||
{
|
||||
|
@ -3422,25 +3298,48 @@ NAME(aout,final_link) (abfd, info, callback)
|
|||
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)
|
||||
trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
|
||||
->link_order_head)
|
||||
* obj_reloc_entry_size (abfd));
|
||||
exec_hdr (abfd)->a_trsize = trsize;
|
||||
if (obj_datasec (abfd) != (asection *) NULL)
|
||||
drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
|
||||
->link_order_head)
|
||||
* 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);
|
||||
|
||||
/* 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
|
||||
filepos for each section. */
|
||||
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
|
||||
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;
|
||||
|
||||
/* We accumulate the string table as we write out the symbols. */
|
||||
if (! stringtab_init (&aout_info.strtab))
|
||||
return false;
|
||||
aout_info.strtab = _bfd_stringtab_init ();
|
||||
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 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 (! aout_link_input_bfd (&aout_info, input_bfd))
|
||||
return false;
|
||||
goto error_return;
|
||||
input_bfd->output_has_begun = true;
|
||||
}
|
||||
}
|
||||
|
@ -3517,7 +3433,7 @@ NAME(aout,final_link) (abfd, info, callback)
|
|||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
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. */
|
||||
if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
|
||||
{
|
||||
if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
|
||||
return false;
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* Update the header information. */
|
||||
|
@ -3567,8 +3504,19 @@ NAME(aout,final_link) (abfd, info, callback)
|
|||
|
||||
/* Write out the string table. */
|
||||
if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
|
||||
return false;
|
||||
return emit_stringtab (abfd, &aout_info.strtab);
|
||||
goto error_return;
|
||||
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. */
|
||||
|
@ -3579,7 +3527,6 @@ aout_link_input_bfd (finfo, input_bfd)
|
|||
bfd *input_bfd;
|
||||
{
|
||||
bfd_size_type sym_count;
|
||||
int *symbol_map = NULL;
|
||||
|
||||
BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
|
||||
|
||||
|
@ -3597,29 +3544,23 @@ aout_link_input_bfd (finfo, input_bfd)
|
|||
return false;
|
||||
|
||||
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. */
|
||||
if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
|
||||
goto error_return;
|
||||
/* 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))
|
||||
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,
|
||||
obj_textsec (input_bfd),
|
||||
&finfo->treloff,
|
||||
exec_hdr (input_bfd)->a_trsize,
|
||||
symbol_map)
|
||||
exec_hdr (input_bfd)->a_trsize)
|
||||
|| ! aout_link_input_section (finfo, input_bfd,
|
||||
obj_datasec (input_bfd),
|
||||
&finfo->dreloff,
|
||||
exec_hdr (input_bfd)->a_drsize,
|
||||
symbol_map))
|
||||
goto error_return;
|
||||
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
|
||||
|
@ -3627,38 +3568,31 @@ aout_link_input_bfd (finfo, input_bfd)
|
|||
if (! finfo->info->keep_memory)
|
||||
{
|
||||
if (! aout_link_free_symbols (input_bfd))
|
||||
goto error_return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (symbol_map != NULL)
|
||||
free (symbol_map);
|
||||
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
|
||||
symbol indices into a symbol_map. */
|
||||
|
||||
static boolean
|
||||
aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
||||
aout_link_write_symbols (finfo, input_bfd)
|
||||
struct aout_final_link_info *finfo;
|
||||
bfd *input_bfd;
|
||||
int *symbol_map;
|
||||
{
|
||||
bfd *output_bfd;
|
||||
bfd_size_type sym_count;
|
||||
char *strings;
|
||||
enum bfd_link_strip strip;
|
||||
enum bfd_link_discard discard;
|
||||
struct external_nlist *output_syms = NULL;
|
||||
struct external_nlist *outsym;
|
||||
bfd_size_type strtab_index;
|
||||
register struct external_nlist *sym;
|
||||
struct external_nlist *sym_end;
|
||||
struct aout_link_hash_entry **sym_hash;
|
||||
int *symbol_map;
|
||||
boolean pass;
|
||||
boolean skip_indirect;
|
||||
|
||||
|
@ -3667,14 +3601,7 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
|
|||
strings = obj_aout_external_strings (input_bfd);
|
||||
strip = finfo->info->strip;
|
||||
discard = finfo->info->discard;
|
||||
output_syms = ((struct external_nlist *)
|
||||
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;
|
||||
outsym = finfo->output_syms;
|
||||
|
||||
/* First write out a symbol for this object file, unless we are
|
||||
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, 0, outsym->e_other);
|
||||
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);
|
||||
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,
|
||||
(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_end = sym + sym_count;
|
||||
sym_hash = obj_aout_sym_hashes (input_bfd);
|
||||
symbol_map = finfo->symbol_map;
|
||||
for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
|
||||
{
|
||||
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.
|
||||
Otherwise, copy name into memory. */
|
||||
if (h != (struct aout_link_hash_entry *) NULL)
|
||||
name = (*sym_hash)->root.root.string;
|
||||
name = h->root.root.string;
|
||||
else
|
||||
copy = true;
|
||||
}
|
||||
strtab_index = add_to_stringtab (output_bfd, &finfo->strtab,
|
||||
strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
|
||||
name, copy);
|
||||
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, val, outsym->e_value);
|
||||
*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. */
|
||||
if (outsym > output_syms)
|
||||
if (outsym > finfo->output_syms)
|
||||
{
|
||||
bfd_size_type outsym_count;
|
||||
|
||||
if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
|
||||
goto error_return;
|
||||
outsym_count = outsym - output_syms;
|
||||
if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE,
|
||||
return false;
|
||||
outsym_count = outsym - finfo->output_syms;
|
||||
if (bfd_write ((PTR) finfo->output_syms,
|
||||
(bfd_size_type) EXTERNAL_NLIST_SIZE,
|
||||
(bfd_size_type) outsym_count, output_bfd)
|
||||
!= outsym_count * EXTERNAL_NLIST_SIZE)
|
||||
goto error_return;
|
||||
return false;
|
||||
finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
|
||||
}
|
||||
|
||||
if (output_syms != NULL)
|
||||
free (output_syms);
|
||||
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
|
||||
|
@ -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, 0, outsym.e_other);
|
||||
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);
|
||||
if (indx == (bfd_size_type) -1)
|
||||
{
|
||||
|
@ -4127,30 +4050,22 @@ aout_link_write_other_symbol (h, data)
|
|||
|
||||
static boolean
|
||||
aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
|
||||
rel_size, symbol_map)
|
||||
rel_size)
|
||||
struct aout_final_link_info *finfo;
|
||||
bfd *input_bfd;
|
||||
asection *input_section;
|
||||
file_ptr *reloff_ptr;
|
||||
bfd_size_type rel_size;
|
||||
int *symbol_map;
|
||||
{
|
||||
bfd_size_type input_size;
|
||||
bfd_byte *contents = NULL;
|
||||
PTR relocs;
|
||||
PTR free_relocs = NULL;
|
||||
|
||||
/* Get the section contents. */
|
||||
input_size = bfd_section_size (input_bfd, input_section);
|
||||
contents = (bfd_byte *) malloc (input_size);
|
||||
if (contents == NULL && input_size != 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
goto error_return;
|
||||
}
|
||||
if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents,
|
||||
if (! bfd_get_section_contents (input_bfd, input_section,
|
||||
(PTR) finfo->contents,
|
||||
(file_ptr) 0, input_size))
|
||||
goto error_return;
|
||||
return false;
|
||||
|
||||
/* Read in the relocs if we haven't already done it. */
|
||||
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;
|
||||
else
|
||||
{
|
||||
relocs = free_relocs = (PTR) malloc (rel_size);
|
||||
if (relocs == NULL && rel_size != 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
goto error_return;
|
||||
}
|
||||
relocs = finfo->relocs;
|
||||
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
|
||||
|| bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
|
||||
goto error_return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
(struct reloc_std_external *) relocs,
|
||||
rel_size, contents, symbol_map))
|
||||
goto error_return;
|
||||
rel_size, finfo->contents))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
|
||||
(struct reloc_ext_external *) relocs,
|
||||
rel_size, contents, symbol_map))
|
||||
goto error_return;
|
||||
rel_size, finfo->contents))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Write out the section contents. */
|
||||
if (! bfd_set_section_contents (finfo->output_bfd,
|
||||
input_section->output_section,
|
||||
(PTR) contents,
|
||||
(PTR) finfo->contents,
|
||||
input_section->output_offset,
|
||||
input_size))
|
||||
goto error_return;
|
||||
return false;
|
||||
|
||||
/* If we are producing relocateable output, the relocs were
|
||||
modified, and we now write them out. */
|
||||
if (finfo->info->relocateable)
|
||||
{
|
||||
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)
|
||||
!= rel_size)
|
||||
goto error_return;
|
||||
return false;
|
||||
*reloff_ptr += rel_size;
|
||||
|
||||
/* 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)));
|
||||
}
|
||||
|
||||
if (free_relocs != NULL)
|
||||
free (free_relocs);
|
||||
if (contents != NULL)
|
||||
free (contents);
|
||||
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. */
|
||||
|
@ -4253,14 +4153,13 @@ aout_reloc_index_to_section (abfd, indx)
|
|||
|
||||
static boolean
|
||||
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;
|
||||
bfd *input_bfd;
|
||||
asection *input_section;
|
||||
struct reloc_std_external *relocs;
|
||||
bfd_size_type rel_size;
|
||||
bfd_byte *contents;
|
||||
int *symbol_map;
|
||||
{
|
||||
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
|
||||
bfd *, asection *,
|
||||
|
@ -4271,6 +4170,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
|||
struct external_nlist *syms;
|
||||
char *strings;
|
||||
struct aout_link_hash_entry **sym_hashes;
|
||||
int *symbol_map;
|
||||
bfd_size_type reloc_count;
|
||||
register struct reloc_std_external *rel;
|
||||
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);
|
||||
strings = obj_aout_external_strings (input_bfd);
|
||||
sym_hashes = obj_aout_sym_hashes (input_bfd);
|
||||
symbol_map = finfo->symbol_map;
|
||||
|
||||
reloc_count = rel_size / RELOC_STD_SIZE;
|
||||
rel = relocs;
|
||||
|
@ -4551,14 +4452,13 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
|||
|
||||
static boolean
|
||||
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;
|
||||
bfd *input_bfd;
|
||||
asection *input_section;
|
||||
struct reloc_ext_external *relocs;
|
||||
bfd_size_type rel_size;
|
||||
bfd_byte *contents;
|
||||
int *symbol_map;
|
||||
{
|
||||
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
|
||||
bfd *, asection *,
|
||||
|
@ -4569,6 +4469,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
|||
struct external_nlist *syms;
|
||||
char *strings;
|
||||
struct aout_link_hash_entry **sym_hashes;
|
||||
int *symbol_map;
|
||||
bfd_size_type reloc_count;
|
||||
register struct reloc_ext_external *rel;
|
||||
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);
|
||||
strings = obj_aout_external_strings (input_bfd);
|
||||
sym_hashes = obj_aout_sym_hashes (input_bfd);
|
||||
symbol_map = finfo->symbol_map;
|
||||
|
||||
reloc_count = rel_size / RELOC_EXT_SIZE;
|
||||
rel = relocs;
|
||||
|
|
Loading…
Reference in New Issue