diff options
-rw-r--r-- | ld/ChangeLog | 6 | ||||
-rw-r--r-- | ld/ld.h | 1 | ||||
-rw-r--r-- | ld/ldlang.c | 36 |
3 files changed, 41 insertions, 2 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index e6897fc..ab12959 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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 @@ -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) diff --git a/ld/ldlang.c b/ld/ldlang.c index a1bd2e3..abf941a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -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. */ |