|
|
|
@ -64,6 +64,12 @@ static boolean elf_hppa_fake_sections |
|
|
|
static void elf_hppa_final_write_processing |
|
|
|
PARAMS ((bfd *, boolean)); |
|
|
|
|
|
|
|
static int hppa_unwind_entry_compare |
|
|
|
PARAMS ((const PTR, const PTR)); |
|
|
|
|
|
|
|
static boolean elf_hppa_sort_unwind |
|
|
|
PARAMS ((bfd *)); |
|
|
|
|
|
|
|
#if ARCH_SIZE == 64 |
|
|
|
static boolean elf_hppa_add_symbol_hook |
|
|
|
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, |
|
|
|
@ -86,12 +92,12 @@ static boolean elf_hppa_final_link |
|
|
|
|
|
|
|
static boolean elf_hppa_relocate_section |
|
|
|
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, |
|
|
|
bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
|
|
|
bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); |
|
|
|
|
|
|
|
static bfd_reloc_status_type elf_hppa_final_link_relocate |
|
|
|
PARAMS ((Elf_Internal_Rela *, bfd *, bfd *, asection *, |
|
|
|
bfd_byte *, bfd_vma, struct bfd_link_info *, |
|
|
|
asection *, struct elf_link_hash_entry *, |
|
|
|
bfd_byte *, bfd_vma, struct bfd_link_info *, |
|
|
|
asection *, struct elf_link_hash_entry *, |
|
|
|
struct elf64_hppa_dyn_hash_entry *)); |
|
|
|
|
|
|
|
static int elf_hppa_relocate_insn |
|
|
|
@ -709,7 +715,7 @@ elf_hppa_reloc_final_type (abfd, base_type, format, field) |
|
|
|
be a section relative relocation. Dwarf2 (for example) |
|
|
|
uses 32bit section relative relocations. */ |
|
|
|
if (bfd_get_arch_info (abfd)->bits_per_address != 32) |
|
|
|
final_type = R_PARISC_SECREL32; |
|
|
|
final_type = R_PARISC_SECREL32; |
|
|
|
break; |
|
|
|
case e_psel: |
|
|
|
final_type = R_PARISC_PLABEL32; |
|
|
|
@ -1037,6 +1043,64 @@ elf_hppa_final_write_processing (abfd, linker) |
|
|
|
| EF_PARISC_TRAPNIL); |
|
|
|
} |
|
|
|
|
|
|
|
/* Comparison function for qsort to sort unwind section during a
|
|
|
|
final link. */ |
|
|
|
|
|
|
|
static int |
|
|
|
hppa_unwind_entry_compare (a, b) |
|
|
|
const PTR a; |
|
|
|
const PTR b; |
|
|
|
{ |
|
|
|
const bfd_byte *ap, *bp; |
|
|
|
unsigned long av, bv; |
|
|
|
|
|
|
|
ap = (const bfd_byte *) a; |
|
|
|
av = (unsigned long) ap[0] << 24; |
|
|
|
av |= (unsigned long) ap[1] << 16; |
|
|
|
av |= (unsigned long) ap[2] << 8; |
|
|
|
av |= (unsigned long) ap[3]; |
|
|
|
|
|
|
|
bp = (const bfd_byte *) b; |
|
|
|
bv = (unsigned long) bp[0] << 24; |
|
|
|
bv |= (unsigned long) bp[1] << 16; |
|
|
|
bv |= (unsigned long) bp[2] << 8; |
|
|
|
bv |= (unsigned long) bp[3]; |
|
|
|
|
|
|
|
return av < bv ? -1 : av > bv ? 1 : 0; |
|
|
|
} |
|
|
|
|
|
|
|
static boolean elf_hppa_sort_unwind (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
asection *s; |
|
|
|
|
|
|
|
/* Magic section names, but this is much safer than having
|
|
|
|
relocate_section remember where SEGREL32 relocs occurred. |
|
|
|
Consider what happens if someone inept creates a linker script |
|
|
|
that puts unwind information in .text. */ |
|
|
|
s = bfd_get_section_by_name (abfd, ".PARISC.unwind"); |
|
|
|
if (s != NULL) |
|
|
|
{ |
|
|
|
bfd_size_type size; |
|
|
|
char *contents; |
|
|
|
|
|
|
|
size = s->_raw_size; |
|
|
|
contents = bfd_malloc (size); |
|
|
|
if (contents == NULL) |
|
|
|
return false; |
|
|
|
|
|
|
|
if (! bfd_get_section_contents (abfd, s, contents, (file_ptr) 0, size)) |
|
|
|
return false; |
|
|
|
|
|
|
|
qsort (contents, (size_t) (size / 16), 16, hppa_unwind_entry_compare); |
|
|
|
|
|
|
|
if (! bfd_set_section_contents (abfd, s, contents, (file_ptr) 0, size)) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
#if ARCH_SIZE == 64 |
|
|
|
/* Hook called by the linker routine which adds symbols from an object
|
|
|
|
file. HP's libraries define symbols with HP specific section |
|
|
|
@ -1284,6 +1348,11 @@ elf_hppa_final_link (abfd, info) |
|
|
|
elf_hppa_remark_useless_dynamic_symbols, |
|
|
|
info); |
|
|
|
|
|
|
|
/* If we're producing a final executable, sort the contents of the
|
|
|
|
unwind section. */ |
|
|
|
if (retval) |
|
|
|
retval = elf_hppa_sort_unwind (abfd); |
|
|
|
|
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1416,7 +1485,7 @@ elf_hppa_relocate_section (output_bfd, info, input_bfd, input_section, |
|
|
|
relocation = 0; |
|
|
|
} |
|
|
|
/* Allow undefined symbols in shared libraries. */ |
|
|
|
else if (info->shared && !info->no_undefined |
|
|
|
else if (info->shared && !info->no_undefined |
|
|
|
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) |
|
|
|
{ |
|
|
|
if (info->symbolic) |
|
|
|
@ -2006,7 +2075,7 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, |
|
|
|
} |
|
|
|
|
|
|
|
/* We want the value of the OPD offset for this symbol, not
|
|
|
|
the symbol's actual address. */ |
|
|
|
the symbol's actual address. */ |
|
|
|
value = (dyn_h->opd_offset |
|
|
|
+ hppa_info->opd_sec->output_offset |
|
|
|
+ hppa_info->opd_sec->output_section->vma); |
|
|
|
@ -2047,7 +2116,7 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, |
|
|
|
bfd_put_32 (input_bfd, value, hit_data); |
|
|
|
else |
|
|
|
bfd_put_64 (input_bfd, value, hit_data); |
|
|
|
return bfd_reloc_ok; |
|
|
|
return bfd_reloc_ok; |
|
|
|
} |
|
|
|
|
|
|
|
/* Something we don't know how to handle. */ |
|
|
|
|