RFC: Rearranging the layout of the _symbol_info and bfd_section structures

Message ID 871ph5mu9h.fsf@redhat.com
State New
Headers
Series RFC: Rearranging the layout of the _symbol_info and bfd_section structures |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Nick Clifton March 27, 2026, 10:39 a.m. UTC
  Hi Guys,

  I am planning on applying the attached patch to close a couple of gaps
  in two of the structures used internally in the BFD library.  This
  reduces the size of the structures, which reduces the linker's overall
  memory requirements.  Not by a lot, but every bit helps.
  
  The first change is quite straightforward.  The _symbol_info structure
  has a 'char type' field sandwiched between several larger fields when
  it could quite happily use up some of the padding at the end of the
  structure.

  The second change is slightly more involved.  It moves all of the bit
  fields in the bfd_section structure to the end, and then also moves
  the target_index field to just before the bitfields.  This makes for a
  more efficient packing of the structure, saving 8 bytes on a 64-bit
  host.

  The is an issue however in that there is also a macro defined to
  initialise static sections (BFD_FAKE_SECTIONS) which expects a
  specific layout for the bfd_section structure.  Rather than fixing the
  macro to respect the new layout I decided instead to make use of the
  designated initialisers feature of C.  This I believe makes the macro
  more robust.

  Plus since I was changing BFD_FAKE_SECTIONS it seemed sensible to make
  a similar change to the GLOBAL_SYM_INIT macro which does a similar
  thing for static symbol declarations.

  Any thoughts or concerns ?

Cheers
  Nick
  

Patch

