diff options
author | Alan Modra <amodra@gmail.com> | 2002-11-28 11:55:43 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2002-11-28 11:55:43 +0000 |
commit | 947216bf8f343c1440e85633b5bf2f2394f87bc4 (patch) | |
tree | 3da37461a51d911b0778e071fc9214f5e9ffc2fe /bfd/elflink.h | |
parent | 1448fa32275a8686debba9323308841480c33fc7 (diff) | |
download | gdb-947216bf8f343c1440e85633b5bf2f2394f87bc4.zip gdb-947216bf8f343c1440e85633b5bf2f2394f87bc4.tar.gz gdb-947216bf8f343c1440e85633b5bf2f2394f87bc4.tar.bz2 |
include/elf/ChangeLog
* internal.h (elf32_internal_ehdr, Elf32_Internal_Ehdr,
elf64_internal_ehdr, Elf64_Internal_Ehdr, elf32_internal_phdr,
Elf32_Internal_Phdr, elf64_internal_phdr, Elf64_Internal_Phdr,
elf32_internal_shdr, Elf32_Internal_Shdr, elf64_internal_shdr,
Elf64_Internal_Shdr, elf32_internal_sym, elf64_internal_sym,
Elf32_Internal_Sym, Elf64_Internal_Sym, Elf32_Internal_Note,
elf32_internal_note, elf32_internal_rel, Elf32_Internal_Rel,
elf64_internal_rel, Elf64_Internal_Rel, elf32_internal_rela,
elf64_internal_rela, Elf32_Internal_Rela, Elf64_Internal_Rela,
elf32_internal_dyn, elf64_internal_dyn, Elf32_Internal_Dyn,
Elf64_Internal_Dyn, elf32_internal_verdef, elf64_internal_verdef,
elf32_internal_verdaux, elf64_internal_verdaux, elf32_internal_verneed,
elf64_internal_verneed, elf32_internal_vernaux, elf64_internal_vernaux,
elf32_internal_versym, elf64_internal_versym, Elf32_Internal_Verdef,
Elf64_Internal_Verdef, Elf32_Internal_Verdaux, Elf64_Internal_Verdaux,
Elf32_Internal_Verneed, Elf64_Internal_Verneed, Elf32_Internal_Vernaux,
Elf64_Internal_Vernaux, Elf32_Internal_Versym, Elf64_Internal_Versym,
Elf32_Internal_Syminfo, Elf64_Internal_Syminfo): Delete.
(Elf_Internal_Rel): Delete.
bfd/ChangeLog
* elf-bfd.h: Replace occurrences of Elf32_Internal_* and
Elf64_Internal_* with Elf_Internal_*. Replace Elf_Internal_Rel
with Elf_Internal_Rela.
* elf-hppa.h, elf-m10200.c, elf-m10300.c, elf32-arc.c, elf32-arm.h,
elf32-avr.c, elf32-cris.c, elf32-d10v.c, elf32-d30v.c, elf32-dlx.c,
elf32-fr30.c, elf32-frv.c, elf32-gen.c, elf32-h8300.c, elf32-hppa.c,
elf32-i370.c, elf32-i386.c, elf32-i860.c, elf32-i960.c, elf32-ip2k.c,
elf32-m32r.c, elf32-m68hc11.c, elf32-m68hc12.c, elf32-m68k.c,
elf32-mcore.c, elf32-mips.c, elf32-openrisc.c, elf32-or32.c,
elf32-ppc.c, elf32-s390.c, elf32-sh.c, elf32-v850.c, elf32-vax.c,
elf32-xstormy16.c, elf64-alpha.c, elf64-gen.c, elf64-hppa.c,
elf64-mips.c, elf64-mmix.c, elf64-ppc.c, elf64-s390.c, elf64-sh64.c,
elf64-sparc.c, elf64-x86-64.c, elfarm-nabi.c, elfarm-oabi.c,
elfcode.h, elflink.h, elfn32-mips.c, elfxx-ia64.c, elfxx-mips.c: Ditto.
* elf-hppa.h (elf_hppa_internal_shdr): Delete. Use Elf_Internal_Shdr
throughout instead.
* elf.c (_bfd_elf_no_info_to_howto_rel): Delete.
* elfcode.h (elf_swap_reloca_in): Pass source operand as a bfd_byte *.
Remove INLINE keyword.
(elf_swap_reloc_in): Likewise. Also clear r_addend.
(elf_swap_reloc_out, elf_swap_reloca_out): Pass destination operand
as a bfd_byte *.
(elf_write_relocs): Consolidate REL and RELA code.
(elf_slurp_reloc_table_from_section): Simplify REL code.
(NAME(_bfd_elf,size_info)): Populate reloc swap entries.
* elf-bfd.h (MAX_INT_RELS_PER_EXT_REL): Define.
* elflink.h (elf_link_read_relocs_from_section): Consolidate REL and
RELA code.
(elf_link_adjust_relocs): Likewise. Don't malloc space for temp
reloc array, use a fixed size of MAX_INT_RELS_PER_EXT_REL.
(elf_link_output_relocs): Likewise.
(elf_reloc_link_order): Likewise.
(elf_finish_pointer_linker_section): Likewise.
(struct elf_link_sort_rela): Remove union.
(elf_link_sort_cmp1): Update to suit.
(elf_link_sort_cmp2): Here too.
(elf_link_sort_relocs): Consolidate REL and RELA code. Fix memory
over-allocation for int_rels_per_ext_rel != 1 case.
* elf32-arm.h: Update all bfd_elf32_swap_reloc_out calls.
* elf32-i386.c: Likewise.
* elf32-cris.c: Likewise for bfd_elf32_swap_reloca_out.
* elf32-hppa.c, elf32-i370.c, elf32-m68k.c, elf32-ppc.c, elf32-s390.c,
elf32-sh.c, elf32-vax.c, elfxx-mips.c: Likewise.
* elf64-alpha.c: Likewise for bfd_elf64_swap_reloca_out.
* elf64-hppa.c, elf64-mips.c, elf64-ppc.c, elf64-s390.c, elf64-sh64.c,
elf64-sparc.c, elf64-x86-64.c: Likewise.
* elfxx-ia64.c: Likewise for bfd_elfNN_swap_reloca_out.
* elfxx-mips.c (sort_dynamic_relocs): Likewise for
bfd_elf32_swap_reloc_in.
* elf32-arm.h: Update elf32_arm_info_to_howto calls.
* elf32-mips.c: Likewise for mips_info_to_howto_rel.
(mips_elf64_swap_reloc_in): Zero r_addend.
(mips_elf64_be_swap_reloc_in): Likewise.
(mips_elf64_slurp_one_reloc_table): Simplify.
* elf64-alpha.c (alpha_elf_size_info): Populate reloc swap entries.
* elf64-hppa.c (hppa64_elf_size_info): Likewise.
* elf64-sparc.c (sparc64_elf_size_info): Likewise.
Diffstat (limited to 'bfd/elflink.h')
-rw-r--r-- | bfd/elflink.h | 482 |
1 files changed, 150 insertions, 332 deletions
diff --git a/bfd/elflink.h b/bfd/elflink.h index c945194..7192778 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -2484,7 +2484,10 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs, Elf_Internal_Rela *internal_relocs; { struct elf_backend_data *bed; - bfd_size_type amt; + void (*swap_in) PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); + const bfd_byte *erela; + const bfd_byte *erelaend; + Elf_Internal_Rela *irela; /* If there aren't any relocations, that's OK. */ if (!shdr) @@ -2502,52 +2505,20 @@ elf_link_read_relocs_from_section (abfd, shdr, external_relocs, /* Convert the external relocations to the internal format. */ if (shdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_External_Rel *erelend; - Elf_Internal_Rela *irela; - Elf_Internal_Rel *irel; - - erel = (Elf_External_Rel *) external_relocs; - erelend = erel + NUM_SHDR_ENTRIES (shdr); - irela = internal_relocs; - amt = bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rel); - irel = bfd_alloc (abfd, amt); - for (; erel < erelend; erel++, irela += bed->s->int_rels_per_ext_rel) - { - unsigned int i; - - if (bed->s->swap_reloc_in) - (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, irel); - else - elf_swap_reloc_in (abfd, erel, irel); - - for (i = 0; i < bed->s->int_rels_per_ext_rel; ++i) - { - irela[i].r_offset = irel[i].r_offset; - irela[i].r_info = irel[i].r_info; - irela[i].r_addend = 0; - } - } - } + swap_in = bed->s->swap_reloc_in; + else if (shdr->sh_entsize == sizeof (Elf_External_Rela)) + swap_in = bed->s->swap_reloca_in; else - { - Elf_External_Rela *erela; - Elf_External_Rela *erelaend; - Elf_Internal_Rela *irela; - - BFD_ASSERT (shdr->sh_entsize == sizeof (Elf_External_Rela)); + abort (); - erela = (Elf_External_Rela *) external_relocs; - erelaend = erela + NUM_SHDR_ENTRIES (shdr); - irela = internal_relocs; - for (; erela < erelaend; erela++, irela += bed->s->int_rels_per_ext_rel) - { - if (bed->s->swap_reloca_in) - (*bed->s->swap_reloca_in) (abfd, (bfd_byte *) erela, irela); - else - elf_swap_reloca_in (abfd, erela, irela); - } + erela = external_relocs; + erelaend = erela + NUM_SHDR_ENTRIES (shdr) * shdr->sh_entsize; + irela = internal_relocs; + while (erela < erelaend) + { + (*swap_in) (abfd, erela, irela); + irela += bed->s->int_rels_per_ext_rel; + erela += shdr->sh_entsize; } return true; @@ -4588,91 +4559,51 @@ elf_link_adjust_relocs (abfd, rel_hdr, count, rel_hash) { unsigned int i; struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Rel *irel; - Elf_Internal_Rela *irela; - bfd_size_type amt = sizeof (Elf_Internal_Rel) * bed->s->int_rels_per_ext_rel; + bfd_byte *erela; + void (*swap_in) PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); + void (*swap_out) PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); - irel = (Elf_Internal_Rel *) bfd_zmalloc (amt); - if (irel == NULL) + if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) { - (*_bfd_error_handler) (_("Error: out of memory")); - abort (); + swap_in = bed->s->swap_reloc_in; + swap_out = bed->s->swap_reloc_out; } - - amt = sizeof (Elf_Internal_Rela) * bed->s->int_rels_per_ext_rel; - irela = (Elf_Internal_Rela *) bfd_zmalloc (amt); - if (irela == NULL) + else if (rel_hdr->sh_entsize == sizeof (Elf_External_Rela)) { - (*_bfd_error_handler) (_("Error: out of memory")); - abort (); + swap_in = bed->s->swap_reloca_in; + swap_out = bed->s->swap_reloca_out; } + else + abort (); - for (i = 0; i < count; i++, rel_hash++) + if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL) + abort (); + + erela = rel_hdr->contents; + for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize) { + Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL]; + unsigned int j; + if (*rel_hash == NULL) continue; BFD_ASSERT ((*rel_hash)->indx >= 0); - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - unsigned int j; - - erel = (Elf_External_Rel *) rel_hdr->contents + i; - if (bed->s->swap_reloc_in) - (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, irel); - else - elf_swap_reloc_in (abfd, erel, irel); - - for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) - irel[j].r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irel[j].r_info)); - - if (bed->s->swap_reloc_out) - (*bed->s->swap_reloc_out) (abfd, irel, (bfd_byte *) erel); - else - elf_swap_reloc_out (abfd, irel, erel); - } - else - { - Elf_External_Rela *erela; - unsigned int j; - - BFD_ASSERT (rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) rel_hdr->contents + i; - if (bed->s->swap_reloca_in) - (*bed->s->swap_reloca_in) (abfd, (bfd_byte *) erela, irela); - else - elf_swap_reloca_in (abfd, erela, irela); - - for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) - irela[j].r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irela[j].r_info)); - - if (bed->s->swap_reloca_out) - (*bed->s->swap_reloca_out) (abfd, irela, (bfd_byte *) erela); - else - elf_swap_reloca_out (abfd, irela, erela); - } + (*swap_in) (abfd, erela, irela); + for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) + irela[j].r_info = ELF_R_INFO ((*rel_hash)->indx, + ELF_R_TYPE (irela[j].r_info)); + (*swap_out) (abfd, irela, erela); } - - free (irel); - free (irela); } struct elf_link_sort_rela { bfd_vma offset; enum elf_reloc_type_class type; - union - { - /* We use these as arrays of size int_rels_per_ext_rel. */ - Elf_Internal_Rel rel[1]; - Elf_Internal_Rela rela[1]; - } u; + /* We use this as an array of size int_rels_per_ext_rel. */ + Elf_Internal_Rela rela[1]; }; static int @@ -4691,13 +4622,13 @@ elf_link_sort_cmp1 (A, B) return 1; if (relativea > relativeb) return -1; - if (ELF_R_SYM (a->u.rel->r_info) < ELF_R_SYM (b->u.rel->r_info)) + if (ELF_R_SYM (a->rela->r_info) < ELF_R_SYM (b->rela->r_info)) return -1; - if (ELF_R_SYM (a->u.rel->r_info) > ELF_R_SYM (b->u.rel->r_info)) + if (ELF_R_SYM (a->rela->r_info) > ELF_R_SYM (b->rela->r_info)) return 1; - if (a->u.rel->r_offset < b->u.rel->r_offset) + if (a->rela->r_offset < b->rela->r_offset) return -1; - if (a->u.rel->r_offset > b->u.rel->r_offset) + if (a->rela->r_offset > b->rela->r_offset) return 1; return 0; } @@ -4721,9 +4652,9 @@ elf_link_sort_cmp2 (A, B) return -1; if (copya > copyb) return 1; - if (a->u.rel->r_offset < b->u.rel->r_offset) + if (a->rela->r_offset < b->rela->r_offset) return -1; - if (a->u.rel->r_offset > b->u.rel->r_offset) + if (a->rela->r_offset > b->rela->r_offset) return 1; return 0; } @@ -4736,12 +4667,14 @@ elf_link_sort_relocs (abfd, info, psec) { bfd *dynobj = elf_hash_table (info)->dynobj; asection *reldyn, *o; - boolean rel = false; bfd_size_type count, size; - size_t i, j, ret; - struct elf_link_sort_rela *rela; + size_t i, ret, sort_elt, ext_size; + bfd_byte *sort, *s_non_relative, *p; + struct elf_link_sort_rela *sq; struct elf_backend_data *bed = get_elf_backend_data (abfd); int i2e = bed->s->int_rels_per_ext_rel; + void (*swap_in) PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *)); + void (*swap_out) PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); reldyn = bfd_get_section_by_name (abfd, ".rela.dyn"); if (reldyn == NULL || reldyn->_raw_size == 0) @@ -4749,11 +4682,17 @@ elf_link_sort_relocs (abfd, info, psec) reldyn = bfd_get_section_by_name (abfd, ".rel.dyn"); if (reldyn == NULL || reldyn->_raw_size == 0) return 0; - rel = true; - count = reldyn->_raw_size / sizeof (Elf_External_Rel); + ext_size = sizeof (Elf_External_Rel); + swap_in = bed->s->swap_reloc_in; + swap_out = bed->s->swap_reloc_out; } else - count = reldyn->_raw_size / sizeof (Elf_External_Rela); + { + ext_size = sizeof (Elf_External_Rela); + swap_in = bed->s->swap_reloca_in; + swap_out = bed->s->swap_reloca_out; + } + count = reldyn->_raw_size / ext_size; size = 0; for (o = dynobj->sections; o != NULL; o = o->next) @@ -4765,24 +4704,10 @@ elf_link_sort_relocs (abfd, info, psec) if (size != reldyn->_raw_size) return 0; - /* We waste some memory here when N = i2e is greater than 1, since - we allocate space for N * sizeof (*rela) where sizeof (*rela) + - (N - 1) * sizeof (Elf_Internal_Rel/Rela) would do. Also, we use - rela[k] only when k is a multiple of N, and then we index the - array within the union, such that rela[k].u.rel[i], i < N, is the - (i+1)th internal relocation corresponding to the (k/N)th external - relocation. This is done such that the relocation swap-in and - swap-out functions can gen pointers to arrays of internal - relocations that form a single external relocation. - - If C permitted arrays of structures with dynamic sizes, we could - do better, but trying to avoid wasting space at the end of the - chunk from rela[k] to rela[k+N-1] would require us to allocate a - separate array of pointers and since most ports have N == 1, this - would be more wasteful. */ - rela = (struct elf_link_sort_rela *) bfd_zmalloc - (sizeof (*rela) * count * i2e); - if (rela == NULL) + sort_elt = (sizeof (struct elf_link_sort_rela) + + (i2e - 1) * sizeof (Elf_Internal_Rela)); + sort = bfd_zmalloc (sort_elt * count); + if (sort == NULL) { (*info->callbacks->warning) (info, _("Not enough memory to sort relocations"), 0, abfd, 0, @@ -4795,103 +4720,62 @@ elf_link_sort_relocs (abfd, info, psec) == (SEC_HAS_CONTENTS|SEC_LINKER_CREATED) && o->output_section == reldyn) { - if (rel) - { - Elf_External_Rel *erel, *erelend; - struct elf_link_sort_rela *s; + bfd_byte *erel, *erelend; - erel = (Elf_External_Rel *) o->contents; - erelend = (Elf_External_Rel *) (o->contents + o->_raw_size); - s = rela + (o->output_offset / sizeof (Elf_External_Rel) * i2e); - for (; erel < erelend; erel++, s += i2e) - { - if (bed->s->swap_reloc_in) - (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, - s->u.rel); - else - elf_swap_reloc_in (abfd, erel, s->u.rel); - - s->type = (*bed->elf_backend_reloc_type_class) (s->u.rela); - } - } - else + erel = o->contents; + erelend = o->contents + o->_raw_size; + p = sort + o->output_offset / ext_size * sort_elt; + while (erel < erelend) { - Elf_External_Rela *erela, *erelaend; - struct elf_link_sort_rela *s; - - erela = (Elf_External_Rela *) o->contents; - erelaend = (Elf_External_Rela *) (o->contents + o->_raw_size); - s = rela + (o->output_offset / sizeof (Elf_External_Rela) * i2e); - for (; erela < erelaend; erela++, s += i2e) - { - if (bed->s->swap_reloca_in) - (*bed->s->swap_reloca_in) (dynobj, (bfd_byte *) erela, - s->u.rela); - else - elf_swap_reloca_in (dynobj, erela, s->u.rela); - - s->type = (*bed->elf_backend_reloc_type_class) (s->u.rela); - } + struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; + (*swap_in) (abfd, erel, s->rela); + s->type = (*bed->elf_backend_reloc_type_class) (s->rela); + p += sort_elt; + erel += ext_size; } } - qsort (rela, (size_t) count, sizeof (*rela) * i2e, elf_link_sort_cmp1); - for (ret = 0; ret < count * i2e && rela[ret].type == reloc_class_relative; - ret += i2e) - ; - for (i = ret, j = ret; i < count * i2e; i += i2e) + qsort (sort, (size_t) count, sort_elt, elf_link_sort_cmp1); + + for (i = 0, p = sort; i < count; i++, p += sort_elt) + { + struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; + if (s->type != reloc_class_relative) + break; + } + ret = i; + s_non_relative = p; + + sq = (struct elf_link_sort_rela *) s_non_relative; + for (; i < count; i++, p += sort_elt) { - if (ELF_R_SYM (rela[i].u.rel->r_info) - != ELF_R_SYM (rela[j].u.rel->r_info)) - j = i; - rela[i].offset = rela[j].u.rel->r_offset; + struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p; + if (ELF_R_SYM (sp->rela->r_info) != ELF_R_SYM (sq->rela->r_info)) + sq = sp; + sp->offset = sq->rela->r_offset; } - ret /= i2e; - qsort (rela + ret, (size_t) count - ret, - sizeof (*rela) * i2e, elf_link_sort_cmp2); + + qsort (s_non_relative, (size_t) count - ret, sort_elt, elf_link_sort_cmp2); for (o = dynobj->sections; o != NULL; o = o->next) if ((o->flags & (SEC_HAS_CONTENTS|SEC_LINKER_CREATED)) == (SEC_HAS_CONTENTS|SEC_LINKER_CREATED) && o->output_section == reldyn) { - if (rel) - { - Elf_External_Rel *erel, *erelend; - struct elf_link_sort_rela *s; + bfd_byte *erel, *erelend; - erel = (Elf_External_Rel *) o->contents; - erelend = (Elf_External_Rel *) (o->contents + o->_raw_size); - s = rela + (o->output_offset / sizeof (Elf_External_Rel) * i2e); - for (; erel < erelend; erel++, s += i2e) - { - if (bed->s->swap_reloc_out) - (*bed->s->swap_reloc_out) (abfd, s->u.rel, - (bfd_byte *) erel); - else - elf_swap_reloc_out (abfd, s->u.rel, erel); - } - } - else + erel = o->contents; + erelend = o->contents + o->_raw_size; + p = sort + o->output_offset / ext_size * sort_elt; + while (erel < erelend) { - Elf_External_Rela *erela, *erelaend; - struct elf_link_sort_rela *s; - - erela = (Elf_External_Rela *) o->contents; - erelaend = (Elf_External_Rela *) (o->contents + o->_raw_size); - s = rela + (o->output_offset / sizeof (Elf_External_Rela) * i2e); - for (; erela < erelaend; erela++, s += i2e) - { - if (bed->s->swap_reloca_out) - (*bed->s->swap_reloca_out) (dynobj, s->u.rela, - (bfd_byte *) erela); - else - elf_swap_reloca_out (dynobj, s->u.rela, erela); - } + struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; + (*swap_out) (abfd, s->rela, erel); + p += sort_elt; + erel += ext_size; } } - free (rela); *psec = reldyn; return ret; } @@ -6481,11 +6365,12 @@ elf_link_output_relocs (output_bfd, input_section, input_rel_hdr, { Elf_Internal_Rela *irela; Elf_Internal_Rela *irelaend; + bfd_byte *erel; Elf_Internal_Shdr *output_rel_hdr; asection *output_section; unsigned int *rel_countp = NULL; struct elf_backend_data *bed; - bfd_size_type amt; + void (*swap_out) PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *)); output_section = input_section->output_section; output_rel_hdr = NULL; @@ -6515,55 +6400,23 @@ elf_link_output_relocs (output_bfd, input_section, input_rel_hdr, } bed = get_elf_backend_data (output_bfd); + if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) + swap_out = bed->s->swap_reloc_out; + else if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rela)) + swap_out = bed->s->swap_reloca_out; + else + abort (); + + erel = output_rel_hdr->contents; + erel += *rel_countp * input_rel_hdr->sh_entsize; irela = internal_relocs; irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) * bed->s->int_rels_per_ext_rel); - - if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_Internal_Rel *irel; - - amt = bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rel); - irel = (Elf_Internal_Rel *) bfd_zmalloc (amt); - if (irel == NULL) - { - (*_bfd_error_handler) (_("Error: out of memory")); - abort (); - } - - erel = ((Elf_External_Rel *) output_rel_hdr->contents + *rel_countp); - for (; irela < irelaend; irela += bed->s->int_rels_per_ext_rel, erel++) - { - unsigned int i; - - for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) - { - irel[i].r_offset = irela[i].r_offset; - irel[i].r_info = irela[i].r_info; - BFD_ASSERT (irela[i].r_addend == 0); - } - - if (bed->s->swap_reloc_out) - (*bed->s->swap_reloc_out) (output_bfd, irel, (PTR) erel); - else - elf_swap_reloc_out (output_bfd, irel, erel); - } - - free (irel); - } - else + while (irela < irelaend) { - Elf_External_Rela *erela; - - BFD_ASSERT (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rela)); - - erela = ((Elf_External_Rela *) output_rel_hdr->contents + *rel_countp); - for (; irela < irelaend; irela += bed->s->int_rels_per_ext_rel, erela++) - if (bed->s->swap_reloca_out) - (*bed->s->swap_reloca_out) (output_bfd, irela, (PTR) erela); - else - elf_swap_reloca_out (output_bfd, irela, erela); + (*swap_out) (output_bfd, irela, erel); + irela += bed->s->int_rels_per_ext_rel; + erel += input_rel_hdr->sh_entsize; } /* Bump the counter, so that we know where to add the next set of @@ -7221,6 +7074,9 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order) struct elf_link_hash_entry **rel_hash_ptr; Elf_Internal_Shdr *rel_hdr; struct elf_backend_data *bed = get_elf_backend_data (output_bfd); + Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL]; + bfd_byte *erel; + unsigned int i; howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); if (howto == NULL) @@ -7336,58 +7192,28 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order) if (! info->relocateable) offset += output_section->vma; - rel_hdr = &elf_section_data (output_section)->rel_hdr; + for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) + { + irel[i].r_offset = offset; + irel[i].r_info = 0; + irel[i].r_addend = 0; + } + irel[0].r_info = ELF_R_INFO (indx, howto->type); + rel_hdr = &elf_section_data (output_section)->rel_hdr; + erel = rel_hdr->contents; if (rel_hdr->sh_type == SHT_REL) { - bfd_size_type size; - Elf_Internal_Rel *irel; - Elf_External_Rel *erel; - unsigned int i; - - size = bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rel); - irel = (Elf_Internal_Rel *) bfd_zmalloc (size); - if (irel == NULL) - return false; - - for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) - irel[i].r_offset = offset; - irel[0].r_info = ELF_R_INFO (indx, howto->type); - - erel = ((Elf_External_Rel *) rel_hdr->contents - + elf_section_data (output_section)->rel_count); - - if (bed->s->swap_reloc_out) - (*bed->s->swap_reloc_out) (output_bfd, irel, (bfd_byte *) erel); - else - elf_swap_reloc_out (output_bfd, irel, erel); - - free (irel); + erel += (elf_section_data (output_section)->rel_count + * sizeof (Elf_External_Rel)); + (*bed->s->swap_reloc_out) (output_bfd, irel, erel); } else { - bfd_size_type size; - Elf_Internal_Rela *irela; - Elf_External_Rela *erela; - unsigned int i; - - size = bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela); - irela = (Elf_Internal_Rela *) bfd_zmalloc (size); - if (irela == NULL) - return false; - - for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) - irela[i].r_offset = offset; - irela[0].r_info = ELF_R_INFO (indx, howto->type); - irela[0].r_addend = addend; - - erela = ((Elf_External_Rela *) rel_hdr->contents - + elf_section_data (output_section)->rel_count); - - if (bed->s->swap_reloca_out) - (*bed->s->swap_reloca_out) (output_bfd, irela, (bfd_byte *) erela); - else - elf_swap_reloca_out (output_bfd, irela, erela); + irel[0].r_addend = addend; + erel += (elf_section_data (output_section)->rel_count + * sizeof (Elf_External_Rela)); + (*bed->s->swap_reloca_out) (output_bfd, irel, erel); } ++elf_section_data (output_section)->rel_count; @@ -7604,19 +7430,10 @@ elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, if (info->shared) { asection *srel = lsect->rel_section; - Elf_Internal_Rela *outrel; - Elf_External_Rela *erel; + Elf_Internal_Rela outrel[MAX_INT_RELS_PER_EXT_REL]; + bfd_byte *erel; struct elf_backend_data *bed = get_elf_backend_data (output_bfd); unsigned int i; - bfd_size_type amt; - - amt = sizeof (Elf_Internal_Rela) * bed->s->int_rels_per_ext_rel; - outrel = (Elf_Internal_Rela *) bfd_zmalloc (amt); - if (outrel == NULL) - { - (*_bfd_error_handler) (_("Error: out of memory")); - return 0; - } /* We need to generate a relative reloc for the dynamic linker. */ @@ -7630,17 +7447,18 @@ elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, BFD_ASSERT (srel != NULL); for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) - outrel[i].r_offset = (lsect->section->output_section->vma - + lsect->section->output_offset - + linker_section_ptr->offset); + { + outrel[i].r_offset = (lsect->section->output_section->vma + + lsect->section->output_offset + + linker_section_ptr->offset); + outrel[i].r_info = 0; + outrel[i].r_addend = 0; + } outrel[0].r_info = ELF_R_INFO (0, relative_reloc); - outrel[0].r_addend = 0; - erel = (Elf_External_Rela *) lsect->section->contents; - erel += elf_section_data (lsect->section)->rel_count; + erel = lsect->section->contents; + erel += (elf_section_data (lsect->section)->rel_count++ + * sizeof (Elf_External_Rela)); elf_swap_reloca_out (output_bfd, outrel, erel); - ++elf_section_data (lsect->section)->rel_count; - - free (outrel); } } } |