[PATCH v2 04/12] bfd/ * bfd/elf32-microblaze.c: Correct adjustment of global symbols
david.holsgrove@xilinx.com
david.holsgrove@xilinx.com
Thu Oct 11 07:18:00 GMT 2012
From: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Fixup symbol sizes after linker relaxation
This bug didn't affect code generation, but would have
affected debuggers that got the wrong view of things.
Correct an off-by one when comparing relaxation addresses
with symbol start.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
---
bfd/ChangeLog | 5 +++++
bfd/elf32-microblaze.c | 46 ++++++++++++++++++++++++++++++++++++++--------
2 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b542abd..6a3dbd3 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-10 Edgar E. Iglesias <edgar.iglesias@gmail.com>
+
+ * bfd/elf32-microblaze.c: Correct adjustment of global symbols
+ after linker relaxation
+
2012-09-20 Walter Lee <walt@tilera.com>
* elf32-tilepro.c (tilepro_elf_relocate_section): Adjust got
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
index 27b569e..b856d4c 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -1257,6 +1257,27 @@ microblaze_elf_relocate_section (bfd *output_bfd,
/* Calculate fixup value for reference. */
static int
+calc_size_fixup (bfd_vma start, bfd_vma size, asection *sec)
+{
+ bfd_vma end = start + size;
+ int i, fixup = 0;
+
+ if (sec == NULL || sec->relax == NULL)
+ return 0;
+
+ /* Look for addr in relax table, total fixup value. */
+ for (i = 0; i < sec->relax_count; i++)
+ {
+ if (end < sec->relax[i].addr)
+ break;
+ if (start > sec->relax[i].addr)
+ continue;
+ fixup += sec->relax[i].size;
+ }
+ return fixup;
+}
+
+static int
calc_fixup (bfd_vma addr, asection *sec)
{
int i, fixup = 0;
@@ -1740,23 +1761,32 @@ microblaze_elf_relax_section (bfd *abfd,
isymend = isymbuf + symtab_hdr->sh_info;
for (isym = isymbuf; isym < isymend; isym++)
{
- if (isym->st_shndx == shndx)
- isym->st_value =- calc_fixup (isym->st_value, sec);
+ if (isym->st_shndx == shndx) {
+ int count, count_size;
+
+ count = calc_fixup (isym->st_value, sec);
+ count_size = calc_size_fixup (isym->st_value, isym->st_size, sec);
+ isym->st_value -= count;
+ isym->st_size -= count_size;
+ }
}
/* Now adjust the global symbols defined in this section. */
isym = isymbuf + symtab_hdr->sh_info;
- isymend = isymbuf + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
- for (sym_index = 0; isym < isymend; isym++, sym_index++)
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
+ for (sym_index = 0; sym_index < symcount; sym_index++)
{
sym_hash = elf_sym_hashes (abfd)[sym_index];
- if (isym->st_shndx == shndx
- && (sym_hash->root.type == bfd_link_hash_defined
+ if ((sym_hash->root.type == bfd_link_hash_defined
|| sym_hash->root.type == bfd_link_hash_defweak)
&& sym_hash->root.u.def.section == sec)
{
- sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
- sec);
+ int count, count_size;
+
+ count = calc_fixup (sym_hash->root.u.def.value, sec);
+ count_size = calc_size_fixup (sym_hash->root.u.def.value, sym_hash->size, sec);
+ sym_hash->root.u.def.value -= count;
+ sym_hash->size -= count_size;
}
}
--
1.7.0.4
More information about the Binutils
mailing list