diff --git a/bfd/syms.c b/bfd/syms.c
index c43ee2da00e..f48f7e66d5c 100644
--- a/bfd/syms.c
+++ b/bfd/syms.c
@@ -337,12 +337,12 @@  EXTERNAL
 .typedef struct _symbol_info
 .{
 .  symvalue value;
-.  char type;
 .  const char *name;		{* Symbol name.  *}
+.  const char *stab_name;	{* String for stab type.  *}
 .  unsigned char stab_type;	{* Stab type.  *}
 .  char stab_other;		{* Stab other.  *}
 .  short stab_desc;		{* Stab desc.  *}
-.  const char *stab_name;	{* String for stab type.  *}
+.  char type;
 .} symbol_info;
 .
 .{* An empty string that will not match the address of any other
diff --git a/bfd/section.c b/bfd/section.c
index a958f71055a..457486b0f89 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -381,71 +381,6 @@  CODE_FRAGMENT
 .
 .  {*  End of section flags.  *}
 .
-.  {* Some internal packed boolean fields.  *}
-.
-.  {* See the vma field.  *}
-.  unsigned int user_set_vma : 1;
-.
-.  {* A mark flag used by some of the linker backends.  *}
-.  unsigned int linker_mark : 1;
-.
-.  {* Another mark flag used by some of the linker backends.  Set for
-.     output sections that have an input section.  *}
-.  unsigned int linker_has_input : 1;
-.
-.  {* Mark flag used by some linker backends for garbage collection.  *}
-.  unsigned int gc_mark : 1;
-.
-.  {* Section compression status.  *}
-.  unsigned int compress_status : 2;
-.#define COMPRESS_SECTION_NONE    0
-.#define COMPRESS_SECTION_DONE    1
-.#define DECOMPRESS_SECTION_ZLIB  2
-.#define DECOMPRESS_SECTION_ZSTD  3
-.
-.  {* The following flags are used by the ELF linker. *}
-.
-.  {* Mark sections which have been allocated to segments.  *}
-.  unsigned int segment_mark : 1;
-.
-.  {* Type of sec_info information.  *}
-.  unsigned int sec_info_type:3;
-.#define SEC_INFO_TYPE_NONE      0
-.#define SEC_INFO_TYPE_STABS     1
-.#define SEC_INFO_TYPE_MERGE     2
-.#define SEC_INFO_TYPE_EH_FRAME  3
-.#define SEC_INFO_TYPE_JUST_SYMS 4
-.#define SEC_INFO_TYPE_TARGET    5
-.#define SEC_INFO_TYPE_EH_FRAME_ENTRY 6
-.#define SEC_INFO_TYPE_SFRAME  7
-.
-.  {* Nonzero if this section uses RELA relocations, rather than REL.  *}
-.  unsigned int use_rela_p:1;
-.
-.  {* Nonzero if section contents are mmapped.  *}
-.  unsigned int mmapped_p:1;
-.
-.  {* Nonzero if section contents should not be freed.  *}
-.  unsigned int alloced:1;
-.
-.  {* Indicate that the section contains branch veneers.  This is used when
-.     support for non-contiguous memory regions is enabled.  The veneers have
-.     to be allocated to the same memory region as the code they are refered
-.     by, i.e. they cannot be moved to a subsequent memory region.  *}
-.  unsigned int veneer : 1;
-.
-.  {* Bits used by various backends.  The generic code doesn't touch
-.     these fields.  *}
-.
-.  unsigned int sec_flg0:1;
-.  unsigned int sec_flg1:1;
-.  unsigned int sec_flg2:1;
-.  unsigned int sec_flg3:1;
-.  unsigned int sec_flg4:1;
-.  unsigned int sec_flg5:1;
-.
-.  {* End of internal packed boolean fields.  *}
-.
 .  {*  The virtual memory address of the section - where it will be
 .      at run time.  The symbols are relocated against this.  The
 .      user_set_vma flag is maintained by bfd; if it's not set, the
@@ -540,9 +475,6 @@  CODE_FRAGMENT
 .     linenumbers are written out.  *}
 .  file_ptr moving_line_filepos;
 .
-.  {* What the section number is in the target world.  *}
-.  int target_index;
-.
 .  void *used_by_bfd;
 .
 .  {* If this is a constructor section then here is a list of the
@@ -578,6 +510,74 @@  CODE_FRAGMENT
 .  {* Explicitly specified section type, if non-zero.  *}
 .  unsigned int type;
 .
+.  {* What the section number is in the target world.  *}
+.  int target_index;
+.
+.  {* Some internal packed boolean fields.  *}
+.
+.  {* See the vma field.  *}
+.  unsigned int user_set_vma : 1;
+.
+.  {* A mark flag used by some of the linker backends.  *}
+.  unsigned int linker_mark : 1;
+.
+.  {* Another mark flag used by some of the linker backends.  Set for
+.     output sections that have an input section.  *}
+.  unsigned int linker_has_input : 1;
+.
+.  {* Mark flag used by some linker backends for garbage collection.  *}
+.  unsigned int gc_mark : 1;
+.
+.  {* Section compression status.  *}
+.  unsigned int compress_status : 2;
+.#define COMPRESS_SECTION_NONE    0
+.#define COMPRESS_SECTION_DONE    1
+.#define DECOMPRESS_SECTION_ZLIB  2
+.#define DECOMPRESS_SECTION_ZSTD  3
+.
+.  {* The following flags are used by the ELF linker. *}
+.
+.  {* Mark sections which have been allocated to segments.  *}
+.  unsigned int segment_mark : 1;
+.
+.  {* Type of sec_info information.  *}
+.  unsigned int sec_info_type:3;
+.#define SEC_INFO_TYPE_NONE      0
+.#define SEC_INFO_TYPE_STABS     1
+.#define SEC_INFO_TYPE_MERGE     2
+.#define SEC_INFO_TYPE_EH_FRAME  3
+.#define SEC_INFO_TYPE_JUST_SYMS 4
+.#define SEC_INFO_TYPE_TARGET    5
+.#define SEC_INFO_TYPE_EH_FRAME_ENTRY 6
+.#define SEC_INFO_TYPE_SFRAME  7
+.
+.  {* Nonzero if this section uses RELA relocations, rather than REL.  *}
+.  unsigned int use_rela_p:1;
+.
+.  {* Nonzero if section contents are mmapped.  *}
+.  unsigned int mmapped_p:1;
+.
+.  {* Nonzero if section contents should not be freed.  *}
+.  unsigned int alloced:1;
+.
+.  {* Indicate that the section contains branch veneers.  This is used when
+.     support for non-contiguous memory regions is enabled.  The veneers have
+.     to be allocated to the same memory region as the code they are refered
+.     by, i.e. they cannot be moved to a subsequent memory region.  *}
+.  unsigned int veneer : 1;
+.
+.  {* Bits used by various backends.  The generic code doesn't touch
+.     these fields.  *}
+.
+.  unsigned int sec_flg0:1;
+.  unsigned int sec_flg1:1;
+.  unsigned int sec_flg2:1;
+.  unsigned int sec_flg3:1;
+.  unsigned int sec_flg4:1;
+.  unsigned int sec_flg5:1;
+.
+.  {* End of internal packed boolean fields.  *}
+.
 .} asection;
 .
 
@@ -723,51 +723,20 @@  EXTERNAL
 .}
 .
 INTERNAL
