This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: tidy elf_obj_tdata


This moves fields only used for output bfds.  Not a huge saving, but
worth the indirection I think.  Committed, the gdb change under the
obvious rule.

bfd/
	* elf-bfd.h (struct elf_build_id): Extracted from..
	(struct elf_build_id_info): ..here.  Delete.
	(struct output_elf_obj_tdata): New, extracted from..
	(struct elf_obj_tdata): ..here.  Reorganize for better packing.
	Add "o" field.
	(elf_program_header_size): Reference tdata->o.
	(elf_seg_map, elf_next_file_pos, elf_eh_frame_hdr, elf_linker,
	elf_stack_flags, elf_shstrtab, elf_strtab_sec, elf_shstrtab_sec,
	elf_section_syms, elf_num_section_syms, elf_flags_init): Likewise.
	* elf.c (bfd_elf_allocate_object): Allocate output_elf_obj_tdata
	when opening bfd in any mode that might write.
	(_bfd_elf_write_object_contents): Use build_id field in
	output_elf_obj_tdata.
	(_bfd_elf_close_and_cleanup): Tweak elf_shstrtab test.
	(elfobj_grok_gnu_build_id): Adjust for elf_tdata changes.
gdb/
	* elfread.c (build_id_bfd_get): Adjust for elf_tdata changes.
ld/
	* emultempl/elf32.em (write_build_id, setup_build_id): Adjust
	for elf_tdata changes.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.364
diff -u -p -r1.364 elf-bfd.h
--- bfd/elf-bfd.h	21 Feb 2013 03:02:28 -0000	1.364
+++ bfd/elf-bfd.h	21 Feb 2013 03:09:28 -0000
@@ -1512,26 +1512,11 @@ struct sdt_note
   bfd_byte data[1];
 };
 
-/* NT_GNU_BUILD_ID note type info.  */
-struct elf_build_id_info
+/* NT_GNU_BUILD_ID note type info for input BFDs.  */
+struct elf_build_id
 {
-  union
-  {
-    /* Used on output bfd by linker.  */
-    struct elf_build_id_out
-    {
-      size_t zero;       /* Always zero */
-      bfd_boolean (*after_write_object_contents) (bfd *);
-      const char *style;
-      asection *sec;
-    } o;
-    /* Used for input bfd.  */
-    struct elf_build_id
-    {
-      size_t size;       /* Always non-zero */
-      bfd_byte data[1];
-    } i;
-  } u;
+  size_t size;
+  bfd_byte data[1];
 };
 
 /* tdata information grabbed from an elf core file.  */
@@ -1544,6 +1529,47 @@ struct core_elf_obj_tdata
   char* command;
 };
 
+/* Extra tdata information held for output ELF BFDs.  */
+struct output_elf_obj_tdata
+{
+  struct elf_segment_map *seg_map;
+  struct elf_strtab_hash *strtab_ptr;
+
+  /* STT_SECTION symbols for each section */
+  asymbol **section_syms;
+
+  /* Used to determine if PT_GNU_EH_FRAME segment header should be
+     created.  */
+  asection *eh_frame_hdr;
+
+  /* NT_GNU_BUILD_ID note type info.  */
+  struct
+  {
+    bfd_boolean (*after_write_object_contents) (bfd *);
+    const char *style;
+    asection *sec;
+  } build_id;
+
+  /* Records the result of `get_program_header_size'.  */
+  bfd_size_type program_header_size;
+
+  /* Used when laying out sections.  */
+  file_ptr next_file_pos;
+
+  int num_section_syms;
+  unsigned int shstrtab_section, strtab_section;
+
+  /* Segment flags for the PT_GNU_STACK segment.  */
+  unsigned int stack_flags;
+
+  /* This is set to TRUE if the object was created by the backend
+     linker.  */
+  bfd_boolean linker;
+
+  /* Used to determine if the e_flags field has been initialized */
+  bfd_boolean flags_init;
+};
+
 /* Some private data is stashed away for future use using the tdata pointer
    in the bfd structure.  */
 
@@ -1552,11 +1578,6 @@ struct elf_obj_tdata
   Elf_Internal_Ehdr elf_header[1];	/* Actual data, but ref like ptr */
   Elf_Internal_Shdr **elf_sect_ptr;
   Elf_Internal_Phdr *phdr;
-  struct elf_segment_map *seg_map;
-  struct elf_strtab_hash *strtab_ptr;
-  unsigned int num_elf_sections;	/* elf_sect_ptr size */
-  int num_section_syms;
-  asymbol **section_syms;		/* STT_SECTION symbols for each section */
   Elf_Internal_Shdr symtab_hdr;
   Elf_Internal_Shdr shstrtab_hdr;
   Elf_Internal_Shdr strtab_hdr;
