diff options
-rw-r--r-- | bfd/bfd-in2.h | 22 | ||||
-rw-r--r-- | bfd/elf32-microblaze.c | 116 | ||||
-rw-r--r-- | bfd/section.c | 22 |
3 files changed, 85 insertions, 75 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index bf3b6c6..404dae2 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1070,13 +1070,6 @@ typedef struct bfd_section /* The compressed size of the section in octets. */ bfd_size_type compressed_size; - /* Relaxation table. */ - struct relax_table *relax; - - /* Count of used relaxation table entries. */ - int relax_count; - - /* If this section is going to be output, then this value is the offset in *bytes* into the output section of the first byte in the input section (byte ==> smallest addressable unit on the @@ -1177,17 +1170,6 @@ typedef struct bfd_section } asection; -/* Relax table contains information about instructions which can - be removed by relaxation -- replacing a long address with a - short address. */ -struct relax_table { - /* Address where bytes may be deleted. */ - bfd_vma addr; - - /* Number of bytes to be deleted. */ - int size; -}; - static inline const char * bfd_section_name (const asection *sec) { @@ -1336,8 +1318,8 @@ discarded_section (const asection *sec) /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \ 0, 0, 0, 0, 0, 0, \ \ - /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \ - 0, 0, 0, 0, 0, 0, 0, \ + /* vma, lma, size, rawsize, compressed_size, */ \ + 0, 0, 0, 0, 0, \ \ /* output_offset, output_section, alignment_power, */ \ 0, &SEC, 0, \ diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c index d09b3f7..ebdba93 100644 --- a/bfd/elf32-microblaze.c +++ b/bfd/elf32-microblaze.c @@ -697,6 +697,47 @@ microblaze_elf_info_to_howto (bfd * abfd, return true; } +/* Relax table contains information about instructions which can + be removed by relaxation -- replacing a long address with a + short address. */ +struct relax_table +{ + /* Address where bytes may be deleted. */ + bfd_vma addr; + + /* Number of bytes to be deleted. */ + size_t size; +}; + +struct _microblaze_elf_section_data +{ + struct bfd_elf_section_data elf; + /* Count of used relaxation table entries. */ + size_t relax_count; + /* Relaxation table. */ + struct relax_table *relax; +}; + +#define microblaze_elf_section_data(sec) \ + ((struct _microblaze_elf_section_data *) elf_section_data (sec)) + +static bool +microblaze_elf_new_section_hook (bfd *abfd, asection *sec) +{ + if (!sec->used_by_bfd) + { + struct _microblaze_elf_section_data *sdata; + size_t amt = sizeof (*sdata); + + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return false; + sec->used_by_bfd = sdata; + } + + return _bfd_elf_new_section_hook (abfd, sec); +} + /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */ static bool @@ -1647,23 +1688,24 @@ microblaze_elf_relocate_section (bfd *output_bfd, /* Calculate fixup value for reference. */ -static int +static size_t calc_fixup (bfd_vma start, bfd_vma size, asection *sec) { bfd_vma end = start + size; - int i, fixup = 0; + size_t i, fixup = 0; + struct _microblaze_elf_section_data *sdata; - if (sec == NULL || sec->relax == NULL) + if (sec == NULL || (sdata = microblaze_elf_section_data (sec)) == NULL) return 0; /* Look for addr in relax table, total fixup value. */ - for (i = 0; i < sec->relax_count; i++) + for (i = 0; i < sdata->relax_count; i++) { - if (end <= sec->relax[i].addr) + if (end <= sdata->relax[i].addr) break; - if ((end != start) && (start > sec->relax[i].addr)) + if (end != start && start > sdata->relax[i].addr) continue; - fixup += sec->relax[i].size; + fixup += sdata->relax[i].size; } return fixup; } @@ -1712,14 +1754,15 @@ microblaze_elf_relax_section (bfd *abfd, bfd_byte *free_contents = NULL; int rel_count; unsigned int shndx; - int i, sym_index; + size_t i, sym_index; asection *o; struct elf_link_hash_entry *sym_hash; Elf_Internal_Sym *isymbuf, *isymend; Elf_Internal_Sym *isym; - int symcount; - int offset; + size_t symcount; + size_t offset; bfd_vma src, dest; + struct _microblaze_elf_section_data *sdata; /* We only do this once per section. We may be able to delete some code by running multiple passes, but it is not worth it. */ @@ -1728,8 +1771,9 @@ microblaze_elf_relax_section (bfd *abfd, /* Only do this for a text section. */ if (bfd_link_relocatable (link_info) || (sec->flags & SEC_RELOC) == 0 - || (sec->reloc_count == 0) - || (sec->flags & SEC_CODE) == 0) + || (sec->flags & SEC_CODE) == 0 + || sec->reloc_count == 0 + || (sdata = microblaze_elf_section_data (sec)) == NULL) return true; BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0)); @@ -1754,11 +1798,11 @@ microblaze_elf_relax_section (bfd *abfd, if (! link_info->keep_memory) free_relocs = internal_relocs; - sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1) - * sizeof (struct relax_table)); - if (sec->relax == NULL) + sdata->relax_count = 0; + sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1) + * sizeof (*sdata->relax)); + if (sdata->relax == NULL) goto error_return; - sec->relax_count = 0; irelend = internal_relocs + sec->reloc_count; rel_count = 0; @@ -1848,9 +1892,9 @@ microblaze_elf_relax_section (bfd *abfd, || (symval & 0xffff8000) == 0xffff8000) { /* We can delete this instruction. */ - sec->relax[sec->relax_count].addr = irel->r_offset; - sec->relax[sec->relax_count].size = INST_WORD_SIZE; - sec->relax_count++; + sdata->relax[sdata->relax_count].addr = irel->r_offset; + sdata->relax[sdata->relax_count].size = INST_WORD_SIZE; + sdata->relax_count++; /* Rewrite relocation type. */ switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info)) @@ -1875,11 +1919,11 @@ microblaze_elf_relax_section (bfd *abfd, } /* Loop through all relocations. */ /* Loop through the relocs again, and see if anything needs to change. */ - if (sec->relax_count > 0) + if (sdata->relax_count > 0) { shndx = _bfd_elf_section_from_bfd_section (abfd, sec); rel_count = 0; - sec->relax[sec->relax_count].addr = sec->size; + sdata->relax[sdata->relax_count].addr = sec->size; for (irel = internal_relocs; irel < irelend; irel++, rel_count++) { @@ -1913,7 +1957,7 @@ microblaze_elf_relax_section (bfd *abfd, { /* This was a PC-relative instruction that was completely resolved. */ - int sfix, efix; + size_t sfix, efix; bfd_vma target_address; target_address = irel->r_addend + irel->r_offset; sfix = calc_fixup (irel->r_offset, 0, sec); @@ -1928,7 +1972,7 @@ microblaze_elf_relax_section (bfd *abfd, { /* This was a PC-relative 64-bit instruction that was completely resolved. */ - int sfix, efix; + size_t sfix, efix; bfd_vma target_address; target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE; sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec); @@ -2195,15 +2239,16 @@ microblaze_elf_relax_section (bfd *abfd, } /* Physically move the code and change the cooked size. */ - dest = sec->relax[0].addr; - for (i = 0; i < sec->relax_count; i++) + dest = sdata->relax[0].addr; + for (i = 0; i < sdata->relax_count; i++) { - int len; - src = sec->relax[i].addr + sec->relax[i].size; - len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size; + size_t len; + src = sdata->relax[i].addr + sdata->relax[i].size; + len = (sdata->relax[i+1].addr - sdata->relax[i].addr + - sdata->relax[i].size); memmove (contents + dest, contents + src, len); - sec->size -= sec->relax[i].size; + sec->size -= sdata->relax[i].size; dest += len; } @@ -2229,11 +2274,11 @@ microblaze_elf_relax_section (bfd *abfd, free_contents = NULL; } - if (sec->relax_count == 0) + if (sdata->relax_count == 0) { *again = false; - free (sec->relax); - sec->relax = NULL; + free (sdata->relax); + sdata->relax = NULL; } else *again = true; @@ -2242,9 +2287,9 @@ microblaze_elf_relax_section (bfd *abfd, error_return: free (free_relocs); free (free_contents); - free (sec->relax); - sec->relax = NULL; - sec->relax_count = 0; + free (sdata->relax); + sdata->relax = NULL; + sdata->relax_count = 0; return false; } @@ -3409,6 +3454,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd, #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name +#define bfd_elf32_new_section_hook microblaze_elf_new_section_hook #define elf_backend_relocate_section microblaze_elf_relocate_section #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match diff --git a/bfd/section.c b/bfd/section.c index 9a10714..d7922e0 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -455,13 +455,6 @@ CODE_FRAGMENT . {* The compressed size of the section in octets. *} . bfd_size_type compressed_size; . -. {* Relaxation table. *} -. struct relax_table *relax; -. -. {* Count of used relaxation table entries. *} -. int relax_count; -. -. . {* If this section is going to be output, then this value is the . offset in *bytes* into the output section of the first byte in the . input section (byte ==> smallest addressable unit on the @@ -562,17 +555,6 @@ CODE_FRAGMENT . .} asection; . -.{* Relax table contains information about instructions which can -. be removed by relaxation -- replacing a long address with a -. short address. *} -.struct relax_table { -. {* Address where bytes may be deleted. *} -. bfd_vma addr; -. -. {* Number of bytes to be deleted. *} -. int size; -.}; -. .static inline const char * .bfd_section_name (const asection *sec) .{ @@ -721,8 +703,8 @@ CODE_FRAGMENT . {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \ . 0, 0, 0, 0, 0, 0, \ . \ -. {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \ -. 0, 0, 0, 0, 0, 0, 0, \ +. {* vma, lma, size, rawsize, compressed_size, *} \ +. 0, 0, 0, 0, 0, \ . \ . {* output_offset, output_section, alignment_power, *} \ . 0, &SEC, 0, \ |