-.#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS)			\
-.  {* name, next, prev, id,  section_id, index, flags, user_set_vma, *}	\
-.  {  NAME, NULL, NULL, IDX, 0,          0,     FLAGS, 0,		\
-.									\
-.  {* linker_mark, linker_has_input, gc_mark, decompress_status,     *}	\
-.     0,           0,                1,       0,			\
-.									\
-.  {* segment_mark, sec_info_type, use_rela_p, mmapped_p, alloced,   *}	\
-.     0,            0,             0,          0,         0,		\
-.									\
-.  {* veneer,                                                        *}	\
-.     0,								\
-.									\
-.  {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5,    *}	\
-.     0,        0,        0,        0,        0,        0,		\
-.									\
-.  {* vma, lma, size, rawsize, compressed_size,                      *}	\
-.     0,   0,   0,    0,       0,					\
-.									\
-.  {* output_offset, output_section, relocation, orelocation,        *}	\
-.     0,             &SEC,           NULL,       NULL,			\
-.									\
-.  {* reloc_count, alignment_power, filepos, rel_filepos,            *}	\
-.     0,           0,               0,       0,				\
-.									\
-.  {* line_filepos, userdata, contents, lineno, lineno_count,        *}	\
-.     0,            NULL,     NULL,     NULL,   0,			\
-.									\
-.  {* entsize, kept_section, moving_line_filepos,                    *}	\
-.     0,       NULL,         0,						\
-.									\
-.  {* target_index, used_by_bfd, constructor_chain, owner,           *}	\
-.     0,            NULL,        NULL,              NULL,		\
-.									\
-.  {* symbol,                                                        *}	\
-.     (struct bfd_symbol *) SYM,					\
-.									\
-.  {* map_head, map_tail, already_assigned, sec_info, type           *}	\
-.     { NULL }, { NULL }, NULL,             NULL,     0			\
-.									\
+.#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS)	\
+.  { .name = NAME,					\
+.    .id = IDX,						\
+.    .flags = FLAGS,					\
+.    .gc_mark = 1,					\
+.    .output_section = &SEC,				\
+.    .symbol = (struct bfd_symbol *) SYM		\
 .  }
 .
-.#define GLOBAL_SYM_INIT(NAME, SECTION)					\
-.  {* the_bfd, name, value, attr,            section, udata  *}		\
-.  {  0,       NAME, 0,     BSF_SECTION_SYM, SECTION, { 0 } }
+.#define GLOBAL_SYM_INIT(NAME, SECTION)			\
+.  { .name = NAME,					\
+.    .section = SECTION,				\
+.    .flags = BSF_SECTION_SYM				\
+.  }
 .
 */
 
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 0b934005f9d..38021d51c16 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -657,71 +657,6 @@  typedef struct bfd_section
 
   /*  End of section flags.  */
 
-  /* Some internal packed boolean fields.  */
-
-  /* See the vma field.  */
-  unsigned int user_set_vma : 1;
-
-  /* A mark flag used by some of the linker backends.  */
-  unsigned int linker_mark : 1;
-
-  /* Another mark flag used by some of the linker backends.  Set for
-     output sections that have an input section.  */
-  unsigned int linker_has_input : 1;
-
-  /* Mark flag used by some linker backends for garbage collection.  */
-  unsigned int gc_mark : 1;
-
-  /* Section compression status.  */
-  unsigned int compress_status : 2;
-#define COMPRESS_SECTION_NONE    0
-#define COMPRESS_SECTION_DONE    1
-#define DECOMPRESS_SECTION_ZLIB  2
-#define DECOMPRESS_SECTION_ZSTD  3
-
-  /* The following flags are used by the ELF linker. */
-
-  /* Mark sections which have been allocated to segments.  */
-  unsigned int segment_mark : 1;
-
-  /* Type of sec_info information.  */
-  unsigned int sec_info_type:3;
-#define SEC_INFO_TYPE_NONE      0
-#define SEC_INFO_TYPE_STABS     1
-#define SEC_INFO_TYPE_MERGE     2
-#define SEC_INFO_TYPE_EH_FRAME  3
-#define SEC_INFO_TYPE_JUST_SYMS 4
-#define SEC_INFO_TYPE_TARGET    5
-#define SEC_INFO_TYPE_EH_FRAME_ENTRY 6
-#define SEC_INFO_TYPE_SFRAME  7
-
-  /* Nonzero if this section uses RELA relocations, rather than REL.  */
-  unsigned int use_rela_p:1;
-
-  /* Nonzero if section contents are mmapped.  */
-  unsigned int mmapped_p:1;
-
-  /* Nonzero if section contents should not be freed.  */
-  unsigned int alloced:1;
-
-  /* Indicate that the section contains branch veneers.  This is used when
-     support for non-contiguous memory regions is enabled.  The veneers have
-     to be allocated to the same memory region as the code they are refered
-     by, i.e. they cannot be moved to a subsequent memory region.  */
-  unsigned int veneer : 1;
-
-  /* Bits used by various backends.  The generic code doesn't touch
-     these fields.  */
-
-  unsigned int sec_flg0:1;
-  unsigned int sec_flg1:1;
-  unsigned int sec_flg2:1;
-  unsigned int sec_flg3:1;
-  unsigned int sec_flg4:1;
-  unsigned int sec_flg5:1;
-
-  /* End of internal packed boolean fields.  */
-
   /*  The virtual memory address of the section - where it will be
       at run time.  The symbols are relocated against this.  The
       user_set_vma flag is maintained by bfd; if it's not set, the
@@ -816,9 +751,6 @@  typedef struct bfd_section
      linenumbers are written out.  */
   file_ptr moving_line_filepos;
 
-  /* What the section number is in the target world.  */
-  int target_index;
-
   void *used_by_bfd;
 
   /* If this is a constructor section then here is a list of the
@@ -854,6 +786,74 @@  typedef struct bfd_section
   /* Explicitly specified section type, if non-zero.  */
   unsigned int type;
 
+  /* What the section number is in the target world.  */
+  int target_index;
+
+  /* Some internal packed boolean fields.  */
+
+  /* See the vma field.  */
+  unsigned int user_set_vma : 1;
+
+  /* A mark flag used by some of the linker backends.  */
+  unsigned int linker_mark : 1;
+
+  /* Another mark flag used by some of the linker backends.  Set for
+     output sections that have an input section.  */
+  unsigned int linker_has_input : 1;
+
+  /* Mark flag used by some linker backends for garbage collection.  */
+  unsigned int gc_mark : 1;
+
+  /* Section compression status.  */
+  unsigned int compress_status : 2;
+#define COMPRESS_SECTION_NONE    0
+#define COMPRESS_SECTION_DONE    1
+#define DECOMPRESS_SECTION_ZLIB  2
+#define DECOMPRESS_SECTION_ZSTD  3
+
+  /* The following flags are used by the ELF linker. */
+
+  /* Mark sections which have been allocated to segments.  */
+  unsigned int segment_mark : 1;
+
+  /* Type of sec_info information.  */
+  unsigned int sec_info_type:3;
+#define SEC_INFO_TYPE_NONE      0
+#define SEC_INFO_TYPE_STABS     1
+#define SEC_INFO_TYPE_MERGE     2
+#define SEC_INFO_TYPE_EH_FRAME  3
+#define SEC_INFO_TYPE_JUST_SYMS 4
+#define SEC_INFO_TYPE_TARGET    5
+#define SEC_INFO_TYPE_EH_FRAME_ENTRY 6
+#define SEC_INFO_TYPE_SFRAME  7
+
+  /* Nonzero if this section uses RELA relocations, rather than REL.  */
+  unsigned int use_rela_p:1;
+
+  /* Nonzero if section contents are mmapped.  */
+  unsigned int mmapped_p:1;
+
+  /* Nonzero if section contents should not be freed.  */
+  unsigned int alloced:1;
+
+  /* Indicate that the section contains branch veneers.  This is used when
+     support for non-contiguous memory regions is enabled.  The veneers have
+     to be allocated to the same memory region as the code they are refered
+     by, i.e. they cannot be moved to a subsequent memory region.  */
+  unsigned int veneer : 1;
+
+  /* Bits used by various backends.  The generic code doesn't touch
+     these fields.  */
+
+  unsigned int sec_flg0:1;
+  unsigned int sec_flg1:1;
+  unsigned int sec_flg2:1;
+  unsigned int sec_flg3:1;
+  unsigned int sec_flg4:1;
+  unsigned int sec_flg5:1;
+
+  /* End of internal packed boolean fields.  */
+
 } asection;
 
 static inline const char *
