summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog18
-rw-r--r--bfd/elf-bfd.h162
-rw-r--r--bfd/elf.c22
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/emultempl/elf32.em21
5 files changed, 129 insertions, 99 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 8952bcb68f..72d912769a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,23 @@
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.
(struct elf_obj_tdata): Delete core_signal, core_pid, core_lwpid,
core_program, and core_command. Add "core".
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index ac4da71060..72be700a12 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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) \
diff --git a/bfd/elf.c b/bfd/elf.c
index 09cd93a6fa..e0487c2c91 100644
--- 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;
}
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 429e4dabc5..95d466daea 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,10 @@
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
accessor macros.
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index ad5d98c30e..32662e5fb6 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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,"