X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf64-hppa.c;h=fbd64584d1db6b2cc532919ddab0531f96b1503a;hb=d4bb5350967d01abe04e646993575ccce888f809;hp=869f7ed7072dc5988f1b3c91dc0965995236e561;hpb=336549c1f5f607f216a31f10511566f7939e0287;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 869f7ed707..fbd64584d1 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "alloca-conf.h" #include "bfd.h" @@ -184,9 +184,6 @@ static const char *get_dyn_name static bfd_boolean elf64_hppa_object_p PARAMS ((bfd *)); -static bfd_boolean elf64_hppa_section_from_shdr - PARAMS ((bfd *, Elf_Internal_Shdr *, const char *)); - static void elf64_hppa_post_process_headers PARAMS ((bfd *, struct bfd_link_info *)); @@ -384,13 +381,16 @@ elf64_hppa_object_p (abfd) { /* GCC on hppa-linux produces binaries with OSABI=Linux, but the kernel produces corefiles with OSABI=SysV. */ - if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX && - i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */ + if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX + && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */ return FALSE; } else { - if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX) + /* HPUX produces binaries with OSABI=HPUX, + but the kernel produces corefiles with OSABI=SysV. */ + if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX + && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */ return FALSE; } @@ -402,7 +402,10 @@ elf64_hppa_object_p (abfd) case EFA_PARISC_1_1: return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 11); case EFA_PARISC_2_0: - return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20); + if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64) + return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25); + else + return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20); case EFA_PARISC_2_0 | EF_PARISC_WIDE: return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25); } @@ -413,10 +416,10 @@ elf64_hppa_object_p (abfd) /* Given section type (hdr->sh_type), return a boolean indicating whether or not the section is an elf64-hppa specific section. */ static bfd_boolean -elf64_hppa_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf_Internal_Shdr *hdr; - const char *name; +elf64_hppa_section_from_shdr (bfd *abfd, + Elf_Internal_Shdr *hdr, + const char *name, + int shindex) { asection *newsect; @@ -436,7 +439,7 @@ elf64_hppa_section_from_shdr (abfd, hdr, name) return FALSE; } - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) + if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) return FALSE; newsect = hdr->bfd_section; @@ -535,15 +538,14 @@ get_reloc_section (abfd, hppa_info, sec) srel = bfd_get_section_by_name (dynobj, srel_name); if (srel == NULL) { - srel = bfd_make_section (dynobj, srel_name); + srel = bfd_make_section_with_flags (dynobj, srel_name, + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED + | SEC_READONLY)); if (srel == NULL - || !bfd_set_section_flags (dynobj, srel, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)) || !bfd_set_section_alignment (dynobj, srel, 3)) return FALSE; } @@ -1235,14 +1237,13 @@ get_opd (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - opd = bfd_make_section (dynobj, ".opd"); + opd = bfd_make_section_with_flags (dynobj, ".opd", + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED)); if (!opd - || !bfd_set_section_flags (dynobj, opd, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, opd, 3)) { BFD_ASSERT (0); @@ -1273,14 +1274,13 @@ get_plt (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - plt = bfd_make_section (dynobj, ".plt"); + plt = bfd_make_section_with_flags (dynobj, ".plt", + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED)); if (!plt - || !bfd_set_section_flags (dynobj, plt, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, plt, 3)) { BFD_ASSERT (0); @@ -1311,14 +1311,13 @@ get_dlt (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - dlt = bfd_make_section (dynobj, ".dlt"); + dlt = bfd_make_section_with_flags (dynobj, ".dlt", + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_LINKER_CREATED)); if (!dlt - || !bfd_set_section_flags (dynobj, dlt, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, dlt, 3)) { BFD_ASSERT (0); @@ -1349,15 +1348,13 @@ get_stub (abfd, info, hppa_info) if (!dynobj) hppa_info->root.dynobj = dynobj = abfd; - stub = bfd_make_section (dynobj, ".stub"); + stub = bfd_make_section_with_flags (dynobj, ".stub", + (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_LINKER_CREATED)); if (!stub - || !bfd_set_section_flags (dynobj, stub, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, stub, 3)) { BFD_ASSERT (0); @@ -1427,46 +1424,46 @@ elf64_hppa_create_dynamic_sections (abfd, info) if (! get_opd (abfd, info, elf64_hppa_hash_table (info))) return FALSE; - s = bfd_make_section(abfd, ".rela.dlt"); + s = bfd_make_section_with_flags (abfd, ".rela.dlt", + (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_LINKER_CREATED)); if (s == NULL - || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) return FALSE; elf64_hppa_hash_table (info)->dlt_rel_sec = s; - s = bfd_make_section(abfd, ".rela.plt"); + s = bfd_make_section_with_flags (abfd, ".rela.plt", + (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_LINKER_CREATED)); if (s == NULL - || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) return FALSE; elf64_hppa_hash_table (info)->plt_rel_sec = s; - s = bfd_make_section(abfd, ".rela.data"); + s = bfd_make_section_with_flags (abfd, ".rela.data", + (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_LINKER_CREATED)); if (s == NULL - || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) return FALSE; elf64_hppa_hash_table (info)->other_rel_sec = s; - s = bfd_make_section(abfd, ".rela.opd"); + s = bfd_make_section_with_flags (abfd, ".rela.opd", + (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_LINKER_CREATED)); if (s == NULL - || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_LINKER_CREATED)) || !bfd_set_section_alignment (abfd, s, 3)) return FALSE; elf64_hppa_hash_table (info)->opd_rel_sec = s; @@ -1708,7 +1705,6 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) for (s = dynobj->sections; s != NULL; s = s->next) { const char *name; - bfd_boolean strip; if ((s->flags & SEC_LINKER_CREATED) == 0) continue; @@ -1717,60 +1713,21 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) of the dynobj section names depend upon the input files. */ name = bfd_get_section_name (dynobj, s); - strip = 0; - if (strcmp (name, ".plt") == 0) { - /* Strip this section if we don't need it; see the comment below. */ - if (s->size == 0) - { - strip = TRUE; - } - else - { - /* Remember whether there is a PLT. */ - plt = TRUE; - } + /* Remember whether there is a PLT. */ + plt = s->size != 0; } - else if (strcmp (name, ".dlt") == 0) + else if (strcmp (name, ".opd") == 0 + || strncmp (name, ".dlt", 4) == 0 + || strcmp (name, ".stub") == 0 + || strcmp (name, ".got") == 0) { /* Strip this section if we don't need it; see the comment below. */ - if (s->size == 0) - { - strip = TRUE; - } - } - else if (strcmp (name, ".opd") == 0) - { - /* Strip this section if we don't need it; see the comment below. */ - if (s->size == 0) - { - strip = TRUE; - } } else if (strncmp (name, ".rela", 5) == 0) { - /* If we don't need this section, strip it from the output file. - This is mostly to handle .rela.bss and .rela.plt. We must - create both sections in create_dynamic_sections, because they - must be created before the linker maps input sections to output - sections. The linker does that before adjust_dynamic_symbol - is called, and it is that function which decides whether - anything needs to go into these sections. */ - if (s->size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = TRUE; - } - else + if (s->size != 0) { asection *target; @@ -1801,20 +1758,30 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) s->reloc_count = 0; } } - else if (strncmp (name, ".dlt", 4) != 0 - && strcmp (name, ".stub") != 0 - && strcmp (name, ".got") != 0) + else { /* It's not one of our sections, so don't allocate space. */ continue; } - if (strip) + if (s->size == 0) { - _bfd_strip_section_from_output (info, s); + /* If we don't need this section, strip it from the + output file. This is mostly to handle .rela.bss and + .rela.plt. We must create both sections in + create_dynamic_sections, because they must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + s->flags |= SEC_EXCLUDE; continue; } + if ((s->flags & SEC_HAS_CONTENTS) == 0) + continue; + /* Allocate memory for the section contents if it has not been allocated already. We use bfd_zalloc here in case unused entries are not reclaimed before the section's @@ -1824,7 +1791,7 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) if (s->contents == NULL) { s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); - if (s->contents == NULL && s->size != 0) + if (s->contents == NULL) return FALSE; } } @@ -2680,11 +2647,64 @@ elf64_hppa_elf_get_symbol_type (elf_sym, type) return type; } -static struct bfd_elf_special_section const elf64_hppa_special_sections[]= +/* Support HP specific sections for core files. */ +static bfd_boolean +elf64_hppa_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index, + const char *typename) +{ + if (hdr->p_type == PT_HP_CORE_KERNEL) + { + asection *sect; + + if (!_bfd_elf_make_section_from_phdr (abfd, hdr, index, typename)) + return FALSE; + + sect = bfd_make_section_anyway (abfd, ".kernel"); + if (sect == NULL) + return FALSE; + sect->size = hdr->p_filesz; + sect->filepos = hdr->p_offset; + sect->flags = SEC_HAS_CONTENTS | SEC_READONLY; + return TRUE; + } + + if (hdr->p_type == PT_HP_CORE_PROC) + { + int sig; + + if (bfd_seek (abfd, hdr->p_offset, SEEK_SET) != 0) + return FALSE; + if (bfd_bread (&sig, 4, abfd) != 4) + return FALSE; + + elf_tdata (abfd)->core_signal = sig; + + if (!_bfd_elf_make_section_from_phdr (abfd, hdr, index, typename)) + return FALSE; + + /* GDB uses the ".reg" section to read register contents. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", hdr->p_filesz, + hdr->p_offset); + } + + if (hdr->p_type == PT_HP_CORE_LOADABLE + || hdr->p_type == PT_HP_CORE_STACK + || hdr->p_type == PT_HP_CORE_MMF) + hdr->p_type = PT_LOAD; + + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, typename); +} + +static const struct bfd_elf_special_section elf64_hppa_special_sections[] = { - { ".fini", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, - { ".init", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, - { NULL, 0, 0, 0, 0 } + { ".fini", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".init", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, + { ".plt", 4, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT }, + { ".dlt", 4, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT }, + { ".sdata", 6, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT }, + { ".sbss", 5, 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT }, + { ".tbss", 5, 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_WEAKORDER }, + { NULL, 0, 0, 0, 0 } }; /* The hash bucket size is the standard one, namely 4. */ @@ -2784,6 +2804,8 @@ const struct elf_size_info hppa64_elf_size_info = #define elf_backend_reloc_type_class elf64_hppa_reloc_type_class #define elf_backend_rela_normal 1 #define elf_backend_special_sections elf64_hppa_special_sections +#define elf_backend_action_discarded elf_hppa_action_discarded +#define elf_backend_section_from_phdr elf64_hppa_section_from_phdr #include "elf64-target.h"