This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: tidy elf_obj_tdata
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Cc: gdb-patches at sourceware dot org
- Date: Thu, 21 Feb 2013 15:16:23 +1030
- Subject: Re: tidy elf_obj_tdata
- References: <20130221022948.GD3080@bubble.grove.modra.org> <20130221030305.GE3080@bubble.grove.modra.org>
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