[binutils-gdb] Move microblaze relax info to target specific data

Alan Modra amodra@sourceware.org
Sun Apr 3 12:05:45 GMT 2022


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9751574e09a4d66b569b019e8b1d87eba1ce3288

commit 9751574e09a4d66b569b019e8b1d87eba1ce3288
Author: Alan Modra <amodra@gmail.com>
Date:   Sun Apr 3 21:34:53 2022 +0930

    Move microblaze relax info to target specific data
    
    Target specific data shouldn't be put in struct bfd_section.
    
            * section.c (struct bfd_section): Delete relax and relax_count.
            (BFD_FAKE_SECTION): Adjust to suit.
            (struct relax_table): Move to..
            * elf32-microblaze.c (struct relax_table): ..here.
            (struct _microblaze_elf_section_data): New.
            (microblaze_elf_section_data): Define.
            (microblaze_elf_new_section_hook): New function.
            (bfd_elf32_new_section_hook): Define.
            (calc_fixup): Return a size_t.  Adjust to suit new location of
            relax and relax_count.
            (microblaze_elf_relax_section): Adjust to suit new location of
            relax and relax_count.  Make some variables size_t.
            * bfd-in2.h: Regenerate.

Diff:
---
 bfd/bfd-in2.h          |  22 +---------
 bfd/elf32-microblaze.c | 116 ++++++++++++++++++++++++++++++++++---------------
 bfd/section.c          |  22 +---------
 3 files changed, 85 insertions(+), 75 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index bf3b6c66fd0..404dae2eba5 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 d09b3f7095d..ebdba93d0e9 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 9a1071454f5..d7922e0741a 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,					\


More information about the Binutils-cvs mailing list