{
/* 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;
}
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);
}
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
- bfd_boolean strip;
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
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;
- }
- }
- else if (strcmp (name, ".dlt") == 0)
- {
- /* Strip this section if we don't need it; see the comment below. */
- if (s->size == 0)
- {
- strip = TRUE;
- }
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
}
- else if (strcmp (name, ".opd") == 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 (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;
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)
{
+ /* 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
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;
}
}
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)
{
- { ".fini", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
- { ".init", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
- { NULL, 0, 0, 0, 0 }
-};
+ if (hdr->p_type == PT_HP_CORE_KERNEL)
+ {
+ asection *sect;
-static const struct bfd_elf_special_section *
-elf64_hppa_get_sec_type_attr (bfd *abfd, asection *sec)
-{
- const struct bfd_elf_special_section const *ssect;
+ if (!_bfd_elf_make_section_from_phdr (abfd, hdr, index, typename))
+ return FALSE;
- /* See if this is one of the special sections. */
- if (sec->name == NULL)
- return NULL;
+ 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;
+ }
- ssect = _bfd_elf_get_special_section (sec->name,
- elf64_hppa_special_sections,
- sec->use_rela_p);
- if (ssect != NULL)
- return ssect;
+ if (hdr->p_type == PT_HP_CORE_PROC)
+ {
+ int sig;
- return _bfd_elf_get_sec_type_attr (abfd, sec);
+ 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 },
+ { ".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. */
const struct elf_size_info hppa64_elf_size_info =
#define elf_backend_get_symbol_type elf64_hppa_elf_get_symbol_type
#define elf_backend_reloc_type_class elf64_hppa_reloc_type_class
#define elf_backend_rela_normal 1
-#define elf_backend_get_sec_type_attr elf64_hppa_get_sec_type_attr
+#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"
#undef TARGET_BIG_NAME
#define TARGET_BIG_NAME "elf64-hppa-linux"
-#undef elf_backend_get_sec_type_attr
+#undef elf_backend_special_sections
#define INCLUDED_TARGET_FILE 1
#include "elf64-target.h"