diff options
Diffstat (limited to 'bfd/cofflink.c')
-rw-r--r-- | bfd/cofflink.c | 559 |
1 files changed, 242 insertions, 317 deletions
diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 59b32ed..c1eee1b 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -3,21 +3,21 @@ Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -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 -(at your option) any later version. + 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 + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This file contains the COFF backend linker code. */ @@ -28,22 +28,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "coff/internal.h" #include "libcoff.h" -static bfd_boolean coff_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean coff_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *)); -static bfd_boolean coff_link_check_ar_symbols - PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *)); -static bfd_boolean coff_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static char *dores_com - PARAMS ((char *, bfd *, int)); -static char *get_name - PARAMS ((char *, char **)); -static int process_embedded_commands - PARAMS ((bfd *, struct bfd_link_info *, bfd *)); -static void mark_relocs - PARAMS ((struct coff_final_link_info *, bfd *)); +static bfd_boolean coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info); +static bfd_boolean coff_link_check_archive_element (bfd *abfd, struct bfd_link_info *info, bfd_boolean *pneeded); +static bfd_boolean coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info); /* Return TRUE if SYM is a weak, external symbol. */ #define IS_WEAK_EXTERNAL(abfd, sym) \ @@ -67,10 +54,9 @@ static void mark_relocs /* Create an entry in a COFF linker hash table. */ struct bfd_hash_entry * -_bfd_coff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +_bfd_coff_link_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) { struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry; @@ -103,12 +89,11 @@ _bfd_coff_link_hash_newfunc (entry, table, string) /* Initialize a COFF linker hash table. */ bfd_boolean -_bfd_coff_link_hash_table_init (table, abfd, newfunc) - struct coff_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); +_bfd_coff_link_hash_table_init (struct coff_link_hash_table *table, + bfd *abfd, + struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, + struct bfd_hash_table *, + const char *)) { table->stab_info = NULL; return _bfd_link_hash_table_init (&table->root, abfd, newfunc); @@ -117,15 +102,15 @@ _bfd_coff_link_hash_table_init (table, abfd, newfunc) /* Create a COFF linker hash table. */ struct bfd_link_hash_table * -_bfd_coff_link_hash_table_create (abfd) - bfd *abfd; +_bfd_coff_link_hash_table_create (bfd *abfd) { struct coff_link_hash_table *ret; bfd_size_type amt = sizeof (struct coff_link_hash_table); - ret = (struct coff_link_hash_table *) bfd_malloc (amt); + ret = bfd_malloc (amt); if (ret == NULL) return NULL; + if (! _bfd_coff_link_hash_table_init (ret, abfd, _bfd_coff_link_hash_newfunc)) { @@ -138,10 +123,9 @@ _bfd_coff_link_hash_table_create (abfd) /* Create an entry in a COFF debug merge hash table. */ struct bfd_hash_entry * -_bfd_coff_debug_merge_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +_bfd_coff_debug_merge_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) { struct coff_debug_merge_hash_entry *ret = (struct coff_debug_merge_hash_entry *) entry; @@ -171,17 +155,15 @@ _bfd_coff_debug_merge_hash_newfunc (entry, table, string) appropriate. */ bfd_boolean -_bfd_coff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +_bfd_coff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) { switch (bfd_get_format (abfd)) { case bfd_object: return coff_link_add_object_symbols (abfd, info); case bfd_archive: - return (_bfd_generic_link_add_archive_symbols - (abfd, info, coff_link_check_archive_element)); + return _bfd_generic_link_add_archive_symbols + (abfd, info, coff_link_check_archive_element); default: bfd_set_error (bfd_error_wrong_format); return FALSE; @@ -191,52 +173,17 @@ _bfd_coff_link_add_symbols (abfd, info) /* Add symbols from a COFF object file. */ static bfd_boolean -coff_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +coff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) { if (! _bfd_coff_get_external_symbols (abfd)) return FALSE; if (! coff_link_add_symbols (abfd, info)) return FALSE; - if (! info->keep_memory) - { - if (! _bfd_coff_free_symbols (abfd)) - return FALSE; - } - return TRUE; -} - -/* Check a single archive element to see if we need to include it in - the link. *PNEEDED is set according to whether this element is - needed in the link or not. This is called via - _bfd_generic_link_add_archive_symbols. */ - -static bfd_boolean -coff_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - bfd_boolean *pneeded; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return FALSE; - - if (! coff_link_check_ar_symbols (abfd, info, pneeded)) + if (! info->keep_memory + && ! _bfd_coff_free_symbols (abfd)) return FALSE; - if (*pneeded) - { - if (! coff_link_add_symbols (abfd, info)) - return FALSE; - } - - if (! info->keep_memory || ! *pneeded) - { - if (! _bfd_coff_free_symbols (abfd)) - return FALSE; - } - return TRUE; } @@ -244,10 +191,9 @@ coff_link_check_archive_element (abfd, info, pneeded) included in the link. */ static bfd_boolean -coff_link_check_ar_symbols (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - bfd_boolean *pneeded; +coff_link_check_ar_symbols (bfd *abfd, + struct bfd_link_info *info, + bfd_boolean *pneeded) { bfd_size_type symesz; bfd_byte *esym; @@ -263,7 +209,7 @@ coff_link_check_ar_symbols (abfd, info, pneeded) struct internal_syment sym; enum coff_symbol_classification classification; - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); + bfd_coff_swap_sym_in (abfd, esym, &sym); classification = bfd_coff_classify_symbol (abfd, &sym); if (classification == COFF_SYMBOL_GLOBAL @@ -275,22 +221,17 @@ coff_link_check_ar_symbols (abfd, info, pneeded) /* This symbol is externally visible, and is defined by this object file. */ - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); if (name == NULL) return FALSE; h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); - /* auto import */ - if (!h && info->pei386_auto_import) - { - if (!strncmp (name,"__imp_", 6)) - { - h = - bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, - TRUE); - } - } + /* Auto import. */ + if (!h + && info->pei386_auto_import + && !strncmp (name,"__imp_", 6)) + h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE); + /* We are only interested in symbols that are currently undefined. If a symbol is currently known to be common, COFF linkers do not bring in an object file which defines @@ -312,12 +253,38 @@ coff_link_check_ar_symbols (abfd, info, pneeded) return TRUE; } +/* Check a single archive element to see if we need to include it in + the link. *PNEEDED is set according to whether this element is + needed in the link or not. This is called via + _bfd_generic_link_add_archive_symbols. */ + +static bfd_boolean +coff_link_check_archive_element (bfd *abfd, + struct bfd_link_info *info, + bfd_boolean *pneeded) +{ + if (! _bfd_coff_get_external_symbols (abfd)) + return FALSE; + + if (! coff_link_check_ar_symbols (abfd, info, pneeded)) + return FALSE; + + if (*pneeded + && ! coff_link_add_symbols (abfd, info)) + return FALSE; + + if ((! info->keep_memory || ! *pneeded) + && ! _bfd_coff_free_symbols (abfd)) + return FALSE; + + return TRUE; +} + /* Add all the symbols from an object file to the hash table. */ static bfd_boolean -coff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +coff_link_add_symbols (bfd *abfd, + struct bfd_link_info *info) { unsigned int n_tmask = coff_data (abfd)->local_n_tmask; unsigned int n_btshft = coff_data (abfd)->local_n_btshft; @@ -346,7 +313,7 @@ coff_link_add_symbols (abfd, info) /* We keep a list of the linker hash table entries that correspond to particular symbols. */ amt = symcount * sizeof (struct coff_link_hash_entry *); - sym_hash = (struct coff_link_hash_entry **) bfd_zalloc (abfd, amt); + sym_hash = bfd_zalloc (abfd, amt); if (sym_hash == NULL && symcount != 0) goto error_return; obj_coff_sym_hashes (abfd) = sym_hash; @@ -361,7 +328,7 @@ coff_link_add_symbols (abfd, info) enum coff_symbol_classification classification; bfd_boolean copy; - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); + bfd_coff_swap_sym_in (abfd, esym, &sym); classification = bfd_coff_classify_symbol (abfd, &sym); if (classification != COFF_SYMBOL_LOCAL) @@ -564,9 +531,9 @@ coff_link_add_symbols (abfd, info) for (i = 0, eaux = esym + symesz, iaux = alloc; i < sym.n_numaux; i++, eaux += symesz, iaux++) - bfd_coff_swap_aux_in (abfd, (PTR) eaux, sym.n_type, + bfd_coff_swap_aux_in (abfd, eaux, sym.n_type, sym.n_sclass, (int) i, - sym.n_numaux, (PTR) iaux); + sym.n_numaux, iaux); (*sym_hash)->aux = alloc; } } @@ -582,7 +549,6 @@ coff_link_add_symbols (abfd, info) FIXME: This is not at all the right place to do this. For example, it won't help objdump. This needs to be done when we swap in the section header. */ - BFD_ASSERT ((*sym_hash)->numaux == 1); if (section->_raw_size == 0) section->_raw_size = (*sym_hash)->aux[0].x_scn.x_scnlen; @@ -620,7 +586,7 @@ coff_link_add_symbols (abfd, info) if (secdata == NULL) { amt = sizeof (struct coff_section_tdata); - stab->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); + stab->used_by_bfd = bfd_zalloc (abfd, amt); if (stab->used_by_bfd == NULL) goto error_return; secdata = coff_section_data (abfd, stab); @@ -648,9 +614,8 @@ coff_link_add_symbols (abfd, info) /* Do the final link step. */ bfd_boolean -_bfd_coff_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +_bfd_coff_final_link (bfd *abfd, + struct bfd_link_info *info) { bfd_size_type symesz; struct coff_final_link_info finfo; @@ -792,7 +757,7 @@ _bfd_coff_final_link (abfd, info) the target_index fields are 1 based. */ amt = abfd->section_count + 1; amt *= sizeof (struct coff_link_section_info); - finfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt); + finfo.section_info = bfd_malloc (amt); if (finfo.section_info == NULL) goto error_return; for (i = 0; i <= abfd->section_count; i++) @@ -835,12 +800,10 @@ _bfd_coff_final_link (abfd, info) BFD_ASSERT (info->relocatable); amt = o->reloc_count; amt *= sizeof (struct internal_reloc); - finfo.section_info[o->target_index].relocs = - (struct internal_reloc *) bfd_malloc (amt); + finfo.section_info[o->target_index].relocs = bfd_malloc (amt); amt = o->reloc_count; amt *= sizeof (struct coff_link_hash_entry *); - finfo.section_info[o->target_index].rel_hashes = - (struct coff_link_hash_entry **) bfd_malloc (amt); + finfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt); if (finfo.section_info[o->target_index].relocs == NULL || finfo.section_info[o->target_index].rel_hashes == NULL) goto error_return; @@ -873,21 +836,21 @@ _bfd_coff_final_link (abfd, info) /* Allocate some buffers used while linking. */ amt = max_sym_count * sizeof (struct internal_syment); - finfo.internal_syms = (struct internal_syment *) bfd_malloc (amt); + finfo.internal_syms = bfd_malloc (amt); amt = max_sym_count * sizeof (asection *); - finfo.sec_ptrs = (asection **) bfd_malloc (amt); + finfo.sec_ptrs = bfd_malloc (amt); amt = max_sym_count * sizeof (long); - finfo.sym_indices = (long *) bfd_malloc (amt); - finfo.outsyms = (bfd_byte *) bfd_malloc ((max_sym_count + 1) * symesz); + finfo.sym_indices = bfd_malloc (amt); + finfo.outsyms = bfd_malloc ((max_sym_count + 1) * symesz); amt = max_lineno_count * bfd_coff_linesz (abfd); - finfo.linenos = (bfd_byte *) bfd_malloc (amt); - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); + finfo.linenos = bfd_malloc (amt); + finfo.contents = bfd_malloc (max_contents_size); amt = max_reloc_count * relsz; - finfo.external_relocs = (bfd_byte *) bfd_malloc (amt); + finfo.external_relocs = bfd_malloc (amt); if (! info->relocatable) { amt = max_reloc_count * sizeof (struct internal_reloc); - finfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt); + finfo.internal_relocs = bfd_malloc (amt); } if ((finfo.internal_syms == NULL && max_sym_count > 0) || (finfo.sec_ptrs == NULL && max_sym_count > 0) @@ -996,8 +959,8 @@ _bfd_coff_final_link (abfd, info) file_ptr pos; finfo.last_file.n_value = obj_raw_syment_count (abfd); - bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, - (PTR) finfo.outsyms); + bfd_coff_swap_sym_out (abfd, &finfo.last_file, + finfo.outsyms); pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz; if (bfd_seek (abfd, pos, SEEK_SET) != 0 @@ -1012,8 +975,7 @@ _bfd_coff_final_link (abfd, info) { finfo.failed = FALSE; coff_link_hash_traverse (coff_hash_table (info), - _bfd_coff_write_task_globals, - (PTR) &finfo); + _bfd_coff_write_task_globals, &finfo); if (finfo.failed) goto error_return; } @@ -1021,8 +983,7 @@ _bfd_coff_final_link (abfd, info) /* Write out the global symbols. */ finfo.failed = FALSE; coff_link_hash_traverse (coff_hash_table (info), - _bfd_coff_write_global_sym, - (PTR) &finfo); + _bfd_coff_write_global_sym, &finfo); if (finfo.failed) goto error_return; @@ -1039,7 +1000,7 @@ _bfd_coff_final_link (abfd, info) the symbol indices to use for relocs against them, and we can finally write out the relocs. */ amt = max_output_reloc_count * relsz; - external_relocs = (bfd_byte *) bfd_malloc (amt); + external_relocs = bfd_malloc (amt); if (external_relocs == NULL) goto error_return; @@ -1064,11 +1025,11 @@ _bfd_coff_final_link (abfd, info) BFD_ASSERT ((*rel_hash)->indx >= 0); irel->r_symndx = (*rel_hash)->indx; } - bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); + bfd_coff_swap_reloc_out (abfd, irel, erel); } if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || (bfd_bwrite ((PTR) external_relocs, + || (bfd_bwrite (external_relocs, (bfd_size_type) relsz * o->reloc_count, abfd) != (bfd_size_type) relsz * o->reloc_count)) goto error_return; @@ -1175,17 +1136,15 @@ _bfd_coff_final_link (abfd, info) return FALSE; } -/* parse out a -heap <reserved>,<commit> line */ +/* Parse out a -heap <reserved>,<commit> line. */ static char * -dores_com (ptr, output_bfd, heap) - char *ptr; - bfd *output_bfd; - int heap; +dores_com (char *ptr, bfd *output_bfd, int heap) { if (coff_data(output_bfd)->pe) { int val = strtoul (ptr, &ptr, 0); + if (heap) pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve = val; else @@ -1203,9 +1162,8 @@ dores_com (ptr, output_bfd, heap) return ptr; } -static char *get_name(ptr, dst) -char *ptr; -char **dst; +static char * +get_name (char *ptr, char **dst) { while (*ptr == ' ') ptr++; @@ -1216,85 +1174,89 @@ char **dst; return ptr+1; } -/* Process any magic embedded commands in a section called .drectve */ +/* Process any magic embedded commands in a section called .drectve. */ static int -process_embedded_commands (output_bfd, info, abfd) - bfd *output_bfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - bfd *abfd; +process_embedded_commands (bfd *output_bfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + bfd *abfd) { asection *sec = bfd_get_section_by_name (abfd, ".drectve"); char *s; char *e; char *copy; + if (!sec) return 1; copy = bfd_malloc (sec->_raw_size); if (!copy) return 0; - if (! bfd_get_section_contents(abfd, sec, copy, (bfd_vma) 0, sec->_raw_size)) + + if (! bfd_get_section_contents (abfd, sec, copy, (bfd_vma) 0, sec->_raw_size)) { free (copy); return 0; } e = copy + sec->_raw_size; + for (s = copy; s < e ; ) { - if (s[0]!= '-') { - s++; - continue; - } + if (s[0]!= '-') + { + s++; + continue; + } if (strncmp (s,"-attr", 5) == 0) { char *name; char *attribs; asection *asec; - int loop = 1; int had_write = 0; int had_read = 0; int had_exec= 0; int had_shared= 0; + s += 5; - s = get_name(s, &name); - s = get_name(s, &attribs); - while (loop) { - switch (*attribs++) - { - case 'W': - had_write = 1; - break; - case 'R': - had_read = 1; - break; - case 'S': - had_shared = 1; - break; - case 'X': - had_exec = 1; - break; - default: - loop = 0; - } - } + s = get_name (s, &name); + s = get_name (s, &attribs); + + while (loop) + { + switch (*attribs++) + { + case 'W': + had_write = 1; + break; + case 'R': + had_read = 1; + break; + case 'S': + had_shared = 1; + break; + case 'X': + had_exec = 1; + break; + default: + loop = 0; + } + } asec = bfd_get_section_by_name (abfd, name); - if (asec) { - if (had_exec) - asec->flags |= SEC_CODE; - if (!had_write) - asec->flags |= SEC_READONLY; - } + if (asec) + { + if (had_exec) + asec->flags |= SEC_CODE; + if (!had_write) + asec->flags |= SEC_READONLY; + } } else if (strncmp (s,"-heap", 5) == 0) - { - s = dores_com (s+5, output_bfd, 1); - } + s = dores_com (s+5, output_bfd, 1); + else if (strncmp (s,"-stack", 6) == 0) - { - s = dores_com (s+6, output_bfd, 0); - } + s = dores_com (s+6, output_bfd, 0); + else s++; } @@ -1305,13 +1267,10 @@ process_embedded_commands (output_bfd, info, abfd) /* Place a marker against all symbols which are used by relocations. This marker can be picked up by the 'do we skip this symbol ?' loop in _bfd_coff_link_input_bfd() and used to prevent skipping - that symbol. - */ + that symbol. */ static void -mark_relocs (finfo, input_bfd) - struct coff_final_link_info * finfo; - bfd * input_bfd; +mark_relocs (struct coff_final_link_info *finfo, bfd *input_bfd) { asection * a; @@ -1349,12 +1308,9 @@ mark_relocs (finfo, input_bfd) /* Place a mark in the sym_indices array (whose entries have been initialised to 0) for all of the symbols that are used in the relocation table. This will then be picked up in the - skip/don't pass */ - + skip/don't-skip pass. */ for (; irel < irelend; irel++) - { - finfo->sym_indices[ irel->r_symndx ] = -1; - } + finfo->sym_indices[ irel->r_symndx ] = -1; } } @@ -1362,9 +1318,7 @@ mark_relocs (finfo, input_bfd) handles all the sections and relocations of the input file at once. */ bfd_boolean -_bfd_coff_link_input_bfd (finfo, input_bfd) - struct coff_final_link_info *finfo; - bfd *input_bfd; +_bfd_coff_link_input_bfd (struct coff_final_link_info *finfo, bfd *input_bfd) { unsigned int n_tmask = coff_data (input_bfd)->local_n_tmask; unsigned int n_btshft = coff_data (input_bfd)->local_n_btshft; @@ -1372,8 +1326,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) unsigned int n_btmask = coff_data (input_bfd)->local_n_btmask; #endif bfd_boolean (*adjust_symndx) - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - struct internal_reloc *, bfd_boolean *)); + (bfd *, struct bfd_link_info *, bfd *, asection *, + struct internal_reloc *, bfd_boolean *); bfd *output_bfd; const char *strings; bfd_size_type syment_base; @@ -1419,20 +1373,18 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) output_index = syment_base; outsym = finfo->outsyms; - if (coff_data (output_bfd)->pe) - { - if (! process_embedded_commands (output_bfd, finfo->info, input_bfd)) - return FALSE; - } + if (coff_data (output_bfd)->pe + && ! process_embedded_commands (output_bfd, finfo->info, input_bfd)) + return FALSE; - /* If we are going to perform relocations and also strip/discard some symbols - then we must make sure that we do not strip/discard those symbols that are - going to be involved in the relocations */ + /* If we are going to perform relocations and also strip/discard some + symbols then we must make sure that we do not strip/discard those + symbols that are going to be involved in the relocations. */ if (( finfo->info->strip != strip_none || finfo->info->discard != discard_none) && finfo->info->relocatable) { - /* mark the symbol array as 'not-used' */ + /* Mark the symbol array as 'not-used'. */ memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp); mark_relocs (finfo, input_bfd); @@ -1447,7 +1399,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) bfd_boolean dont_skip_symbol; int add; - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); + bfd_coff_swap_sym_in (input_bfd, esym, isymp); /* Make a copy of *isymp so that the relocate_section function always sees the original values. This is more reliable than @@ -1529,13 +1481,12 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) /* Skip section symbols for sections which are not going to be emitted. */ if (!skip + && dont_skip_symbol == 0 && isym.n_sclass == C_STAT && isym.n_type == T_NULL - && isym.n_numaux > 0) - { - if ((*secpp)->output_section == bfd_abs_section_ptr) - skip = TRUE; - } + && isym.n_numaux > 0 + && (*secpp)->output_section == bfd_abs_section_ptr) + skip = TRUE; #endif /* If we stripping debugging symbols, and this is a debugging @@ -1620,16 +1571,16 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) out to be a duplicate, we pass this address to bfd_release. */ amt = sizeof (struct coff_debug_merge_type); - mt = (struct coff_debug_merge_type *) bfd_alloc (input_bfd, amt); + mt = bfd_alloc (input_bfd, amt); if (mt == NULL) return FALSE; mt->class = isym.n_sclass; /* Pick up the aux entry, which points to the end of the tag entries. */ - bfd_coff_swap_aux_in (input_bfd, (PTR) (esym + isymesz), + bfd_coff_swap_aux_in (input_bfd, (esym + isymesz), isym.n_type, isym.n_sclass, 0, isym.n_numaux, - (PTR) &aux); + &aux); /* Gather the elements. */ epp = &mt->elements; @@ -1644,11 +1595,10 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) char elebuf[SYMNMLEN + 1]; char *name_copy; - bfd_coff_swap_sym_in (input_bfd, (PTR) esl, (PTR) islp); + bfd_coff_swap_sym_in (input_bfd, esl, islp); amt = sizeof (struct coff_debug_merge_element); - *epp = ((struct coff_debug_merge_element *) - bfd_alloc (input_bfd, amt)); + *epp = bfd_alloc (input_bfd, amt); if (*epp == NULL) return FALSE; @@ -1658,7 +1608,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) return FALSE; amt = strlen (elename) + 1; - name_copy = (char *) bfd_alloc (input_bfd, amt); + name_copy = bfd_alloc (input_bfd, amt); if (name_copy == NULL) return FALSE; strcpy (name_copy, elename); @@ -1673,16 +1623,15 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) union internal_auxent eleaux; long indx; - bfd_coff_swap_aux_in (input_bfd, (PTR) (esl + isymesz), + bfd_coff_swap_aux_in (input_bfd, (esl + isymesz), islp->n_type, islp->n_sclass, 0, - islp->n_numaux, (PTR) &eleaux); + islp->n_numaux, &eleaux); indx = eleaux.x_sym.x_tagndx.l; /* FIXME: If this tagndx entry refers to a symbol defined later in this file, we just ignore it. Handling this correctly would be tedious, and may not be required. */ - if (indx > 0 && (indx < ((esym - @@ -1705,7 +1654,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) type. We always output the type if it has no elements, for simplicity. */ if (mt->elements == NULL) - bfd_release (input_bfd, (PTR) mt); + bfd_release (input_bfd, mt); else { struct coff_debug_merge_type *mtl; @@ -1741,7 +1690,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) else { /* This is a redefinition which can be merged. */ - bfd_release (input_bfd, (PTR) mt); + bfd_release (input_bfd, mt); *indexp = mtl->indx; add = (eslend - esym) / isymesz; skip = TRUE; @@ -1765,8 +1714,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) bfd_coff_symname_in_debug. That is only true for XCOFF, and XCOFF requires different linking code anyhow. */ - name = _bfd_coff_internal_syment_name (input_bfd, &isym, - (char *) NULL); + name = _bfd_coff_internal_syment_name (input_bfd, &isym, NULL); if (name == NULL) return FALSE; indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy); @@ -1839,7 +1787,6 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) it). We try to get this right, below, just before we write the symbols out, but in the general case we may have to write the symbol out twice. */ - if (finfo->last_file_index != -1 && finfo->last_file.n_value != (bfd_vma) output_index) { @@ -1850,11 +1797,11 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) { /* The last C_FILE symbol is in this input file. */ bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - - syment_base) - * osymesz))); + &finfo->last_file, + (finfo->outsyms + + ((finfo->last_file_index + - syment_base) + * osymesz))); } else { @@ -1864,8 +1811,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) symbol. We need to write it out again. We borrow *outsym temporarily. */ bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) outsym); + &finfo->last_file, outsym); pos = obj_sym_filepos (output_bfd); pos += finfo->last_file_index * osymesz; if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 @@ -1885,8 +1831,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) isym.n_sclass = C_STAT; /* Output the symbol. */ - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); + bfd_coff_swap_sym_out (output_bfd, &isym, outsym); *indexp = output_index; @@ -1926,13 +1871,13 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) /* Fix up the aux entries. This must be done in a separate pass, because we don't know the correct symbol indices until we have already decided which symbols we are going to keep. */ - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; isymp = finfo->internal_syms; indexp = finfo->sym_indices; sym_hash = obj_coff_sym_hashes (input_bfd); outsym = finfo->outsyms; + while (esym < esym_end) { int add; @@ -1977,9 +1922,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) auxp = h->aux + i; else { - bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) &aux); + bfd_coff_swap_aux_in (input_bfd, esym, isymp->n_type, + isymp->n_sclass, i, isymp->n_numaux, &aux); auxp = &aux; } @@ -2072,18 +2016,19 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) if ((bfd_size_type) finfo->last_bf_index >= syment_base) { - PTR auxout; + void *auxout; /* The last .bf symbol is in this input file. This will only happen if the assembler did not set up the .bf endndx symbols correctly. */ - auxout = (PTR) (finfo->outsyms - + ((finfo->last_bf_index - - syment_base) - * osymesz)); + auxout = (finfo->outsyms + + ((finfo->last_bf_index + - syment_base) + * osymesz)); + bfd_coff_swap_aux_out (output_bfd, - (PTR) &finfo->last_bf, + &finfo->last_bf, isymp->n_type, isymp->n_sclass, 0, isymp->n_numaux, @@ -2099,11 +2044,11 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) temporarily. FIXME: This case should be made faster. */ bfd_coff_swap_aux_out (output_bfd, - (PTR) &finfo->last_bf, + &finfo->last_bf, isymp->n_type, isymp->n_sclass, 0, isymp->n_numaux, - (PTR) outsym); + outsym); pos = obj_sym_filepos (output_bfd); pos += finfo->last_bf_index * osymesz; if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 @@ -2130,9 +2075,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) if (h == NULL) { - bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isymp->n_type, + bfd_coff_swap_aux_out (output_bfd, auxp, isymp->n_type, isymp->n_sclass, i, isymp->n_numaux, - (PTR) outsym); + outsym); outsym += osymesz; } @@ -2186,7 +2131,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) { struct internal_lineno iline; - bfd_coff_swap_lineno_in (input_bfd, (PTR) eline, (PTR) &iline); + bfd_coff_swap_lineno_in (input_bfd, eline, &iline); if (iline.l_lnno != 0) iline.l_addr.l_paddr += offset; @@ -2222,27 +2167,26 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) of the line numbers rather than an absolute file index. */ bfd_coff_swap_sym_in (output_bfd, - (PTR) (finfo->outsyms - + ((indx - syment_base) - * osymesz)), - (PTR) &is); + (finfo->outsyms + + ((indx - syment_base) + * osymesz)), &is); if ((ISFCN (is.n_type) || is.n_sclass == C_BLOCK) && is.n_numaux >= 1) { - PTR auxptr; + void *auxptr; - auxptr = (PTR) (finfo->outsyms - + ((indx - syment_base + 1) - * osymesz)); + auxptr = (finfo->outsyms + + ((indx - syment_base + 1) + * osymesz)); bfd_coff_swap_aux_in (output_bfd, auxptr, is.n_type, is.n_sclass, - 0, is.n_numaux, (PTR) &ia); + 0, is.n_numaux, &ia); ia.x_sym.x_fcnary.x_fcn.x_lnnoptr = (o->output_section->line_filepos + o->output_section->lineno_count * linesz + eline - finfo->linenos); - bfd_coff_swap_aux_out (output_bfd, (PTR) &ia, + bfd_coff_swap_aux_out (output_bfd, &ia, is.n_type, is.n_sclass, 0, is.n_numaux, auxptr); } @@ -2255,8 +2199,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) if (!skipping) { - bfd_coff_swap_lineno_out (output_bfd, (PTR) &iline, - (PTR) oeline); + bfd_coff_swap_lineno_out (output_bfd, &iline, oeline); oeline += linesz; } } @@ -2280,10 +2223,10 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) && (bfd_size_type) finfo->last_file_index >= syment_base) { finfo->last_file.n_value = output_index; - bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - syment_base) - * osymesz))); + bfd_coff_swap_sym_out (output_bfd, &finfo->last_file, + (finfo->outsyms + + ((finfo->last_file_index - syment_base) + * osymesz))); } /* Write the modified symbols to the output file. */ @@ -2313,10 +2256,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) struct coff_section_tdata *secdata; if (! o->linker_mark) - { - /* This section was omitted from the link. */ - continue; - } + /* This section was omitted from the link. */ + continue; if ((o->flags & SEC_HAS_CONTENTS) == 0 || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0)) @@ -2393,7 +2334,6 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) *rel_hash = NULL; /* Adjust the reloc address and symbol index. */ - irel->r_vaddr += offset; if (irel->r_symndx == -1) @@ -2444,7 +2384,6 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) stripping. This should have been handled by the 'dont_skip_symbol' code in the while loop at the top of this function. */ - is = finfo->internal_syms + irel->r_symndx; name = (_bfd_coff_internal_syment_name @@ -2483,11 +2422,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) } } - if (! finfo->info->keep_memory) - { - if (! _bfd_coff_free_symbols (input_bfd)) - return FALSE; - } + if (! finfo->info->keep_memory + && ! _bfd_coff_free_symbols (input_bfd)) + return FALSE; return TRUE; } @@ -2495,9 +2432,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd) /* Write out a global symbol. Called via coff_link_hash_traverse. */ bfd_boolean -_bfd_coff_write_global_sym (h, data) - struct coff_link_hash_entry *h; - PTR data; +_bfd_coff_write_global_sym (struct coff_link_hash_entry *h, void *data) { struct coff_final_link_info *finfo = (struct coff_final_link_info *) data; bfd *output_bfd; @@ -2616,7 +2551,7 @@ _bfd_coff_write_global_sym (h, data) isym.n_numaux = h->numaux; - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms); + bfd_coff_swap_sym_out (output_bfd, &isym, finfo->outsyms); symesz = bfd_coff_symesz (output_bfd); @@ -2663,7 +2598,6 @@ _bfd_coff_write_global_sym (h, data) /* For PE, an overflow on the final link reportedly does not matter. FIXME: Why not? */ - if (sec->reloc_count > 0xffff && (! obj_pe (output_bfd) || finfo->info->relocatable)) @@ -2690,9 +2624,9 @@ _bfd_coff_write_global_sym (h, data) } } - bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isym.n_type, + bfd_coff_swap_aux_out (output_bfd, auxp, isym.n_type, isym.n_sclass, (int) i, isym.n_numaux, - (PTR) finfo->outsyms); + finfo->outsyms); if (bfd_bwrite (finfo->outsyms, symesz, output_bfd) != symesz) { finfo->failed = TRUE; @@ -2709,9 +2643,7 @@ _bfd_coff_write_global_sym (h, data) the dirty work, if the symbol we are processing needs conversion. */ bfd_boolean -_bfd_coff_write_task_globals (h, data) - struct coff_link_hash_entry *h; - PTR data; +_bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data) { struct coff_final_link_info *finfo = (struct coff_final_link_info *) data; bfd_boolean rtnval = TRUE; @@ -2741,11 +2673,10 @@ _bfd_coff_write_task_globals (h, data) /* Handle a link order which is supposed to generate a reloc. */ bfd_boolean -_bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) - bfd *output_bfd; - struct coff_final_link_info *finfo; - asection *output_section; - struct bfd_link_order *link_order; +_bfd_coff_reloc_link_order (bfd *output_bfd, + struct coff_final_link_info *finfo, + asection *output_section, + struct bfd_link_order *link_order) { reloc_howto_type *howto; struct internal_reloc *irel; @@ -2767,7 +2698,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) file_ptr loc; size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); + buf = bfd_zmalloc (size); if (buf == NULL) return FALSE; @@ -2797,7 +2728,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) break; } loc = link_order->offset * bfd_octets_per_byte (output_bfd); - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, + ok = bfd_set_section_contents (output_bfd, output_section, buf, loc, size); free (buf); if (! ok) @@ -2806,7 +2737,6 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) /* Store the reloc information in the right place. It will get swapped and written out at the end of the final_link routine. */ - irel = (finfo->section_info[output_section->target_index].relocs + output_section->reloc_count); rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes @@ -2865,7 +2795,6 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) routines anyhow. r_extern is only used for ECOFF. */ /* FIXME: What is the right value for r_offset? Is zero OK? */ - ++output_section->reloc_count; return TRUE; @@ -2875,17 +2804,14 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) simple relocs. */ bfd_boolean -_bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, - input_section, contents, relocs, syms, - sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; +_bfd_coff_generic_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + struct internal_reloc *relocs, + struct internal_syment *syms, + asection **sections) { struct internal_reloc *rel; struct internal_reloc *relend; @@ -2927,7 +2853,6 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, size of the symbol is included in the section contents, or it is not. We assume that the size is not included, and force the rtype_to_howto function to adjust the addend as needed. */ - if (sym != NULL && sym->n_scnum != 0) addend = - sym->n_value; else |