diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 579c4cb449e..2be755417a5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,25 @@ +Mon Jan 11 18:32:22 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * targets.c (bfd_target): Added relocateable argument to + _bfd_get_relocated_section_contents. Added _bfd_seclet_link + target vector for linker use. + * bfd.c (bfd_seclet_link): New macro. + * bfd-in.h (JUMP_TABLE): Added _bfd_seclet_link. + * seclet.c (rel, seclet_dump_seclet): Added relocateable argument + and boolean return value. Made static. + (bfd_generic_seclet_link): Renamed from seclet_dump. Added + relocateable argument. + * reloc.c (bfd_generic_get_relocated_section_contents): Added + relocateable argument (if relocateable, saves relocs). + * bout.c (b_out_get_relocated_section_contents), + reloc16.c (bfd_coff_reloc16_get_relocated_section_contents): Added + relocateable argument (if relocateable, just calls + bfd_generic_get_relocated_section_contents). + * libcoff-in.h (bfd_coff_reloc16_get_value): Added relocateable + argument to prototype. + * All targets: Set new _bfd_seclet_link vector to + bfd_generic_seclet_link. + Sat Jan 9 21:29:32 1993 Stu Grossman (grossman at cygnus.com) * coffgen.c: #include seclet.h. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index ea36784dbff..637af0d2feb 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -143,9 +143,12 @@ typedef int symtype; /* Who knows, yet? */ #define bfd_get_section(x) ((x)->section) #define bfd_get_output_section(x) ((x)->section->output_section) #define bfd_set_section(x,y) ((x)->section) = (y) -#define bfd_asymbol_base(x) ((x)->section?((x)->section->vma):0) +#define bfd_asymbol_base(x) ((x)->section->vma) #define bfd_asymbol_value(x) (bfd_asymbol_base(x) + x->value) #define bfd_asymbol_name(x) ((x)->name) +/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ +#define bfd_asymbol_bfd(x) ((x)->the_bfd) +#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) /* This is a type pun with struct ranlib on purpose! */ typedef struct carsym { @@ -284,15 +287,10 @@ CAT(NAME,_bfd_debug_info_start),\ CAT(NAME,_bfd_debug_info_end),\ CAT(NAME,_bfd_debug_info_accumulate),\ CAT(NAME,_bfd_get_relocated_section_contents),\ -CAT(NAME,_bfd_relax_section) - -#define COFF_SWAP_TABLE \ - coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, \ - coff_swap_aux_out, coff_swap_sym_out, \ - coff_swap_lineno_out, coff_swap_reloc_out, \ - coff_swap_filehdr_out, coff_swap_aouthdr_out, \ - coff_swap_scnhdr_out +CAT(NAME,_bfd_relax_section),\ +CAT(NAME,_bfd_seclet_link) +#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table /* User program access to BFD facilities */ diff --git a/bfd/bout.c b/bfd/bout.c index 8ab69c23cb3..a99bfdeeb50 100644 --- a/bfd/bout.c +++ b/bfd/bout.c @@ -1,5 +1,5 @@ /* BFD back-end for Intel 960 b.out binaries. - Copyright (C) 1990-1991 Free Software Foundation, Inc. + Copyright 1990, 1991, 1992 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -268,18 +268,23 @@ b_out_write_object_contents (abfd) #define PCREL13_MASK 0x1fff /* Magic to turn callx into calljx */ static bfd_reloc_status_type -DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section), +DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section, seclet), bfd *abfd AND arelent *reloc_entry AND PTR src AND PTR dst AND - - asection *input_section) + asection *input_section AND + bfd_seclet_type *seclet) { int word = bfd_get_32(abfd, src); asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); aout_symbol_type *symbol = aout_symbol(symbol_in); + if (symbol_in->section == &bfd_und_section) + { + bfd_error_vector.undefined_symbol(reloc_entry, seclet); + } + if (IS_CALLNAME(symbol->other)) { @@ -304,19 +309,26 @@ DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section), /* Magic to turn call into callj */ static bfd_reloc_status_type -DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx, input_section), +DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx, + input_section, seclet), bfd *abfd AND arelent *reloc_entry AND PTR data AND unsigned int srcidx AND unsigned int dstidx AND - asection *input_section ) + asection *input_section AND + bfd_seclet_type *seclet) { int word = bfd_get_32(abfd, (bfd_byte *) data + srcidx); asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); aout_symbol_type *symbol = aout_symbol(symbol_in); + if (symbol_in->section == &bfd_und_section) + { + bfd_error_vector.undefined_symbol(reloc_entry, seclet); + } + if (IS_OTHER(symbol->other)) { /* Call to a system procedure - replace code with system @@ -690,12 +702,14 @@ b_out_squirt_out_relocs (abfd, section) arelent *g = *generic; unsigned char *raw = (unsigned char *)natptr; asymbol *sym = *(g->sym_ptr_ptr); - + asection *output_section = sym->section->output_section; + bfd_h_put_32(abfd, g->address, raw); /* Find a type in the output format which matches the input howto - * at the moment we assume input format == output format FIXME!! */ + r_idx = 0; /* FIXME: Need callj stuff here, and to check the howto entries to be sure they are real for this architecture. */ if (g->howto== &howto_reloc_callj) @@ -714,12 +728,26 @@ b_out_squirt_out_relocs (abfd, section) { raw[7] = len_2 + incode_mask; } + else if (g->howto >= howto_align_table + && g->howto <= (howto_align_table + + sizeof (howto_align_table) / sizeof (howto_align_table[0]) + - 1)) + { + /* symnum == -2; extern_mask not set, pcrel_mask set */ + r_idx = -2; + r_extern = 0; + raw[7] = (pcrel_mask + | ((g->howto - howto_align_table) << 1)); + } else { raw[7] = len_2; } - if (output_section == &bfd_com_section - || output_section == &bfd_abs_section - || output_section == &bfd_und_section) + + if (r_idx != 0) + /* already mucked with r_extern, r_idx */; + else if (output_section == &bfd_com_section + || output_section == &bfd_abs_section + || output_section == &bfd_und_section) { if (bfd_abs_section.symbol == sym) @@ -1073,11 +1101,14 @@ DEFUN(b_out_relax_section,(abfd, i, symbols), #endif static bfd_byte * -DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), +DEFUN(b_out_get_relocated_section_contents,(in_abfd, + seclet, + data, + relocateable), bfd *in_abfd AND bfd_seclet_type *seclet AND - bfd_byte *data) - + bfd_byte *data AND + boolean relocateable) { /* Get enough memory to hold the stuff */ bfd *input_bfd = seclet->u.indirect.section->owner; @@ -1086,6 +1117,11 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), input_section); arelent **reloc_vector = (arelent **)alloca(reloc_size); + /* If producing relocateable output, don't bother to relax. */ + if (relocateable) + return bfd_generic_get_relocated_section_contents (in_abfd, seclet, + data, relocateable); + /* read in the section */ bfd_get_section_contents(input_bfd, input_section, @@ -1140,7 +1176,8 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), switch (reloc->howto->type) { case ABS32CODE: - calljx_callback(in_abfd, reloc, src_address + data, dst_address+data, input_section); + calljx_callback(in_abfd, reloc, src_address + data, dst_address+data, + input_section, seclet); src_address+=4; dst_address+=4; break; @@ -1150,7 +1187,8 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), dst_address+=4; break; case CALLJ: - callj_callback(in_abfd, reloc ,data,src_address,dst_address,input_section); + callj_callback(in_abfd, reloc ,data,src_address,dst_address, + input_section, seclet); src_address+=4; dst_address+=4; break; @@ -1161,7 +1199,8 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), case ABS32CODE_SHRUNK: /* This used to be a callx, but we've found out that a callj will reach, so do the right thing */ - callj_callback(in_abfd, reloc,data,src_address+4, dst_address,input_section); + callj_callback(in_abfd, reloc,data,src_address+4, dst_address, + input_section, seclet); dst_address+=4; src_address+=8; @@ -1170,6 +1209,10 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), { long int word = bfd_get_32(in_abfd, data+src_address); asymbol *symbol = *(reloc->sym_ptr_ptr); + if (symbol->section == &bfd_und_section) + { + bfd_error_vector.undefined_symbol(reloc, seclet); + } word = (word & ~BAL_MASK) | (((word & BAL_MASK) + symbol->section->output_offset + @@ -1189,6 +1232,10 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), { long int word = bfd_get_32(in_abfd, data+src_address); asymbol *symbol = *(reloc->sym_ptr_ptr); + if (symbol->section == &bfd_und_section) + { + bfd_error_vector.undefined_symbol(reloc, seclet); + } word = (word & ~PCREL13_MASK) | (((word & PCREL13_MASK) + symbol->section->output_offset + @@ -1244,6 +1291,7 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), #define aout_32_bfd_get_relocated_section_contents b_out_get_relocated_section_contents #define aout_32_bfd_relax_section b_out_relax_section +#define aout_32_bfd_seclet_link bfd_generic_seclet_link bfd_target b_out_vec_big_host = { @@ -1270,7 +1318,6 @@ bfd_target b_out_vec_big_host = _bfd_write_archive_contents, bfd_false}, JUMP_TABLE(aout_32), - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */ b_out_reloc_type_lookup, }; @@ -1299,6 +1346,5 @@ _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, JUMP_TABLE(aout_32), - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */ b_out_reloc_type_lookup, }; diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c index cddc4159b87..0fd65a72967 100644 --- a/bfd/coff-mips.c +++ b/bfd/coff-mips.c @@ -1302,6 +1302,7 @@ static CONST bfd_coff_backend_data bfd_ecoff_std_swap_table = { (void (*) PARAMS ((bfd *, struct sec *))) bfd_void #define ecoff_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define ecoff_bfd_relax_section bfd_generic_relax_section +#define ecoff_bfd_seclet_link bfd_generic_seclet_link bfd_target ecoff_little_vec = { diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 288464701f6..3c790812f30 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -2221,3 +2221,4 @@ static CONST bfd_coff_backend_data bfd_coff_std_swap_table = { (void (*) PARAMS ((bfd *, struct sec *))) bfd_void #define coff_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define coff_bfd_relax_section bfd_generic_relax_section +#define coff_bfd_seclet_link bfd_generic_seclet_link diff --git a/bfd/hppa.c b/bfd/hppa.c index 32fabf0364d..f035d7a8ad9 100644 --- a/bfd/hppa.c +++ b/bfd/hppa.c @@ -615,6 +615,7 @@ hppa_core_file_matches_executable_p (core_bfd, exec_bfd) #define hppa_bfd_get_relocated_section_contents \ bfd_generic_get_relocated_section_contents #define hppa_bfd_relax_section bfd_generic_relax_section +#define hppa_bfd_seclet_link bfd_generic_seclet_link bfd_target hppa_vec = { diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index c164c059613..05c0d1d4fb2 100644 --- a/bfd/libcoff-in.h +++ b/bfd/libcoff-in.h @@ -104,7 +104,7 @@ extern boolean bfd_coff_reloc16_relax_section PARAMS ((bfd *, asection *, asymbol **)); extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *)); + PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *, boolean relocateable)); extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *, struct bfd_seclet *)); diff --git a/bfd/libcoff.h b/bfd/libcoff.h index 01effe6fa3f..b3723806ff6 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -104,7 +104,7 @@ extern boolean bfd_coff_reloc16_relax_section PARAMS ((bfd *, asection *, asymbol **)); extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *)); + PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *, boolean relocateable)); extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *, struct bfd_seclet *)); diff --git a/bfd/sco-core.c b/bfd/sco-core.c index 01aac6c6241..c7279efcd9f 100644 --- a/bfd/sco-core.c +++ b/bfd/sco-core.c @@ -249,6 +249,9 @@ sco_core_file_matches_executable_p (core_bfd, exec_bfd) (bfd *, struct sec *))) bfd_void #define sco_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents #define sco_bfd_relax_section bfd_generic_relax_section +#define sco_bfd_seclet_link \ + ((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false) + /* If somebody calls any byte-swapping routines, shoot them. */ void swap_abort() diff --git a/bfd/seclet.c b/bfd/seclet.c index 9da4eb0fa9a..4615aee59da 100644 --- a/bfd/seclet.c +++ b/bfd/seclet.c @@ -46,6 +46,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "libbfd.h" #include "seclet.h" #include "coff/internal.h" + +/* Create a new seclet and attach it to a section. */ + bfd_seclet_type * DEFUN(bfd_new_seclet,(abfd, section), bfd *abfd AND @@ -64,19 +67,17 @@ DEFUN(bfd_new_seclet,(abfd, section), return n; } +/* Given an indirect seclet which points to an input section, relocate + the contents of the seclet and put the data in its final + destination. */ - - -#define MAX_ERRORS_IN_A_ROW 10 -extern bfd_error_vector_type bfd_error_vector; - - -void -DEFUN(rel,(abfd, seclet, output_section, data), +static boolean +DEFUN(rel,(abfd, seclet, output_section, data, relocateable), bfd *abfd AND bfd_seclet_type *seclet AND asection *output_section AND - PTR data) + PTR data AND + boolean relocateable) { if (output_section->flags & SEC_HAS_CONTENTS @@ -84,7 +85,8 @@ DEFUN(rel,(abfd, seclet, output_section, data), && (output_section->flags & SEC_LOAD) && seclet->size) { - data = (PTR) bfd_get_relocated_section_contents(abfd, seclet, data); + data = (PTR) bfd_get_relocated_section_contents(abfd, seclet, data, + relocateable); if(bfd_set_section_contents(abfd, output_section, data, @@ -94,59 +96,88 @@ DEFUN(rel,(abfd, seclet, output_section, data), abort(); } } + return true; } -void -DEFUN(seclet_dump_seclet,(abfd, seclet, section, data), +/* Put the contents of a seclet in its final destination. */ + +static boolean +DEFUN(seclet_dump_seclet,(abfd, seclet, section, data, relocateable), bfd *abfd AND bfd_seclet_type *seclet AND asection *section AND - PTR data) + PTR data AND + boolean relocateable) { switch (seclet->type) - { - case bfd_indirect_seclet: - /* The contents of this section come from another one somewhere - else */ - rel(abfd, seclet, section, data); - break; - case bfd_fill_seclet: - /* Fill in the section with us */ - { - char *d = bfd_xmalloc(seclet->size); - unsigned int i; - for (i =0; i < seclet->size; i+=2) { - d[i] = seclet->u.fill.value >> 8; - } - for (i = 1; i < seclet->size; i+=2) { - d[i] = seclet->u.fill.value ; - } - bfd_set_section_contents(abfd, section, d, seclet->offset, seclet->size); + { + case bfd_indirect_seclet: + /* The contents of this section come from another one somewhere + else */ + return rel(abfd, seclet, section, data, relocateable); - } - break; - default: - abort(); - } + case bfd_fill_seclet: + /* Fill in the section with us */ + { + char *d = bfd_xmalloc(seclet->size); + unsigned int i; + for (i =0; i < seclet->size; i+=2) { + d[i] = seclet->u.fill.value >> 8; + } + for (i = 1; i < seclet->size; i+=2) { + d[i] = seclet->u.fill.value ; + } + return bfd_set_section_contents(abfd, section, d, seclet->offset, + seclet->size); + } + + default: + abort(); + } + + return true; } -void -DEFUN(seclet_dump,(abfd, data), - bfd *abfd AND - PTR data) -{ - /* Write all the seclets on the bfd out, relocate etc according to the - rules */ +/* +INTERNAL_FUNCTION + bfd_generic_seclet_link +SYNOPSIS + boolean bfd_generic_seclet_link + (bfd *abfd, + PTR data, + boolean relocateable); + +DESCRIPTION + + The generic seclet linking routine. The caller should have + set up seclets for all the output sections. The DATA argument + should point to a memory area large enough to hold the largest + section. This function looks through the seclets and moves + the contents into the output sections. If RELOCATEABLE is + true, the orelocation fields of the output sections must + already be initialized. + +*/ + +boolean +DEFUN(bfd_generic_seclet_link,(abfd, data, relocateable), + bfd *abfd AND + PTR data AND + boolean relocateable) +{ asection *o = abfd->sections; while (o != (asection *)NULL) { bfd_seclet_type *p = o->seclets_head; while (p != (bfd_seclet_type *)NULL) { - seclet_dump_seclet(abfd, p, o, data); + if (seclet_dump_seclet(abfd, p, o, data, relocateable) == false) + return false; p = p ->next; } o = o->next; } + + return true; }