From c03551323c0425db9b677ac2618e43854ac56064 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 21 Feb 2013 04:35:22 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 18 +++++ bfd/elf-bfd.h | 162 ++++++++++++++++++++++-------------------- bfd/elf.c | 22 +++--- gdb/ChangeLog | 4 ++ gdb/elfread.c | 5 +- ld/ChangeLog | 5 ++ ld/emultempl/elf32.em | 21 +++--- 7 files changed, 135 insertions(+), 102 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8952bcb68fc..72d912769ad 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2013-02-21 Alan Modra + + * 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 * elf-bfd.h (struct core_elf_obj_tdata): New. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index ac4da71060a..72be700a125 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 09cd93a6fa0..e0487c2c915 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/gdb/ChangeLog b/gdb/ChangeLog index f72353b9726..a0c78441a76 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2013-02-21 Alan Modra + + * elfread.c (build_id_bfd_get): Adjust for elf_tdata changes. + 2013-02-20 Siva Chandra Reddy Add a new method 'disassemble' to gdb.Architecture class. diff --git a/gdb/elfread.c b/gdb/elfread.c index 85e408ffe0c..4520209b61e 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -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. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 429e4dabc50..95d466daea7 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2013-02-21 Alan Modra + + * emultempl/elf32.em (write_build_id, setup_build_id): Adjust + for elf_tdata changes. + 2013-02-21 Alan Modra * emultempl/elf-generic.em: Use newly defined elf_obj_tdata diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index ad5d98c30e7..32662e5fb6b 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," -- 2.30.2