@@ -1566,13 +1587,9 @@ struct elf_obj_tdata
   Elf_Internal_Shdr dynverref_hdr;
   Elf_Internal_Shdr dynverdef_hdr;
   Elf_Internal_Shdr symtab_shndx_hdr;
-  unsigned int symtab_section, shstrtab_section;
-  unsigned int strtab_section, dynsymtab_section;
-  unsigned int symtab_shndx_section;
-  unsigned int dynversym_section, dynverdef_section, dynverref_section;
-  file_ptr next_file_pos;
   bfd_vma gp;				/* The gp value */
   unsigned int gp_size;			/* The gp size */
+  unsigned int num_elf_sections;	/* elf_sect_ptr size */
 
   /* A mapping from external symbols to entries in the linker hash
      table, used when linking.  This is indexed by the symbol index
@@ -1603,9 +1620,6 @@ struct elf_obj_tdata
      are used by a dynamic object.  */
   const char *dt_audit;
 
-  /* Records the result of `get_program_header_size'.  */
-  bfd_size_type program_header_size;
-
   /* Used by find_nearest_line entry point.  */
   void *line_info;
 
@@ -1618,22 +1632,12 @@ struct elf_obj_tdata
   /* Stash away info for yet another find line/function variant.  */
   void *elf_find_function_cache;
 
-  /* Used to determine if PT_GNU_EH_FRAME segment header should be
-     created.  */
-  asection *eh_frame_hdr;
-
-  Elf_Internal_Shdr **group_sect_ptr;
-  int num_group;
-
   /* Number of symbol version definitions we are about to emit.  */
   unsigned int cverdefs;
 
   /* Number of symbol version references we are about to emit.  */
   unsigned int cverrefs;
 
-  /* Segment flags for the PT_GNU_STACK segment.  */
-  unsigned int stack_flags;
-
   /* Symbol version definitions in external objects.  */
   Elf_Internal_Verdef *verdef;
 
@@ -1643,25 +1647,6 @@ struct elf_obj_tdata
   /* A pointer to the .eh_frame section.  */
   asection *eh_frame_section;
 
-  /* Whether a dyanmic object was specified normally on the linker
-     command line, or was specified when --as-needed was in effect,
-     or was found via a DT_NEEDED entry.  */
-  enum dynamic_lib_link_class dyn_lib_class;
-
-  /* This is set to TRUE if the object was created by the backend
-     linker.  */
-  bfd_boolean linker;
-
-  /* Irix 5 often screws up the symbol table, sorting local symbols
-     after global symbols.  This flag is set if the symbol table in
-     this BFD appears to be screwed up.  If it is, we ignore the
-     sh_info field in the symbol table header, and always read all the
-     symbols.  */
-  bfd_boolean bad_symtab;
-
-  /* Used to determine if the e_flags field has been initialized */
-  bfd_boolean flags_init;
-
   /* Symbol buffer.  */
   void *symbuf;
 
@@ -1669,43 +1654,64 @@ struct elf_obj_tdata
   obj_attribute_list *other_obj_attributes[2];
 
   /* NT_GNU_BUILD_ID note type.  */
-  struct elf_build_id_info *build_id;
+  struct elf_build_id *build_id;
 
   /* Linked-list containing information about every Systemtap section
      found in the object file.  Each section corresponds to one entry
      in the list.  */
   struct sdt_note *sdt_note_head;
 
-  /* True if the bfd contains symbols that have the STT_GNU_IFUNC
-     symbol type or STB_GNU_UNIQUE binding.  Used to set the osabi
-     field in the ELF header structure.  */
-  bfd_boolean has_gnu_symbols;
+  Elf_Internal_Shdr **group_sect_ptr;
+  int num_group;
+
+  unsigned int symtab_section, symtab_shndx_section, dynsymtab_section;
+  unsigned int dynversym_section, dynverdef_section, dynverref_section;
 
   /* An identifier used to distinguish different target
      specific extensions to this structure.  */
   enum elf_target_id object_id;
 
+  /* Whether a dyanmic object was specified normally on the linker
+     command line, or was specified when --as-needed was in effect,
+     or was found via a DT_NEEDED entry.  */
+  enum dynamic_lib_link_class dyn_lib_class;
+
+  /* Irix 5 often screws up the symbol table, sorting local symbols
+     after global symbols.  This flag is set if the symbol table in
+     this BFD appears to be screwed up.  If it is, we ignore the
+     sh_info field in the symbol table header, and always read all the
+     symbols.  */
+  bfd_boolean bad_symtab;
+
+  /* True if the bfd contains symbols that have the STT_GNU_IFUNC
+     symbol type or STB_GNU_UNIQUE binding.  Used to set the osabi
+     field in the ELF header structure.  */
+  bfd_boolean has_gnu_symbols;
+
   /* Information grabbed from an elf core file.  */
   struct core_elf_obj_tdata *core;
