aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2001-05-28 11:57:54 +0000
committerNick Clifton <nickc@redhat.com>2001-05-28 11:57:54 +0000
commit209f668ef256fe2cfd18c64737ed89182383f11f (patch)
treecc4467b6dfd3b87e36a490c13c930edd82aae75a
parent1e329ce6ace8ea24ba9a160fa16055d29c65d497 (diff)
downloadgdb-209f668ef256fe2cfd18c64737ed89182383f11f.zip
gdb-209f668ef256fe2cfd18c64737ed89182383f11f.tar.gz
gdb-209f668ef256fe2cfd18c64737ed89182383f11f.tar.bz2
Handle MIPS64 relocs which use a non-1 valued int_rels_per_ext_rel
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elflink.h193
2 files changed, 149 insertions, 55 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 766e0f0..1ba25f5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2001-05-28 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ src/bfd/ChangeLog
+ * elflink.h (elf_link_size_reloc_section): Use bfd_zmalloc instead of
+ a zeroing loop.
+ (elf_link_output_relocs): Handle MIPS ELF64 relocations correctly.
+ (elf_link_input_bfd): Likewise.
+ (elf_reloc_link_order): Likewise.
+ (elf_finish_pointer_linker_section): Typo. Handle MIPS ELF64
+ relocations correctly.
+
2001-05-28 Nicolas Pitre <nico@cam.org>
* elf32-arm.h: fix PLT generation for big endian ARM
diff --git a/bfd/elflink.h b/bfd/elflink.h
index 0f5c712..db1c593 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -4108,7 +4108,6 @@ elf_link_size_reloc_section (abfd, rel_hdr, o)
Elf_Internal_Shdr *rel_hdr;
asection *o;
{
- register struct elf_link_hash_entry **p, **pend;
unsigned reloc_count;
/* Figure out how many relocations there will be. */
@@ -4132,16 +4131,15 @@ elf_link_size_reloc_section (abfd, rel_hdr, o)
first time we are called. */
if (elf_section_data (o)->rel_hashes == NULL)
{
+ struct elf_link_hash_entry **p;
+
p = ((struct elf_link_hash_entry **)
- bfd_malloc (o->reloc_count
- * sizeof (struct elf_link_hash_entry *)));
+ bfd_zmalloc (o->reloc_count
+ * sizeof (struct elf_link_hash_entry *)));
if (p == NULL && o->reloc_count != 0)
return false;
elf_section_data (o)->rel_hashes = p;
- pend = p + o->reloc_count;
- for (; p < pend; p++)
- *p = NULL;
}
return true;
@@ -4161,6 +4159,24 @@ 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;
+
+ irel = (Elf_Internal_Rel *) bfd_zmalloc (sizeof (Elf_Internal_Rel)
+ * bed->s->int_rels_per_ext_rel);
+ if (irel == NULL)
+ {
+ (*_bfd_error_handler) (_("Error: out of memory"));
+ abort ();
+ }
+
+ irela = (Elf_Internal_Rela *) bfd_zmalloc (sizeof (Elf_Internal_Rela)
+ * bed->s->int_rels_per_ext_rel);
+ if (irela == NULL)
+ {
+ (*_bfd_error_handler) (_("Error: out of memory"));
+ abort ();
+ }
for (i = 0; i < count; i++, rel_hash++)
{
@@ -4172,41 +4188,50 @@ elf_link_adjust_relocs (abfd, rel_hdr, count, rel_hash)
if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel))
{
Elf_External_Rel *erel;
- Elf_Internal_Rel irel;
+ 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);
+ (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, irel);
else
- elf_swap_reloc_in (abfd, erel, &irel);
- irel.r_info = ELF_R_INFO ((*rel_hash)->indx,
- ELF_R_TYPE (irel.r_info));
+ 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);
+ (*bed->s->swap_reloc_out) (abfd, irel, (bfd_byte *) erel);
else
- elf_swap_reloc_out (abfd, &irel, erel);
+ elf_swap_reloc_out (abfd, irel, erel);
}
else
{
Elf_External_Rela *erela;
- Elf_Internal_Rela irela;
+ 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);
+ (*bed->s->swap_reloca_in) (abfd, (bfd_byte *) erela, irela);
else
- elf_swap_reloca_in (abfd, erela, &irela);
- irela.r_info = ELF_R_INFO ((*rel_hash)->indx,
- ELF_R_TYPE (irela.r_info));
+ 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);
+ (*bed->s->swap_reloca_out) (abfd, irela, (bfd_byte *) erela);
else
- elf_swap_reloca_out (abfd, &irela, erela);
+ elf_swap_reloca_out (abfd, irela, erela);
}
}
+
+ free (irel);
+ free (irela);
}
/* Do the final step of an ELF link. */
@@ -5440,33 +5465,50 @@ elf_link_output_relocs (output_bfd, input_section, input_rel_hdr,
bed = get_elf_backend_data (output_bfd);
irela = internal_relocs;
- irelaend = irela + NUM_SHDR_ENTRIES (input_rel_hdr);
+ 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;
+
+ irel = (Elf_Internal_Rel *) bfd_zmalloc (bed->s->int_rels_per_ext_rel
+ * sizeof (Elf_Internal_Rel));
+ 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++, erel++)
+ for (; irela < irelaend; irela += bed->s->int_rels_per_ext_rel, erel++)
{
- Elf_Internal_Rel irel;
+ unsigned char 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);
+ }
- irel.r_offset = irela->r_offset;
- irel.r_info = irela->r_info;
- BFD_ASSERT (irela->r_addend == 0);
if (bed->s->swap_reloc_out)
- (*bed->s->swap_reloc_out) (output_bfd, &irel, (PTR) erel);
+ (*bed->s->swap_reloc_out) (output_bfd, irel, (PTR) erel);
else
- elf_swap_reloc_out (output_bfd, &irel, erel);
+ elf_swap_reloc_out (output_bfd, irel, erel);
}
+
+ free (irel);
}
else
{
Elf_External_Rela *erela;
- BFD_ASSERT (input_rel_hdr->sh_entsize
- == sizeof (Elf_External_Rela));
+ 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++, erela++)
+ 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
@@ -5798,21 +5840,28 @@ elf_link_input_bfd (finfo, input_bfd)
Elf_Internal_Rela *irelaend;
struct elf_link_hash_entry **rel_hash;
Elf_Internal_Shdr *input_rel_hdr;
+ unsigned char next_erel;
/* Adjust the reloc addresses and symbol indices. */
irela = internal_relocs;
- irelaend =
- irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
+ irelaend = irela
+ + o->reloc_count * bed->s->int_rels_per_ext_rel;
rel_hash = (elf_section_data (o->output_section)->rel_hashes
+ elf_section_data (o->output_section)->rel_count
+ elf_section_data (o->output_section)->rel_count2);
- for (; irela < irelaend; irela++, rel_hash++)
+ for (next_erel = 0; irela < irelaend; irela++, next_erel++)
{
unsigned long r_symndx;
Elf_Internal_Sym *isym;
asection *sec;
+ if (next_erel == bed->s->int_rels_per_ext_rel)
+ {
+ rel_hash++;
+ next_erel = 0;
+ }
+
irela->r_offset += o->output_offset;
/* Relocs in an executable have to be virtual addresses. */
@@ -5829,7 +5878,7 @@ elf_link_input_bfd (finfo, input_bfd)
&& finfo->sections[r_symndx] == NULL))
{
struct elf_link_hash_entry *rh;
- long indx;
+ unsigned long indx;
/* This is a reloc against a global symbol. We
have not yet output all the local symbols, so
@@ -5937,7 +5986,8 @@ elf_link_input_bfd (finfo, input_bfd)
elf_link_output_relocs (output_bfd, o,
input_rel_hdr,
internal_relocs);
- internal_relocs += NUM_SHDR_ENTRIES (input_rel_hdr);
+ internal_relocs += NUM_SHDR_ENTRIES (input_rel_hdr)
+ * bed->s->int_rels_per_ext_rel;
input_rel_hdr = elf_section_data (o)->rel_hdr2;
if (input_rel_hdr)
elf_link_output_relocs (output_bfd, o,
@@ -6110,32 +6160,52 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
if (rel_hdr->sh_type == SHT_REL)
{
- Elf_Internal_Rel irel;
+ Elf_Internal_Rel *irel;
Elf_External_Rel *erel;
+ unsigned char i;
+
+ irel = (Elf_Internal_Rel *) bfd_zmalloc (bed->s->int_rels_per_ext_rel
+ * sizeof (Elf_Internal_Rel));
+ 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);
- irel.r_offset = offset;
- irel.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);
+ (*bed->s->swap_reloc_out) (output_bfd, irel, (bfd_byte *) erel);
else
- elf_swap_reloc_out (output_bfd, &irel, erel);
+ elf_swap_reloc_out (output_bfd, irel, erel);
+
+ free (irel);
}
else
{
- Elf_Internal_Rela irela;
+ Elf_Internal_Rela *irela;
Elf_External_Rela *erela;
+ unsigned char i;
+
+ irela = (Elf_Internal_Rela *) bfd_zmalloc (bed->s->int_rels_per_ext_rel
+ * sizeof (Elf_Internal_Rela));
+ 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;
- irela.r_offset = offset;
- irela.r_info = ELF_R_INFO (indx, howto->type);
- irela.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);
+ (*bed->s->swap_reloca_out) (output_bfd, irela, (bfd_byte *) erela);
else
- elf_swap_reloca_out (output_bfd, &irela, erela);
+ elf_swap_reloca_out (output_bfd, irela, erela);
}
++elf_section_data (output_section)->rel_count;
@@ -6272,7 +6342,7 @@ elf_create_pointer_linker_section (abfd, info, lsect, h, rel)
#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_32 (BFD, VAL, ADDR)
#endif
-/* Fill in the address for a pointer generated in alinker section. */
+/* Fill in the address for a pointer generated in a linker section. */
bfd_vma
elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, relocation, rel, relative_reloc)
@@ -6339,7 +6409,17 @@ elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, reloca
if (info->shared)
{
asection *srel = lsect->rel_section;
- Elf_Internal_Rela outrel;
+ Elf_Internal_Rela *outrel;
+ struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+ unsigned int i;
+
+ outrel = (Elf_Internal_Rela *) bfd_zmalloc (sizeof (Elf_Internal_Rela)
+ * bed->s->int_rels_per_ext_rel);
+ if (outrel == NULL)
+ {
+ (*_bfd_error_handler) (_("Error: out of memory"));
+ return 0;
+ }
/* We need to generate a relative reloc for the dynamic linker. */
if (!srel)
@@ -6348,16 +6428,19 @@ elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, reloca
BFD_ASSERT (srel != NULL);
- outrel.r_offset = (lsect->section->output_section->vma
- + lsect->section->output_offset
- + linker_section_ptr->offset);
- outrel.r_info = ELF_R_INFO (0, relative_reloc);
- outrel.r_addend = 0;
- elf_swap_reloca_out (output_bfd, &outrel,
+ 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[0].r_info = ELF_R_INFO (0, relative_reloc);
+ outrel[0].r_addend = 0;
+ elf_swap_reloca_out (output_bfd, outrel,
(((Elf_External_Rela *)
lsect->section->contents)
+ elf_section_data (lsect->section)->rel_count));
++elf_section_data (lsect->section)->rel_count;
+
+ free (outrel);
}
}
}