This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 04/12] bfd/ * bfd/elf32-microblaze.c: Correct adjustment of global symbols


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]