+
+  /* More information held for output ELF BFDs.  */
+  struct output_elf_obj_tdata *o;
 };
 
 #define elf_tdata(bfd)		((bfd) -> tdata.elf_obj_data)
 
 #define elf_object_id(bfd)	(elf_tdata(bfd) -> object_id)
-#define elf_program_header_size(bfd) (elf_tdata(bfd) -> program_header_size)
+#define elf_program_header_size(bfd) (elf_tdata(bfd) -> o->program_header_size)
 #define elf_elfheader(bfd)	(elf_tdata(bfd) -> elf_header)
 #define elf_elfsections(bfd)	(elf_tdata(bfd) -> elf_sect_ptr)
 #define elf_numsections(bfd)	(elf_tdata(bfd) -> num_elf_sections)
-#define elf_seg_map(bfd)	(elf_tdata(bfd) -> seg_map)
-#define elf_next_file_pos(bfd)	(elf_tdata(bfd) -> next_file_pos)
-#define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> eh_frame_hdr)
-#define elf_linker(bfd)		(elf_tdata(bfd) -> linker)
-#define elf_stack_flags(bfd)	(elf_tdata(bfd) -> stack_flags)
-#define elf_shstrtab(bfd)	(elf_tdata(bfd) -> strtab_ptr)
+#define elf_seg_map(bfd)	(elf_tdata(bfd) -> o->seg_map)
+#define elf_next_file_pos(bfd)	(elf_tdata(bfd) -> o->next_file_pos)
+#define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> o->eh_frame_hdr)
+#define elf_linker(bfd)		(elf_tdata(bfd) -> o->linker)
+#define elf_stack_flags(bfd)	(elf_tdata(bfd) -> o->stack_flags)
+#define elf_shstrtab(bfd)	(elf_tdata(bfd) -> o->strtab_ptr)
 #define elf_onesymtab(bfd)	(elf_tdata(bfd) -> symtab_section)
 #define elf_symtab_shndx(bfd)	(elf_tdata(bfd) -> symtab_shndx_section)
-#define elf_strtab_sec(bfd)	(elf_tdata(bfd) -> strtab_section)
-#define elf_shstrtab_sec(bfd)	(elf_tdata(bfd) -> shstrtab_section)
+#define elf_strtab_sec(bfd)	(elf_tdata(bfd) -> o->strtab_section)
+#define elf_shstrtab_sec(bfd)	(elf_tdata(bfd) -> o->shstrtab_section)
 #define elf_symtab_hdr(bfd)	(elf_tdata(bfd) -> symtab_hdr)
 #define elf_dynsymtab(bfd)	(elf_tdata(bfd) -> dynsymtab_section)
 #define elf_dynversym(bfd)	(elf_tdata(bfd) -> dynversym_section)
@@ -1713,8 +1719,8 @@ struct elf_obj_tdata
 #define elf_dynverref(bfd)	(elf_tdata(bfd) -> dynverref_section)
 #define elf_eh_frame_section(bfd) \
 				(elf_tdata(bfd) -> eh_frame_section)
-#define elf_section_syms(bfd)	(elf_tdata(bfd) -> section_syms)
-#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms)
+#define elf_section_syms(bfd)	(elf_tdata(bfd) -> o->section_syms)
+#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> o->num_section_syms)
 #define core_prpsinfo(bfd)	(elf_tdata(bfd) -> prpsinfo)
 #define core_prstatus(bfd)	(elf_tdata(bfd) -> prstatus)
 #define elf_gp(bfd)		(elf_tdata(bfd) -> gp)
@@ -1727,7 +1733,7 @@ struct elf_obj_tdata
 #define elf_dt_audit(bfd)	(elf_tdata(bfd) -> dt_audit)
 #define elf_dyn_lib_class(bfd)	(elf_tdata(bfd) -> dyn_lib_class)
 #define elf_bad_symtab(bfd)	(elf_tdata(bfd) -> bad_symtab)
-#define elf_flags_init(bfd)	(elf_tdata(bfd) -> flags_init)
+#define elf_flags_init(bfd)	(elf_tdata(bfd) -> o->flags_init)
 #define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes)
 #define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes)
 #define elf_known_obj_attributes_proc(bfd) \
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.587
diff -u -p -r1.587 elf.c
--- bfd/elf.c	21 Feb 2013 03:02:28 -0000	1.587
+++ bfd/elf.c	21 Feb 2013 03:09:28 -0000
@@ -246,7 +246,14 @@ bfd_elf_allocate_object (bfd *abfd,
     return FALSE;
 
   elf_object_id (abfd) = object_id;
-  elf_program_header_size (abfd) = (bfd_size_type) -1;
+  if (abfd->direction != read_direction)
+    {
+      struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
+      if (o == NULL)
+	return FALSE;
+      elf_tdata (abfd)->o = o;
+      elf_program_header_size (abfd) = (bfd_size_type) -1;
+    }
   return TRUE;
 }
 
