2009-08-12 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Wed, 12 Aug 2009 12:40:55 +0000 (12:40 +0000)
committerTristan Gingold <gingold@adacore.com>
Wed, 12 Aug 2009 12:40:55 +0000 (12:40 +0000)
* ld.h (fat_user_section_struct): Add map_symbol_def_count field.
* ldlang.c (hash_entry_addr_cmp): New function.
(print_all_symbols): Sort the symbols by address before printing them.

ld/ChangeLog
ld/ld.h
ld/ldlang.c

index e6897fc..ab12959 100644 (file)
@@ -1,3 +1,9 @@
+2009-08-12  Tristan Gingold  <gingold@adacore.com>
+
+       * ld.h (fat_user_section_struct): Add map_symbol_def_count field.
+       * ldlang.c (hash_entry_addr_cmp): New function.
+       (print_all_symbols): Sort the symbols by address before printing them.
+
 2009-08-10  Alan Modra  <amodra@bigpond.net.au>
 
        PR 10474
diff --git a/ld/ld.h b/ld/ld.h
index 018c080..32a140a 100644 (file)
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -114,6 +114,7 @@ typedef struct fat_user_section_struct {
      list of hash table entries for symbols defined in this section.  */
   struct map_symbol_def *map_symbol_def_head;
   struct map_symbol_def **map_symbol_def_tail;
+  unsigned long map_symbol_def_count;
 } fat_section_userdata_type;
 
 #define get_userdata(x) ((x)->userdata)
index a1bd2e3..abf941a 100644 (file)
@@ -1997,6 +1997,7 @@ init_map_userdata (bfd *abfd ATTRIBUTE_UNUSED,
   ASSERT (get_userdata (sec) == NULL);
   get_userdata (sec) = new_data;
   new_data->map_symbol_def_tail = &new_data->map_symbol_def_head;
+  new_data->map_symbol_def_count = 0;
 }
 
 static bfd_boolean
@@ -2024,6 +2025,7 @@ sort_def_symbol (struct bfd_link_hash_entry *hash_entry,
       def->entry = hash_entry;
       *(ud->map_symbol_def_tail) = def;
       ud->map_symbol_def_tail = &def->next;
+      ud->map_symbol_def_count++;
     }
   return TRUE;
 }
@@ -3949,18 +3951,48 @@ print_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr)
   return TRUE;
 }
 
+static int
+hash_entry_addr_cmp (const void *a, const void *b)
+{
+  const struct bfd_link_hash_entry *l = *(const struct bfd_link_hash_entry **)a;
+  const struct bfd_link_hash_entry *r = *(const struct bfd_link_hash_entry **)b;
+
+  if (l->u.def.value < r->u.def.value)
+    return -1;
+  else if (l->u.def.value > r->u.def.value)
+    return 1;
+  else
+    return 0;
+}
+
 static void
 print_all_symbols (asection *sec)
 {
   struct fat_user_section_struct *ud = get_userdata (sec);
   struct map_symbol_def *def;
+  struct bfd_link_hash_entry **entries;
+  unsigned int i;
 
   if (!ud)
     return;
 
   *ud->map_symbol_def_tail = 0;
-  for (def = ud->map_symbol_def_head; def; def = def->next)
-    print_one_symbol (def->entry, sec);
+  
+  /* Sort the symbols by address.  */
+  entries = obstack_alloc (&map_obstack,
+                           ud->map_symbol_def_count * sizeof (*entries));
+
+  for (i = 0, def = ud->map_symbol_def_head; def; def = def->next, i++)
+    entries[i] = def->entry;
+
+  qsort (entries, ud->map_symbol_def_count, sizeof (*entries),
+         hash_entry_addr_cmp);
+
+  /* Print the symbols.  */
+  for (i = 0; i < ud->map_symbol_def_count; i++)
+    print_one_symbol (entries[i], sec);
+
+  obstack_free (&map_obstack, entries);
 }
 
 /* Print information about an input section to the map file.  */