diff options
-rw-r--r-- | bfd/coff-i960.c | 101 | ||||
-rw-r--r-- | bfd/coffcode.h | 273 | ||||
-rw-r--r-- | bfd/cpu-a29k.c | 1 | ||||
-rw-r--r-- | bfd/ctor.c | 4 | ||||
-rw-r--r-- | bfd/reloc.c | 78 |
5 files changed, 344 insertions, 113 deletions
diff --git a/bfd/coff-i960.c b/bfd/coff-i960.c index b0a4b9d..e0727db 100644 --- a/bfd/coff-i960.c +++ b/bfd/coff-i960.c @@ -27,8 +27,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "sysdep.h" #include "libbfd.h" #include "obstack.h" -#include "coff-i960.h" -#include "internalcoff.h" +#include "coff/i960.h" +#include "coff/internal.h" #include "libcoff.h" /* to allow easier abstraction-breaking */ @@ -37,12 +37,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define BAL_MASK 0x00ffffff static bfd_reloc_status_type -optcall_callback(abfd, reloc_entry, symbol_in, data, ignore_input_section) -bfd *abfd; -arelent *reloc_entry; -asymbol *symbol_in; -unsigned char *data; -asection *ignore_input_section; +DEFUN (optcall_callback, (abfd, reloc_entry, symbol_in, data, ignore_input_section), + bfd *abfd AND + arelent *reloc_entry AND + asymbol *symbol_in AND + PTR data AND + asection *ignore_input_section) { /* This item has already been relocated correctly, but we may be * able to patch in yet better code - done by digging out the @@ -70,7 +70,7 @@ asection *ignore_input_section; to the correct location */ { union internal_auxent *aux = &((cs->native+2)->u.auxent); - int word = bfd_get_32(abfd, data + reloc_entry->address); + int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address); int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value); BFD_ASSERT(cs->native->u.syment.n_numaux==2); /* We replace the original call instruction with a bal to */ @@ -80,7 +80,7 @@ asection *ignore_input_section; /* offset of the bal entry point */ word = ((word + olf) & BAL_MASK) | BAL; - bfd_put_32(abfd, word, data+reloc_entry->address); + bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address); } result = bfd_reloc_ok; break; @@ -97,51 +97,47 @@ asection *ignore_input_section; return result; } - - -static reloc_howto_type howto_table[] = -{ - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - {6}, - {7}, - {8}, - {9}, - {10}, - {11}, - {12}, - {13}, - {14}, - {15}, - {16}, - +static reloc_howto_type howto_rellong = { (unsigned int) R_RELLONG, 0, 2, 32,false, 0, true, true, - 0,"rellong", true, 0xffffffff, 0xffffffff}, - {18}, - {19}, - {20}, - {21}, - {22}, - {23}, - {24}, - + 0,"rellong", true, 0xffffffff, 0xffffffff}; +static reloc_howto_type howto_iprmed = { R_IPRMED, 0, 2, 24,true,0, true, true,0,"iprmed ", true, - 0x00ffffff, 0x00ffffff}, - {26}, - + 0x00ffffff, 0x00ffffff}; +static reloc_howto_type howto_optcall = { R_OPTCALL, 0,2,24,true,0, true, true, optcall_callback, - "optcall", true, 0x00ffffff, 0x00ffffff}, + "optcall", true, 0x00ffffff, 0x00ffffff}; -}; +static reloc_howto_type * +DEFUN (coff_i960_reloc_type_lookup, (abfd, code), + bfd *abfd AND + bfd_reloc_code_type code) +{ + switch (code) + { + default: + return 0; + case BFD_RELOC_I960_CALLJ: + return &howto_optcall; + case BFD_RELOC_32: + return &howto_rellong; + case BFD_RELOC_24_PCREL: + return &howto_iprmed; + } +} /* The real code is in coffcode.h */ #define RTYPE2HOWTO(cache_ptr, dst) \ - cache_ptr->howto = howto_table + dst.r_type; +{ \ + reloc_howto_type *howto_ptr; \ + switch ((dst)->r_type) { \ + case 17: howto_ptr = &howto_rellong; break; \ + case 25: howto_ptr = &howto_iprmed; break; \ + case 27: howto_ptr = &howto_optcall; break; \ + default: howto_ptr = 0; break; \ + } \ + cache_ptr->howto = howto_ptr; \ + } #include "coffcode.h" @@ -170,8 +166,11 @@ bfd_target icoff_little_vec = _bfd_generic_mkarchive, bfd_false}, {bfd_false, coff_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, - JUMP_TABLE(coff) - }; + JUMP_TABLE(coff), + COFF_SWAP_TABLE, + coff_i960_reloc_type_lookup, + coff_make_debug_symbol, +}; bfd_target icoff_big_vec = @@ -200,5 +199,7 @@ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs {bfd_false, coff_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, JUMP_TABLE(coff), -COFF_SWAP_TABLE + COFF_SWAP_TABLE, + coff_i960_reloc_type_lookup, + coff_make_debug_symbol, }; diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 6c7eea9..cdb94eb 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -22,6 +22,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Most of this hacked by Steve Chamberlain, sac@cygnus.com */ + +#include <assert.h> +#include <stdio.h> + /* SECTION @@ -377,23 +381,34 @@ static flagword DEFUN(styp_to_sec_flags, (styp_flags), long styp_flags) { - flagword sec_flags=0; - - if ((styp_flags & STYP_TEXT) || (styp_flags & STYP_DATA)) - sec_flags = (SEC_LOAD | SEC_ALLOC); - else if (styp_flags & STYP_BSS) - sec_flags = SEC_ALLOC; + flagword sec_flags=0; -#ifdef STYP_LIT /* A29k readonly text/data section type */ - if ((styp_flags & STYP_LIT) == STYP_LIT) - sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY); -#endif /* STYP_LIT */ -#ifdef STYP_OTHER_LOAD /* Other loaded sections */ - if (styp_flags & STYP_OTHER_LOAD) - sec_flags = (SEC_LOAD | SEC_ALLOC); -#endif /* STYP_SDATA */ + if ((styp_flags & STYP_TEXT) || (styp_flags & STYP_DATA)) + { + sec_flags = SEC_LOAD | SEC_ALLOC; + } + else if (styp_flags & STYP_BSS) + { + sec_flags = SEC_ALLOC; + } + else + { + sec_flags = SEC_ALLOC | SEC_LOAD; + } +#ifdef STYP_LIT /* A29k readonly text/data section type */ + if ((styp_flags & STYP_LIT) == STYP_LIT) + { + sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY); + } +#endif /* STYP_LIT */ +#ifdef STYP_OTHER_LOAD /* Other loaded sections */ + if (styp_flags & STYP_OTHER_LOAD) + { + sec_flags = (SEC_LOAD | SEC_ALLOC); + } +#endif /* STYP_SDATA */ - return(sec_flags); + return(sec_flags); } #define get_index(symbol) ((int) (symbol)->udata) @@ -884,27 +899,22 @@ DEFUN(coff_swap_scnhdr_out,(abfd, in, out), */ static boolean -DEFUN(coff_new_section_hook,(abfd_ignore, section), - bfd *abfd_ignore AND +DEFUN(coff_new_section_hook,(abfd, section), + bfd *abfd AND asection *section) { - section->alignment_power = abfd_ignore->xvec->align_power_min; + section->alignment_power = abfd->xvec->align_power_min; + /* Allocate aux records for section symbols, to store size and + related info. + + @@ Shouldn't use constant multiplier here! */ + coffsymbol (section->symbol)->native = + (combined_entry_type *) bfd_zalloc (abfd, + sizeof (combined_entry_type) * 10); return true; } -static asection bfd_debug_section = -{ "*DEBUG*" }; - - - -static void -DEFUN(make_abs_section,(abfd), - bfd *abfd) -{ - - - -} +static asection bfd_debug_section = { "*DEBUG*" }; /* Take a section header read from a coff file (in HOST byte order), and make a BFD "section" out of it. */ @@ -1336,6 +1346,30 @@ DEFUN(coff_renumber_symbols,(bfd_ptr), unsigned int native_index = 0; struct internal_syment *last_file = (struct internal_syment *)NULL; unsigned int symbol_index; + + /* COFF demands that undefined symbols come after all other symbols. + Since we don't need to impose this extra knowledge on all our client + programs, deal with that here. Sort the symbol table; just move the + undefined symbols to the end, leaving the rest alone. */ + /* @@ Do we have some condition we could test for, so we don't always + have to do this? I don't think relocatability is quite right, but + I'm not certain. [raeburn:19920508.1711EST] */ + { + asymbol **newsyms; + int i; + + newsyms = (asymbol **) bfd_alloc_by_size_t (bfd_ptr, + sizeof (asymbol *) * symbol_count); + bfd_ptr->outsymbols = newsyms; + for (i = 0; i < symbol_count; i++) + if (symbol_ptr_ptr[i]->section != &bfd_und_section) + *newsyms++ = symbol_ptr_ptr[i]; + for (i = 0; i < symbol_count; i++) + if (symbol_ptr_ptr[i]->section == &bfd_und_section) + *newsyms++ = symbol_ptr_ptr[i]; + symbol_ptr_ptr = bfd_ptr->outsymbols; + } + for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) { coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]); @@ -1365,6 +1399,7 @@ DEFUN(coff_renumber_symbols,(bfd_ptr), native_index++; } } + obj_conv_table_size (bfd_ptr) = native_index; } @@ -1475,6 +1510,12 @@ unsigned int written) int class = native->u.syment.n_sclass; SYMENT buf; unsigned int j; + + /* @@ bfd_debug_section isn't accessible outside this file, but we know + that C_FILE symbols belong there. So move them. */ + if (native->u.syment.n_sclass == C_FILE) + symbol->section = &bfd_debug_section; + if (symbol->section == &bfd_abs_section) { native->u.syment.n_scnum = N_ABS; @@ -1588,7 +1629,7 @@ coff_symbol_type *symbol AND unsigned int written) { /* - Does this symbol have an ascociated line number - if so then + Does this symbol have an associated line number - if so then make it remember this symbol index. Also tag the auxent of this symbol to point to the right place in the lineno table */ @@ -1748,9 +1789,20 @@ DEFUN(coff_write_relocs,(abfd), struct internal_reloc n; arelent *q = p[i]; memset((PTR)&n, 0, sizeof(n)); + + /* @@FIXME COFF relocs don't support addends. Code should probably be + in the target-independent code, using a target flag to decide whether + to fold the addend into the section contents. */ + if (q->addend != 0) + abort (); + n.r_vaddr = q->address + s->vma; if (q->sym_ptr_ptr) { n.r_symndx = get_index((*(q->sym_ptr_ptr))); + /* Take notice if the symbol reloc points to a symbol we don't have + in our symbol table. What should we do for this?? */ + if (n.r_symndx > obj_conv_table_size (abfd)) + abort (); } #ifdef SELECT_RELOC /* Work out reloc type from what is required */ @@ -1823,6 +1875,7 @@ bfd *abfd; bfd_error = no_memory; return (NULL); } /* on error */ + new->symbol.section = 0; new->native = 0; new->lineno = (alent *) NULL; new->done_lineno = false; @@ -1832,6 +1885,26 @@ bfd *abfd; #ifndef NO_COFF_SYMBOLS +static asymbol * +DEFUN (coff_make_debug_symbol, (abfd, ptr, sz), + bfd *abfd AND + PTR ptr AND + unsigned long sz) +{ + coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type)); + if (new == NULL) { + bfd_error = no_memory; + return (NULL); + } /* on error */ + /* @@ This shouldn't be using a constant multiplier. */ + new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10); + new->symbol.section = &bfd_debug_section; + new->lineno = (alent *) NULL; + new->done_lineno = false; + new->symbol.the_bfd = abfd; + return &new->symbol; +} + static void DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how), bfd *ignore_abfd AND @@ -2128,8 +2201,115 @@ DEFUN(coff_compute_section_file_positions,(abfd), obj_relocbase(abfd) = sofar; } +#ifndef NO_COFF_SYMBOLS +static asymbol * +coff_section_symbol (abfd, name) + bfd *abfd; + char *name; +{ + asection *sec = bfd_get_section_by_name (abfd, name); + asymbol *sym; + combined_entry_type *csym; + + if (!sec) + { + /* create empty symbol */ + abort (); + } + sym = sec->symbol; + if (coff_symbol_from (abfd, sym)) + csym = coff_symbol_from (abfd, sym)->native; + else + csym = 0; + /* Make sure back-end COFF stuff is there. */ + if (csym == 0) + { + struct foo { + coff_symbol_type sym; + /* @@FIXME This shouldn't use a fixed size!! */ + combined_entry_type e[10]; + }; + struct foo *f; + f = (struct foo *) bfd_alloc_by_size_t (abfd, sizeof (*f)); + bzero ((char *) f, sizeof (*f)); + coff_symbol_from (abfd, sym)->native = csym = f->e; + } + csym[0].u.syment.n_sclass = C_STAT; + csym[0].u.syment.n_numaux = 1; +/* SF_SET_STATICS (sym); @@ ??? */ + if (sec) + { + csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size; + csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count; + csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count; + } + else + { + csym[1].u.auxent.x_scn.x_scnlen = 0; + csym[1].u.auxent.x_scn.x_nreloc = 0; + csym[1].u.auxent.x_scn.x_nlinno = 0; + } + return sym; +} +/* If .file, .text, .data, .bss symbols are missing, add them. */ +/* @@ Should we only be adding missing symbols, or overriding the aux + values for existing section symbols? */ +static void +coff_add_missing_symbols (abfd) + bfd *abfd; +{ + unsigned int nsyms = bfd_get_symcount (abfd); + asymbol **sympp = abfd->outsymbols; + asymbol **sympp2; + unsigned int i; + int need_text = 1, need_data = 1, need_bss = 1, need_file = 1; + coff_data_type *cdata = coff_data (abfd); + + for (i = 0; i < nsyms; i++) + { + coff_symbol_type *csym = coff_symbol_from (abfd, sympp[i]); + CONST char *name; + if (csym->native->u.syment.n_sclass == C_FILE) + { + need_file = 0; + continue; + } + name = csym->symbol.name; + if (!name) + continue; + if (!strcmp (name, _TEXT)) + need_text = 0; + else if (!strcmp (name, _DATA)) + need_data = 0; + else if (!strcmp (name, _BSS)) + need_bss = 0; + } + /* Now i == bfd_get_symcount (abfd). */ + /* @@ For now, don't deal with .file symbol. */ + need_file = 0; + + if (!need_text && !need_data && !need_bss && !need_file) + return; + nsyms += need_text + need_data + need_bss + need_file; + sympp2 = (asymbol**) bfd_alloc_by_size_t (abfd, nsyms * sizeof (asymbol *)); + memcpy (sympp2, sympp, i * sizeof (asymbol *)); + if (need_file) + { + /* @@ Generate fake .file symbol, in sympp2[i], and increment i. */ + abort (); + } + if (need_text) + sympp2[i++] = coff_section_symbol (abfd, _TEXT); + if (need_data) + sympp2[i++] = coff_section_symbol (abfd, _DATA); + if (need_bss) + sympp2[i++] = coff_section_symbol (abfd, _BSS); + assert (i == nsyms); + bfd_set_symtab (abfd, sympp2, nsyms); +} +#endif /* NO_COFF_SYMBOLS */ /* SUPPRESS 558 */ /* SUPPRESS 529 */ @@ -2159,12 +2339,15 @@ DEFUN(coff_write_object_contents,(abfd), bfd_error = system_call_error; /* Number the output sections, starting from one on the first section - with a name which doesn't start with a * */ + with a name which doesn't start with a *. + @@ The code doesn't make this check. Is it supposed to be done, + or isn't it?? */ count = 1; for (current = abfd->sections; current != (asection *)NULL; current = current->next) { current->target_index = count; + count++; } @@ -2424,6 +2607,7 @@ DEFUN(coff_write_object_contents,(abfd), #ifndef NO_COFF_SYMBOLS if (bfd_get_symcount(abfd) != 0) { + coff_add_missing_symbols (abfd); coff_renumber_symbols(abfd); coff_mangle_symbols(abfd); coff_write_symbols(abfd); @@ -3149,6 +3333,7 @@ DEFUN(coff_slurp_symbol_table,(abfd), obj_symbols(abfd) = cached_area; obj_raw_syments(abfd) = native_symbols; + obj_conv_table_size (abfd) = bfd_get_symcount (abfd); bfd_get_symcount(abfd) = number_of_symbols; obj_convert(abfd) = table_ptr; /* Slurp the line tables for each section too */ @@ -3324,16 +3509,18 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), cache_ptr->address = dst.r_vaddr; if (dst.r_symndx != -1) - { + { + /* @@ Should never be greater than count of symbols! */ + if (dst.r_symndx >= obj_conv_table_size (abfd)) + abort (); cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx]; ptr = *(cache_ptr->sym_ptr_ptr); - } + } else - { - cache_ptr->sym_ptr_ptr= bfd_abs_section.symbol_ptr_ptr; - ptr = 0; - - } + { + cache_ptr->sym_ptr_ptr= bfd_abs_section.symbol_ptr_ptr; + ptr = 0; + } /* The symbols definitions that we have read in have been @@ -3723,15 +3910,15 @@ DEFUN(bfd_coff_relax_section,(abfd, i, symbols), } static bfd_byte * -DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet), +DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet, data), bfd *in_abfd AND - bfd_seclet_type *seclet) + bfd_seclet_type *seclet AND + bfd_byte *data) { /* Get enough memory to hold the stuff */ bfd *input_bfd = seclet->u.indirect.section->owner; asection *input_section = seclet->u.indirect.section; - bfd_byte *data = (bfd_byte *)malloc(input_section->_raw_size); bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, input_section); arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size); diff --git a/bfd/cpu-a29k.c b/bfd/cpu-a29k.c index 3e1438c..50759ee 100644 --- a/bfd/cpu-a29k.c +++ b/bfd/cpu-a29k.c @@ -16,7 +16,6 @@ static bfd_arch_info_type arch_info_struct = bfd_default_compatible, bfd_default_scan , 0, - bfd_default_reloc_type_lookup, }; void DEFUN_VOID(bfd_a29k_arch) @@ -140,9 +140,7 @@ void DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type), rel_section->constructor_chain = reloc; reloc->relent.address = rel_section->_cooked_size; /* ask the cpu which howto to use */ - reloc->relent.howto = - bfd_reloc_type_lookup(abfd->arch_info, - BFD_RELOC_CTOR); + reloc->relent.howto = bfd_reloc_type_lookup(abfd, BFD_RELOC_CTOR); rel_section->_cooked_size += sizeof(int *); rel_section->reloc_count++; } diff --git a/bfd/reloc.c b/bfd/reloc.c index 1c715a5..93b2af7 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -295,7 +295,8 @@ CODE_FRAGMENT . arelent *reloc_entry, . struct symbol_cache_entry *symbol, . PTR data, -. asection *input_section)); +. asection *input_section, +. bfd *output_bfd )); . . {* The textual name of the relocation type. *} . char *name; @@ -450,13 +451,14 @@ DEFUN(bfd_perform_relocation,(abfd, flag = bfd_reloc_undefined; } - if (howto->special_function){ + if (howto->special_function) { bfd_reloc_status_type cont; cont = howto->special_function(abfd, reloc_entry, symbol, data, - input_section); + input_section, + output_bfd); if (cont != bfd_reloc_continue) return cont; } @@ -676,7 +678,50 @@ CODE_FRAGMENT . moment probably a 32 bit wide abs address, but the cpu can . choose. *} . -. BFD_RELOC_CTOR +. BFD_RELOC_CTOR, +. +. {* 32 bits wide, simple reloc *} +. BFD_RELOC_32, +. {* 32 bits, PC-relative *} +. BFD_RELOC_32_PCREL, +. +. {* High 22 bits of 32-bit value; simple reloc. *} +. BFD_RELOC_HI22, +. {* Low 10 bits. *} +. BFD_RELOC_LO10, +. +. {* Reloc types used for i960/b.out. *} +. BFD_RELOC_24_PCREL, +. BFD_RELOC_I960_CALLJ, +. +. BFD_RELOC_16_PCREL, +. {* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit +. word displacement, e.g. for SPARC) *} +. BFD_RELOC_32_PCREL_S2, +. +. {* now for the sparc/elf codes *} +. BFD_RELOC_NONE, {* actually used *} +. BFD_RELOC_SPARC_WDISP22, +. BFD_RELOC_SPARC22, +. BFD_RELOC_SPARC13, +. BFD_RELOC_SPARC_BASE13, +. BFD_RELOC_SPARC_GOT10, +. BFD_RELOC_SPARC_GOT13, +. BFD_RELOC_SPARC_GOT22, +. BFD_RELOC_SPARC_PC10, +. BFD_RELOC_SPARC_PC22, +. BFD_RELOC_SPARC_WPLT30, +. BFD_RELOC_SPARC_COPY, +. BFD_RELOC_SPARC_GLOB_DAT, +. BFD_RELOC_SPARC_JMP_SLOT, +. BFD_RELOC_SPARC_RELATIVE, +. BFD_RELOC_SPARC_UA32, +. +. {* this one is a.out specific? *} +. BFD_RELOC_SPARC_BASE22, +. +. {* this must be the highest numeric value *} +. BFD_RELOC_UNUSED . } bfd_reloc_code_real_type; */ @@ -688,8 +733,7 @@ SECTION SYNOPSIS CONST struct reloc_howto_struct * - bfd_reloc_type_lookup - (CONST bfd_arch_info_type *arch, bfd_reloc_code_type code); + bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_type code); DESCRIPTION This routine returns a pointer to a howto struct which when @@ -701,10 +745,10 @@ DESCRIPTION CONST struct reloc_howto_struct * DEFUN(bfd_reloc_type_lookup,(arch, code), - CONST bfd_arch_info_type *arch AND - bfd_reloc_code_type code) + bfd *abfd AND + bfd_reloc_code_type code) { - return arch->reloc_type_lookup(arch, code); + return BFD_SEND (abfd, reloc_type_lookup, (abfd, code)); } static reloc_howto_type bfd_howto_32 = @@ -764,7 +808,7 @@ SYNOPSIS DESCRIPTION Provides default handling for relaxing for back ends which - don't do relaxing - ie does nothing + don't do relaxing -- i.e., does nothing. */ boolean @@ -786,7 +830,8 @@ INTERNAL_FUNCTION SYNOPSIS bfd_byte * bfd_generic_get_relocated_section_contents(bfd *abfd, - struct bfd_seclet_struct *seclet) + struct bfd_seclet_struct *seclet, + bfd_byte *data) DESCRIPTION Provides default handling of relocation effort for back ends @@ -795,9 +840,10 @@ DESCRIPTION */ bfd_byte * -DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet), +DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet, data), bfd *abfd AND - struct bfd_seclet_struct *seclet) + struct bfd_seclet_struct *seclet AND + bfd_byte *data) { extern bfd_error_vector_type bfd_error_vector; @@ -805,11 +851,11 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet), bfd *input_bfd = seclet->u.indirect.section->owner; asection *input_section = seclet->u.indirect.section; - bfd_byte *data = (bfd_byte *) bfd_xmalloc(input_section->_raw_size); + bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, input_section); - arelent **reloc_vector = (arelent **) bfd_xmalloc(reloc_size); + arelent **reloc_vector = (arelent **) alloca(reloc_size); /* read in the section */ bfd_get_section_contents(input_bfd, @@ -862,7 +908,7 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet), } } - free((char *)reloc_vector); + return data; |