@@ -5333,9 +5340,8 @@ _bfd_elf_write_object_contents (bfd *abf
     return FALSE;
 
   /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0].  */
-  if (t->build_id != NULL
-      && t->build_id->u.o.zero == 0)
-    return (*t->build_id->u.o.after_write_object_contents) (abfd);
+  if (t->o->build_id.after_write_object_contents != NULL)
+    return (*t->o->build_id.after_write_object_contents) (abfd);
 
   return TRUE;
 }
@@ -7874,7 +7880,7 @@ _bfd_elf_close_and_cleanup (bfd *abfd)
   struct elf_obj_tdata *tdata = elf_tdata (abfd);
   if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
     {
-      if (elf_shstrtab (abfd) != NULL)
+      if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
 	_bfd_elf_strtab_free (elf_shstrtab (abfd));
       _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
     }
@@ -8697,12 +8703,12 @@ elfobj_grok_gnu_build_id (bfd *abfd, Elf
     return FALSE;
 
   t = elf_tdata (abfd);
-  t->build_id = bfd_alloc (abfd, sizeof (t->build_id->u.i) - 1 + note->descsz);
+  t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
   if (t->build_id == NULL)
     return FALSE;
 
-  t->build_id->u.i.size = note->descsz;
-  memcpy (t->build_id->u.i.data, note->descdata, note->descsz);
+  t->build_id->size = note->descsz;
+  memcpy (t->build_id->data, note->descdata, note->descsz);
 
   return TRUE;
 }
Index: gdb/elfread.c
===================================================================
RCS file: /cvs/src/src/gdb/elfread.c,v
retrieving revision 1.144
diff -u -p -r1.144 elfread.c
--- gdb/elfread.c	18 Feb 2013 23:50:30 -0000	1.144
+++ gdb/elfread.c	21 Feb 2013 03:09:35 -0000
@@ -1081,11 +1081,10 @@ build_id_bfd_get (bfd *abfd)
 {
   if (!bfd_check_format (abfd, bfd_object)
       || bfd_get_flavour (abfd) != bfd_target_elf_flavour
-      || elf_tdata (abfd)->build_id == NULL
-      || elf_tdata (abfd)->build_id->u.i.size == 0)
+      || elf_tdata (abfd)->build_id == NULL)
     return NULL;
 
-  return &elf_tdata (abfd)->build_id->u.i;
+  return elf_tdata (abfd)->build_id;
 }
 
 /* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value.  */
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.240
diff -u -p -r1.240 elf32.em
--- ld/emultempl/elf32.em	18 Feb 2013 23:50:32 -0000	1.240
+++ ld/emultempl/elf32.em	21 Feb 2013 03:09:36 -0000
@@ -960,8 +960,8 @@ write_build_id (bfd *abfd)
   Elf_External_Note *e_note;
   typedef void (*sum_fn) (const void *, size_t, void *);
 
-  style = t->build_id->u.o.style;
-  asec = t->build_id->u.o.sec;
+  style = t->o->build_id.style;
+  asec = t->o->build_id.sec;
   if (bfd_is_abs_section (asec->output_section))
     {
       einfo (_("%P: warning: .note.gnu.build-id section discarded,"
@@ -1068,17 +1068,12 @@ setup_build_id (bfd *ibfd)
   if (s != NULL && bfd_set_section_alignment (ibfd, s, 2))
     {
       struct elf_obj_tdata *t = elf_tdata (link_info.output_bfd);
-      t->build_id = bfd_alloc (link_info.output_bfd, sizeof (t->build_id->u.o));
-      if (t->build_id != NULL)
-	{
-	  t->build_id->u.o.zero = 0;
-	  t->build_id->u.o.after_write_object_contents = &write_build_id;
-	  t->build_id->u.o.style = emit_note_gnu_build_id;
-	  t->build_id->u.o.sec = s;
-	  elf_section_type (s) = SHT_NOTE;
-	  s->size = size;
-	  return TRUE;
-	}
+      t->o->build_id.after_write_object_contents = &write_build_id;
+      t->o->build_id.style = emit_note_gnu_build_id;
+      t->o->build_id.sec = s;
+      elf_section_type (s) = SHT_NOTE;
+      s->size = size;
+      return TRUE;
     }
 
   einfo ("%P: warning: Cannot create .note.gnu.build-id section,"

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]