bfd/
authorAlan Modra <amodra@gmail.com>
Thu, 21 Feb 2013 04:35:22 +0000 (04:35 +0000)
committerAlan Modra <amodra@gmail.com>
Thu, 21 Feb 2013 04:35:22 +0000 (04:35 +0000)
* 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.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
gdb/ChangeLog
gdb/elfread.c
ld/ChangeLog
ld/emultempl/elf32.em

index 8952bcb68fcfbe9cb62791ac892678d47ffb9f26..72d912769ad1dd21bda007c4f1af09815898c326 100644 (file)
@@ -1,3 +1,21 @@
+2013-02-21  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2013-02-21  Alan Modra  <amodra@gmail.com>
 
        * elf-bfd.h (struct core_elf_obj_tdata): New.
index ac4da71060ad5b014a10607d9f6b377c293367e3..72be700a12518a0b72c124cb92397a81050ec40f 100644 (file)
@@ -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 09cd93a6fa09c814d84db69f72282c93229a7792..e0487c2c915235cc9e5788a2d4a7cb1f8c5a4706 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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 *abfd)
     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_Internal_Note *note)
     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 f72353b97260f22aba9b399d71da41ab756280a3..a0c78441a765e48e36edc8637039887037f2cc8d 100644 (file)
@@ -1,3 +1,7 @@
+2013-02-21  Alan Modra  <amodra@gmail.com>
+
+       * elfread.c (build_id_bfd_get): Adjust for elf_tdata changes.
+
 2013-02-20  Siva Chandra Reddy  <sivachandra@google.com>
 
        Add a new method 'disassemble' to gdb.Architecture class.
index 85e408ffe0cfd3a76a60a7fb299b8b0fd8079d54..4520209b61ea2e523972a902ffb57ef6b77a2c86 100644 (file)
@@ -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 429e4dabc50836bd6c9315d7e9ef67efe0c31cef..95d466daea70ed257da65b3d20480767c3099cce 100644 (file)
@@ -1,3 +1,8 @@
+2013-02-21  Alan Modra  <amodra@gmail.com>
+
+       * emultempl/elf32.em (write_build_id, setup_build_id): Adjust
+       for elf_tdata changes.
+
 2013-02-21  Alan Modra  <amodra@gmail.com>
 
        * emultempl/elf-generic.em: Use newly defined elf_obj_tdata
index ad5d98c30e73a9cf8ffb3e278d6934aae29fba1a..32662e5fb6be1ae0a4dda98d2025767645f72ead 100644 (file)
@@ -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,"