This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH v2 04/12] bfd/ * bfd/elf32-microblaze.c: Correct adjustment of global symbols
- From: david dot holsgrove at xilinx dot com
- To: binutils at sourceware dot org
- Cc: eager at eagercon dot com, edgar dot iglesias at gmail dot com, joseph at codesourcery dot com, john dot williams at xilinx dot com, vidhumouli dot hunsigida at xilinx dot com, nagaraju dot mekala at xilinx dot com, David Holsgrove <david dot holsgrove at xilinx dot com>
- Date: Thu, 11 Oct 2012 17:17:06 +1000
- Subject: [PATCH v2 04/12] bfd/ * bfd/elf32-microblaze.c: Correct adjustment of global symbols
- References: <cover.1349938301.git.david.holsgrove@xilinx.com>
- References: <cover.1349938301.git.david.holsgrove@xilinx.com>
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