@@ -1226,12 +1226,12 @@  typedef enum bfd_print_symbol
 typedef struct _symbol_info
 {
   symvalue value;
-  char type;
   const char *name;            /* Symbol name.  */
+  const char *stab_name;       /* String for stab type.  */
   unsigned char stab_type;     /* Stab type.  */
   char stab_other;             /* Stab other.  */
   short stab_desc;             /* Stab desc.  */
-  const char *stab_name;       /* String for stab type.  */
+  char type;
 } symbol_info;
 
 /* An empty string that will not match the address of any other
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index fdf3588e18e..1829f76e642 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3548,51 +3548,20 @@  void _bfd_link_reloc_status_error
     bfd_reloc_status_type r) ATTRIBUTE_HIDDEN;
 
 /* Extracted from section.c.  */
-#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS)                   \
-  /* name, next, prev, id,  section_id, index, flags, user_set_vma, */ \
-  {  NAME, NULL, NULL, IDX, 0,          0,     FLAGS, 0,               \
-								       \
-  /* linker_mark, linker_has_input, gc_mark, decompress_status,     */ \
-     0,           0,                1,       0,                        \
-								       \
-  /* segment_mark, sec_info_type, use_rela_p, mmapped_p, alloced,   */ \
-     0,            0,             0,          0,         0,            \
-								       \
-  /* veneer,                                                        */ \
-     0,                                                                \
-								       \
-  /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5,    */ \
-     0,        0,        0,        0,        0,        0,              \
-								       \
-  /* vma, lma, size, rawsize, compressed_size,                      */ \
-     0,   0,   0,    0,       0,                                       \
-								       \
-  /* output_offset, output_section, relocation, orelocation,        */ \
-     0,             &SEC,           NULL,       NULL,                  \
-								       \
-  /* reloc_count, alignment_power, filepos, rel_filepos,            */ \
-     0,           0,               0,       0,                         \
-								       \
-  /* line_filepos, userdata, contents, lineno, lineno_count,        */ \
-     0,            NULL,     NULL,     NULL,   0,                      \
-								       \
-  /* entsize, kept_section, moving_line_filepos,                    */ \
-     0,       NULL,         0,                                         \
-								       \
-  /* target_index, used_by_bfd, constructor_chain, owner,           */ \
-     0,            NULL,        NULL,              NULL,               \
-								       \
-  /* symbol,                                                        */ \
-     (struct bfd_symbol *) SYM,                                        \
-								       \
-  /* map_head, map_tail, already_assigned, sec_info, type           */ \
-     { NULL }, { NULL }, NULL,             NULL,     0                 \
-								       \
+#define BFD_FAKE_SECTION(SEC, SYM, NAME, IDX, FLAGS)   \
+  { .name = NAME,                                      \
+    .id = IDX,                                         \
+    .flags = FLAGS,                                    \
+    .gc_mark = 1,                                      \
+    .output_section = &SEC,                            \
+    .symbol = (struct bfd_symbol *) SYM                \
   }
 
-#define GLOBAL_SYM_INIT(NAME, SECTION)                                 \
-  /* the_bfd, name, value, attr,            section, udata  */         \
-  {  0,       NAME, 0,     BSF_SECTION_SYM, SECTION, { 0 } }
+#define GLOBAL_SYM_INIT(NAME, SECTION)                 \
+  { .name = NAME,                                      \
+    .section = SECTION,                                \
+    .flags = BSF_SECTION_SYM                           \
+  }
 
 /* Extracted from stabs.c.  */
 bool _bfd_link_section_stabs