diff options
author | Nick Clifton <nickc@redhat.com> | 2005-08-02 08:17:45 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2005-08-02 08:17:45 +0000 |
commit | 8e3de13a7def5bf8e931e34500f97bdeee6b111b (patch) | |
tree | 559192361050e3d7e4b8d0ae2af5430c2c009118 /bfd/elf32-arm.c | |
parent | 4e6935a6475f5041952c15c84c7d363fb98f055f (diff) | |
download | gdb-8e3de13a7def5bf8e931e34500f97bdeee6b111b.zip gdb-8e3de13a7def5bf8e931e34500f97bdeee6b111b.tar.gz gdb-8e3de13a7def5bf8e931e34500f97bdeee6b111b.tar.bz2 |
PR 1147
* elf32-arm.c (struct _arm_elf_section_data): Turn into a typedef and make the
mapcount field unsigned.
(struct section_list): New: Used to keep track of which sections have an
_arm_elf_section_data structure.
(record_section_with_arm_elf_section_data): New function.
(get_arm_elf_section_data): New function.
(unrecord_section_with_arm_elf_section_data): New function.
(elf32_arm_output_symbol_hook): Use get_arm_elf_section_data.
(elf32_arm_new_section_hook): Call record_section_with_arm_elf_section_data.
(elf32_arm_write_section): Use get_arm_elf_section_data and
unrecord_section_with_arm_elf_section_data.
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r-- | bfd/elf32-arm.c | 125 |
1 files changed, 108 insertions, 17 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 8adbf10..147a7a5 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -1515,15 +1515,16 @@ typedef struct elf32_elf_section_map } elf32_arm_section_map; -struct _arm_elf_section_data +typedef struct _arm_elf_section_data { struct bfd_elf_section_data elf; - int mapcount; + unsigned int mapcount; elf32_arm_section_map *map; -}; +} +_arm_elf_section_data; #define elf32_arm_section_data(sec) \ - ((struct _arm_elf_section_data *) elf_section_data (sec)) + ((_arm_elf_section_data *) elf_section_data (sec)) /* The size of the thread control block. */ #define TCB_SIZE 8 @@ -4400,7 +4401,7 @@ elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd) /* Check to see if the input BFD actually contains any sections. If not, its flags may not have been initialised either, but it - cannot actually cause any incompatibility. Do not short-circuit + cannot actually cause any incompatiblity. Do not short-circuit dynamic objects; their section list may be emptied by elf_link_add_object_symbols. @@ -6511,6 +6512,71 @@ elf32_arm_section_from_shdr (bfd *abfd, return TRUE; } +/* A structure used to record a list of sections, independently + of the next and prev fields in the asection structure. */ +typedef struct section_list +{ + asection * sec; + struct section_list * next; + struct section_list * prev; +} +section_list; + +/* Unfortunately we need to keep a list of sections for which + an _arm_elf_section_data structure has been allocated. This + is because it is possible for functions like elf32_arm_write_section + to be called on a section which has had an elf_data_structure + allocated for it (and so the used_by_bfd field is valid) but + for which the ARM extended version of this structure - the + _arm_elf_section_data structure - has not been allocated. */ +static section_list * sections_with_arm_elf_section_data = NULL; + +static void +record_section_with_arm_elf_section_data (bfd * abfd, asection * sec) +{ + struct section_list * entry; + + entry = bfd_alloc (abfd, sizeof (* entry)); + if (entry == NULL) + return; + entry->sec = sec; + entry->next = sections_with_arm_elf_section_data; + entry->prev = NULL; + if (entry->next != NULL) + entry->next->prev = entry; + sections_with_arm_elf_section_data = entry; +} + +static _arm_elf_section_data * +get_arm_elf_section_data (asection * sec) +{ + struct section_list * entry; + + for (entry = sections_with_arm_elf_section_data; entry; entry = entry->next) + if (entry->sec == sec) + return elf32_arm_section_data (sec); + return NULL; +} + +static void +unrecord_section_with_arm_elf_section_data (asection * sec) +{ + struct section_list * entry; + + for (entry = sections_with_arm_elf_section_data; entry; entry = entry->next) + if (entry->sec == sec) + { + if (entry->prev != NULL) + entry->prev->next = entry->next; + if (entry->next != NULL) + entry->next->prev = entry->prev; + if (entry == sections_with_arm_elf_section_data) + sections_with_arm_elf_section_data = entry->next; + free (entry); + break; + } +} + /* Called for each symbol. Builds a section map based on mapping symbols. Does not alter any of the symbols. */ @@ -6523,6 +6589,8 @@ elf32_arm_output_symbol_hook (struct bfd_link_info *info, { int mapcount; elf32_arm_section_map *map; + elf32_arm_section_map *newmap; + _arm_elf_section_data *arm_data; struct elf32_arm_link_hash_table *globals; /* Only do this on final link. */ @@ -6538,25 +6606,35 @@ elf32_arm_output_symbol_hook (struct bfd_link_info *info, if (! bfd_is_arm_mapping_symbol_name (name)) return TRUE; - mapcount = ++(elf32_arm_section_data (input_sec)->mapcount); - map = elf32_arm_section_data (input_sec)->map; + /* If this section has not been allocated an _arm_elf_section_data + structure then we cannot record anything. */ + arm_data = get_arm_elf_section_data (input_sec); + if (arm_data == NULL) + return TRUE; + + mapcount = arm_data->mapcount + 1; + map = arm_data->map; /* TODO: This may be inefficient, but we probably don't usually have many mapping symbols per section. */ - map = bfd_realloc (map, mapcount * sizeof (elf32_arm_section_map)); - elf32_arm_section_data (input_sec)->map = map; + newmap = bfd_realloc (map, mapcount * sizeof (* map)); + if (newmap != NULL) + { + arm_data->map = newmap; + arm_data->mapcount = mapcount; + + map[mapcount - 1].vma = elfsym->st_value; + map[mapcount - 1].type = name[1]; + } - map[mapcount - 1].vma = elfsym->st_value; - map[mapcount - 1].type = name[1]; return TRUE; } - /* Allocate target specific section data. */ static bfd_boolean elf32_arm_new_section_hook (bfd *abfd, asection *sec) { - struct _arm_elf_section_data *sdata; + _arm_elf_section_data *sdata; bfd_size_type amt = sizeof (*sdata); sdata = bfd_zalloc (abfd, amt); @@ -6564,6 +6642,8 @@ elf32_arm_new_section_hook (bfd *abfd, asection *sec) return FALSE; sec->used_by_bfd = sdata; + record_section_with_arm_elf_section_data (abfd, sec); + return _bfd_elf_new_section_hook (abfd, sec); } @@ -6586,6 +6666,7 @@ elf32_arm_write_section (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec, bfd_byte *contents) { int mapcount; + _arm_elf_section_data *arm_data; elf32_arm_section_map *map; bfd_vma ptr; bfd_vma end; @@ -6593,14 +6674,19 @@ elf32_arm_write_section (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec, bfd_byte tmp; int i; - mapcount = elf32_arm_section_data (sec)->mapcount; - map = elf32_arm_section_data (sec)->map; + /* If this section has not been allocated an _arm_elf_section_data + structure then we cannot record anything. */ + arm_data = get_arm_elf_section_data (sec); + if (arm_data == NULL) + return FALSE; + + mapcount = arm_data->mapcount; + map = arm_data->map; if (mapcount == 0) return FALSE; - qsort (map, mapcount, sizeof (elf32_arm_section_map), - elf32_arm_compare_mapping); + qsort (map, mapcount, sizeof (* map), elf32_arm_compare_mapping); offset = sec->output_section->vma + sec->output_offset; ptr = map[0].vma - offset; @@ -6644,7 +6730,12 @@ elf32_arm_write_section (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec, } ptr = end; } + free (map); + arm_data->mapcount = 0; + arm_data->map = NULL; + unrecord_section_with_arm_elf_section_data (sec); + return FALSE; } |