diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2003-07-25 14:35:56 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2003-07-25 14:35:56 +0000 |
commit | 2f89ff8d8ead0e6eb034d7c26470be4eac7c3185 (patch) | |
tree | deecbf5e1012acc2b9492ad093cde8236a3404e6 /bfd/elf.c | |
parent | 20650579793e339d3438ee509c464a253d7ef079 (diff) | |
download | gdb-2f89ff8d8ead0e6eb034d7c26470be4eac7c3185.zip gdb-2f89ff8d8ead0e6eb034d7c26470be4eac7c3185.tar.gz gdb-2f89ff8d8ead0e6eb034d7c26470be4eac7c3185.tar.bz2 |
bfd/
2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
* elf-bfd.h (bfd_elf_special_section): New.
(elf_backend_data): Add special_sections, a pointer to
bfd_elf_special_section.
(elf_section_type). New.
(elf_section_flags): New.
(_bfd_elf_get_sec_type_attr): New.
* elf.c (_bfd_elf_make_section_from_shdr): Always use the
real section type/flags.
(special_sections): New.
(get_special_section): New.
(_bfd_elf_get_sec_type_attr): New.
(_bfd_elf_new_section_hook): Check special_section to set
elf_section_type and elf_section_flags.
(elf_fake_sections): Don't use section name to set ELF section
data.
* elf32-m32r.c (m32r_elf_special_sections): New.
(elf_backend_special_sections): Defined.
* elf32-m68hc11.c (elf32_m68hc11_special_sections): New.
(elf_backend_special_sections): Defined.
* elf32-mcore.c (mcore_elf_special_sections): New.
(elf_backend_special_sections): Defined.
* elf32-ppc.c (ppc_elf_special_sections): New.
(elf_backend_special_sections): Defined.
* elf32-sh64.c (sh64_elf_special_sections): New.
(elf_backend_special_sections): Defined.
* elf32-v850.c (v850_elf_special_sections): New.
(elf_backend_special_sections): Defined.
* elf32-xtensa.c (elf_xtensa_special_sections): New.
(elf_backend_special_sections): Defined.
* elf64-alpha.c (elf64_alpha_special_sections): New.
(elf_backend_special_sections): Defined.
* elf64-hppa.c (elf64_hppa_special_sections): New.
(elf_backend_special_sections): Defined.
* elf64-ppc.c (ppc64_elf_special_sections): New.
(elf_backend_special_sections): Defined.
* elf64-sh64.c (sh64_elf64_special_sections): New.
(elf_backend_special_sections): Defined.
* elfxx-ia64.c (elfNN_ia64_special_sections): New.
(elf_backend_special_sections): Defined.
* elfxx-mips.c (_bfd_mips_elf_special_sections): New.
* elfxx-mips.h (_bfd_mips_elf_special_sections): New.
(elf_backend_special_sections): Defined.
* elfxx-target.h (elf_backend_special_sections): New. Default
to NULL.
(elfNN_bed): Initialize special_sections.
* section.c (bfd_abs_section): Remove const.
(bfd_und_section): Likewise.
(bfd_com_section): Likewise.
(bfd_ind_section): Likewise.
gas/
2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
* config/obj-elf.c (special_sections): Removed.
(obj_elf_change_section): Call _bfd_elf_get_sec_type_attr. Set
elf_section_type and elf_section_flags.
(elf_frob_file): Set SHT_GROUP.
* config/obj-elf.h (obj_sec_set_private_data): New.
* config/tc-alpha.h (ELF_TC_SPECIAL_SECTIONS): Removed.
* config/tc-ia64.h: Likewise.
* config/tc-m32r.h: Likewise.
* config/tc-m68hc11.h: Likewise.
* config/tc-mcore.h: Likewise.
* config/tc-mips.h: Likewise.
* config/tc-ppc.h: Likewise.
* config/tc-sh64.h: Likewise.
* config/tc-v850.h: Likewise.
* config/tc-xtensa.h: Likewise.
* config/tc-v850.h (SHF_V850_GPREL): Removed.
(SHF_V850_EPREL): Likewise.
(SHF_V850_R0REL): Likewise.
* subsegs.c (subseg_get): Call obj_sec_set_private_data if it
is defined.
include/elf/
2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
* v850.h (SHF_V850_GPREL): New.
(SHF_V850_EPREL): Likewise.
(SHF_V850_R0REL): Likewise.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 256 |
1 files changed, 198 insertions, 58 deletions
@@ -741,6 +741,10 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) if (newsect == NULL) return FALSE; + /* Always use the real type/flags. */ + elf_section_type (newsect) = hdr->sh_type; + elf_section_flags (newsect) = hdr->sh_flags; + newsect->filepos = hdr->sh_offset; if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr) @@ -2139,12 +2143,145 @@ bfd_section_from_elf_index (abfd, index) return elf_elfsections (abfd)[index]->bfd_section; } +static struct bfd_elf_special_section const special_sections[] = +{ + { ".bss", 0, NULL, 0, + SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, + { ".comment", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".data", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".data1", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".debug", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".fini", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".init", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".line", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".rodata", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC }, + { ".rodata1", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC }, + { ".tbss", 0, NULL, 0, + SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, + { ".tdata", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS }, + { ".text", 0, NULL, 0, + SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, + { ".init_array", 0, NULL, 0, + SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE }, + { ".fini_array", 0, NULL, 0, + SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE }, + { ".preinit_array", 0, NULL, 0, + SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE }, + { ".debug_line", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".debug_info", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".debug_abbrev", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".debug_aranges", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".dynamic", 0, NULL, 0, + SHT_DYNAMIC, SHF_ALLOC }, + { ".dynstr", 0, NULL, 0, + SHT_STRTAB, SHF_ALLOC }, + { ".dynsym", 0, NULL, 0, + SHT_DYNSYM, SHF_ALLOC }, + { ".got", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".hash", 0, NULL, 0, + SHT_HASH, SHF_ALLOC }, + { ".interp", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".plt", 0, NULL, 0, + SHT_PROGBITS, 0 }, + { ".shstrtab", 0, NULL, 0, + SHT_STRTAB, 0 }, + { ".strtab", 0, NULL, 0, + SHT_STRTAB, 0 }, + { ".symtab", 0, NULL, 0, + SHT_SYMTAB, 0 }, + { ".gnu.version", 0, NULL, 0, + SHT_GNU_versym, 0 }, + { ".gnu.version_d", 0, NULL, 0, + SHT_GNU_verdef, 0 }, + { ".gnu.version_r", 0, NULL, 0, + SHT_GNU_verneed, 0 }, + { ".note", 5, NULL, 0, + SHT_NOTE, 0 }, + { ".rela", 5, NULL, 0, + SHT_RELA, 0 }, + { ".rel", 4, NULL, 0, + SHT_REL, 0 }, + { ".stab", 5, "str", 3, + SHT_STRTAB, 0 }, + { NULL, 0, NULL, 0, + 0, 0 } +}; + +static const struct bfd_elf_special_section * +get_special_section (const char *name, + const struct bfd_elf_special_section *special_sections, + unsigned int rela) +{ + int i; + + for (i = 0; special_sections[i].prefix != NULL; i++) + if (((special_sections[i].prefix_length + && strncmp (name, special_sections[i].prefix, + special_sections[i].prefix_length) == 0 + && (! special_sections[i].suffix_length + || strcmp ((name + strlen (name) + - special_sections[i].suffix_length), + special_sections[i].suffix) == 0)) + || strcmp (name, special_sections[i].prefix) == 0) + && (rela || special_sections[i].type != SHT_RELA)) + return &special_sections[i]; + + return NULL; +} + +bfd_boolean +_bfd_elf_get_sec_type_attr (bfd *abfd, const char *name, + int *type, int *attr) +{ + bfd_boolean found = FALSE; + struct elf_backend_data *bed = get_elf_backend_data (abfd); + + /* See if this is one of the special sections. */ + if (name) + { + const struct bfd_elf_special_section *ssect = NULL; + unsigned int rela = get_elf_backend_data (abfd)->default_use_rela_p; + + if (bed->special_sections) + ssect = get_special_section (name, bed->special_sections, rela); + + if (! ssect) + ssect = get_special_section (name, special_sections, rela); + + if (ssect) + { + *type = ssect->type; + *attr = ssect->attributes; + found = TRUE; + } + } + + return found; +} + bfd_boolean _bfd_elf_new_section_hook (abfd, sec) bfd *abfd; asection *sec; { struct bfd_elf_section_data *sdata; + int type, attr; sdata = (struct bfd_elf_section_data *) sec->used_by_bfd; if (sdata == NULL) @@ -2156,6 +2293,19 @@ _bfd_elf_new_section_hook (abfd, sec) sec->used_by_bfd = (PTR) sdata; } + if ((sec->flags & SEC_ALLOC) != 0 + && (((sec->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) + || (sec->flags & SEC_NEVER_LOAD) != 0)) + elf_section_type (sec) = SHT_NOBITS; + else + elf_section_type (sec) = SHT_PROGBITS; + if (sec->name && _bfd_elf_get_sec_type_attr (abfd, sec->name, + &type, &attr)) + { + elf_section_type (sec) = type; + elf_section_flags (sec) = attr; + } + /* Indicate whether or not this section should use RELA relocations. */ sec->use_rela_p = get_elf_backend_data (abfd)->default_use_rela_p; @@ -2394,55 +2544,52 @@ elf_fake_sections (abfd, asect, failedptrarg) this_hdr->bfd_section = asect; this_hdr->contents = NULL; - /* FIXME: This should not be based on section names. */ - if (strcmp (asect->name, ".dynstr") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if (strcmp (asect->name, ".hash") == 0) + switch (this_hdr->sh_type) { - this_hdr->sh_type = SHT_HASH; + default: + (*_bfd_error_handler) + (_("%s: Section `%s' has unknown type 0x%0x"), + bfd_get_filename (asect->owner), asect->name, + this_hdr->sh_type); + abort (); + break; + + case SHT_STRTAB: + case SHT_INIT_ARRAY: + case SHT_FINI_ARRAY: + case SHT_PREINIT_ARRAY: + case SHT_NOTE: + case SHT_NOBITS: + case SHT_PROGBITS: + break; + + case SHT_HASH: this_hdr->sh_entsize = bed->s->sizeof_hash_entry; - } - else if (strcmp (asect->name, ".dynsym") == 0) - { - this_hdr->sh_type = SHT_DYNSYM; + break; + + case SHT_DYNSYM: this_hdr->sh_entsize = bed->s->sizeof_sym; - } - else if (strcmp (asect->name, ".dynamic") == 0) - { - this_hdr->sh_type = SHT_DYNAMIC; + break; + + case SHT_DYNAMIC: this_hdr->sh_entsize = bed->s->sizeof_dyn; - } - else if (strncmp (asect->name, ".rela", 5) == 0 - && get_elf_backend_data (abfd)->may_use_rela_p) - { - this_hdr->sh_type = SHT_RELA; - this_hdr->sh_entsize = bed->s->sizeof_rela; - } - else if (strncmp (asect->name, ".rel", 4) == 0 - && get_elf_backend_data (abfd)->may_use_rel_p) - { - this_hdr->sh_type = SHT_REL; - this_hdr->sh_entsize = bed->s->sizeof_rel; - } - else if (strcmp (asect->name, ".init_array") == 0) - this_hdr->sh_type = SHT_INIT_ARRAY; - else if (strcmp (asect->name, ".fini_array") == 0) - this_hdr->sh_type = SHT_FINI_ARRAY; - else if (strcmp (asect->name, ".preinit_array") == 0) - this_hdr->sh_type = SHT_PREINIT_ARRAY; - else if (strncmp (asect->name, ".note", 5) == 0) - this_hdr->sh_type = SHT_NOTE; - else if (strncmp (asect->name, ".stab", 5) == 0 - && strcmp (asect->name + strlen (asect->name) - 3, "str") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if (strcmp (asect->name, ".gnu.version") == 0) - { - this_hdr->sh_type = SHT_GNU_versym; + break; + + case SHT_RELA: + if (get_elf_backend_data (abfd)->may_use_rela_p) + this_hdr->sh_entsize = bed->s->sizeof_rela; + break; + + case SHT_REL: + if (get_elf_backend_data (abfd)->may_use_rel_p) + this_hdr->sh_entsize = bed->s->sizeof_rel; + break; + + case SHT_GNU_versym: this_hdr->sh_entsize = sizeof (Elf_External_Versym); - } - else if (strcmp (asect->name, ".gnu.version_d") == 0) - { - this_hdr->sh_type = SHT_GNU_verdef; + break; + + case SHT_GNU_verdef: this_hdr->sh_entsize = 0; /* objcopy or strip will copy over sh_info, but may not set cverdefs. The linker will set cverdefs, but sh_info will be @@ -2452,10 +2599,9 @@ elf_fake_sections (abfd, asect, failedptrarg) else BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0 || this_hdr->sh_info == elf_tdata (abfd)->cverdefs); - } - else if (strcmp (asect->name, ".gnu.version_r") == 0) - { - this_hdr->sh_type = SHT_GNU_verneed; + break; + + case SHT_GNU_verneed: this_hdr->sh_entsize = 0; /* objcopy or strip will copy over sh_info, but may not set cverrefs. The linker will set cverrefs, but sh_info will be @@ -2465,18 +2611,12 @@ elf_fake_sections (abfd, asect, failedptrarg) else BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0 || this_hdr->sh_info == elf_tdata (abfd)->cverrefs); - } - else if ((asect->flags & SEC_GROUP) != 0) - { - this_hdr->sh_type = SHT_GROUP; + break; + + case SHT_GROUP: this_hdr->sh_entsize = 4; + break; } - else if ((asect->flags & SEC_ALLOC) != 0 - && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - || (asect->flags & SEC_NEVER_LOAD) != 0)) - this_hdr->sh_type = SHT_NOBITS; - else - this_hdr->sh_type = SHT_PROGBITS; if ((asect->flags & SEC_ALLOC) != 0) this_hdr->sh_flags |= SHF_ALLOC; |