diff options
author | Ken Raeburn <raeburn@cygnus> | 1993-08-28 00:10:54 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1993-08-28 00:10:54 +0000 |
commit | d9ad93bce5cb9be821085233353cbf6baa7e1a2e (patch) | |
tree | 1d611bcef298efb57c2f27e3a732cfc571361985 /bfd/elf32-hppa.c | |
parent | 78e1e6d95a89375bfcd2f01e963f9edbc67c8b85 (diff) | |
download | gdb-d9ad93bce5cb9be821085233353cbf6baa7e1a2e.zip gdb-d9ad93bce5cb9be821085233353cbf6baa7e1a2e.tar.gz gdb-d9ad93bce5cb9be821085233353cbf6baa7e1a2e.tar.bz2 |
More patches from Jeff Law, plus a little cleanup of my own.
These changes separate PA-SOM support from PA-ELF support.
A sun4-x-hppaosf assembler can now be built.
* elf32-hppa.c (elf_hppa_howto_table): Now static.
(symext_rootP, symext_lastP, global_value, GOT_value, global_symbol,
global_sym_defined, symextn_contents, symextn_contents_real_size,
elf_hppa_stub_rootP, elf32_hppa_symextn_map, elf32_hppa_symextn_map_size): Rely
on default initialization.
(hppa_elf_gen_reloc_type): Macro "UNDEFINED" doesn't need a trailing semicolon.
(hppa_look_for_stubs_in_section): Introduce temporaries to make code more
readable in 80 columns.
* libhppa.h (all functions): Now inline under GNU C.
* elf32-hppa.c (AR_WARN): Give argument which caused the invalid argument
relocation.
(AR_UNIMP): Delete unused macro.
(hppa_elf_set_section_contents): Always return a value.
(elf32_hppa_backend_table_processing): Likewise.
(elf32_hppa_backend_section_processing: Likewise.
* som.c: New file containing SOM specific code extracted from hppa.c
* som.h: New file containing SOM specific code extracted from libhppa.h
* hppa.c: Deleted.
* libhppa.h: Delete SOM specific code. Add generic PA code which can be shared
by both SOM and ELF backends.
* Makefile.in: Replace hppa.c with som.c. elf32-hppa.o depends on libhppa.h
now.
* configure.in (hppa_vec): Needs som.o module instead of hppa.o.
* elf32-hppa.c: Include libhppa.h. Do not define BYTES_IN_WORD.
* elf32-hppa.h (hppa_reloc_field_selector_type): Delete now lives in libhppa.h.
(hppa_reloc_field_selector_type_alt): Likewise.
* elf32-hppa.c (hppa_elf_relocate_unwind_table): Delete unused variables.
(elf_hppa_reloc_type_lookup): Likewise.
(elf_hppa_tc_make_sections): Likewise.
(hppa_elf_arg_reloc_needed_p): Likewise.
(hppa_elf_build_long_branch_stub): Likewise.
(elf_reloc_map): Delete, no longer used.
(elf_hppa_reloc_map): Likewise.
(elf32_hppa_symextn_map_max_size): Likewise.
(elf32_hppa_get_sym_extn): Abort if type is bogus.
* elf32-hppa.c (elf32_hppa_backend_fake_sections): Add processing
of the .hppa_unwind section.
Diffstat (limited to 'bfd/elf32-hppa.c')
-rw-r--r-- | bfd/elf32-hppa.c | 1307 |
1 files changed, 969 insertions, 338 deletions
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index afc4011..99801bd 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -45,156 +45,157 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ */ #include "elf32-hppa.h" -/*#include "libhppa.h"*/ -#define BYTES_IN_WORD 4 +#include "libhppa.h" #include "aout/aout64.h" +#include "hppa_stubs.h" /* ELF/PA relocation howto entries */ static bfd_reloc_status_type hppa_elf_reloc (); -reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = +static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = { /* 'bitpos' and 'abs' are obsolete */ /* type rs sz bsz pcrel bpos abs ovrf sf name */ /* 9.3.4. Address relocation types */ - {R_HPPA_NONE, 0, 3, 19, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NONE"}, - {R_HPPA_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_32"}, - {R_HPPA_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_11"}, - {R_HPPA_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_14"}, - {R_HPPA_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_17"}, -{R_HPPA_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L21"}, -{R_HPPA_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R11"}, -{R_HPPA_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R14"}, -{R_HPPA_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_R17"}, - {R_HPPA_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LS21"}, - {R_HPPA_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS11"}, - {R_HPPA_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS14"}, - {R_HPPA_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RS17"}, - {R_HPPA_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LD21"}, - {R_HPPA_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD11"}, - {R_HPPA_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD14"}, - {R_HPPA_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RD17"}, - {R_HPPA_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LR21"}, - {R_HPPA_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR14"}, - {R_HPPA_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_RR17"}, + {R_HPPA_NONE, 0, 3, 19, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NONE"}, + {R_HPPA_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_32"}, + {R_HPPA_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_11"}, + {R_HPPA_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_14"}, + {R_HPPA_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_17"}, +{R_HPPA_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L21"}, +{R_HPPA_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R11"}, +{R_HPPA_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R14"}, +{R_HPPA_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R17"}, + {R_HPPA_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LS21"}, + {R_HPPA_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS11"}, + {R_HPPA_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS14"}, + {R_HPPA_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS17"}, + {R_HPPA_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LD21"}, + {R_HPPA_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD11"}, + {R_HPPA_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD14"}, + {R_HPPA_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD17"}, + {R_HPPA_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LR21"}, + {R_HPPA_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR14"}, + {R_HPPA_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR17"}, /* 9.3.5. GOTOFF address relocation types */ - {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_11"}, - {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_14"}, - {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"}, - {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"}, - {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"}, - {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"}, - {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"}, - {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"}, - {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"}, - {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"}, - {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"}, - {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"}, - {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"}, + {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_11"}, + {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_14"}, + {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"}, + {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"}, + {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"}, + {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"}, + {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"}, + {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"}, + {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"}, + {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"}, + {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"}, + {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"}, + {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"}, /* 9.3.6. Absolute call relocation types */ - {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"}, - {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"}, - {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"}, - {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"}, - {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"}, - {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"}, - {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"}, - {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"}, - {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"}, - {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"}, - {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"}, - {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"}, - {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"}, - {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"}, - {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"}, - {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"}, - {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"}, - {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"}, + {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"}, + {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"}, + {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"}, + {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"}, + {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"}, + {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"}, + {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"}, + {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"}, + {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"}, + {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"}, + {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"}, + {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"}, + {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"}, + {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"}, + {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"}, + {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"}, + {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"}, + {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"}, /* 9.3.7. PC-relative call relocation types */ - {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"}, - {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"}, - {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"}, - {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"}, - {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"}, - {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"}, - {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"}, - {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"}, - {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"}, - {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"}, - {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"}, - {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"}, - {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"}, - {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"}, - {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"}, - {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"}, - {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"}, - {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"}, - {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"}, + {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"}, + {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"}, + {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"}, + {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"}, + {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"}, + {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"}, + {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"}, + {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"}, + {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"}, + {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"}, + {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"}, + {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"}, + {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"}, + {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"}, + {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"}, + {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"}, + {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"}, + {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"}, + {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"}, /* 9.3.8. Plabel relocation types */ - {R_HPPA_PLABEL_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_32"}, - {R_HPPA_PLABEL_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_11"}, - {R_HPPA_PLABEL_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_14"}, - {R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_L21"}, - {R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R11"}, - {R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_PLABEL_R14"}, + {R_HPPA_PLABEL_32, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_32"}, + {R_HPPA_PLABEL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_11"}, + {R_HPPA_PLABEL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_14"}, + {R_HPPA_PLABEL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_L21"}, + {R_HPPA_PLABEL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R11"}, + {R_HPPA_PLABEL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R14"}, /* 9.3.9. Data linkage table (DLT) relocation types */ - {R_HPPA_DLT_32, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_32"}, - {R_HPPA_DLT_11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_11"}, - {R_HPPA_DLT_14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_14"}, - {R_HPPA_DLT_L21, 0, 3, 21, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_L21"}, - {R_HPPA_DLT_R11, 0, 3, 11, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R11"}, - {R_HPPA_DLT_R14, 0, 3, 14, true, 0, false, true, hppa_elf_reloc, "R_HPPA_DLT_R14"}, + {R_HPPA_DLT_32, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_32"}, + {R_HPPA_DLT_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_11"}, + {R_HPPA_DLT_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_14"}, + {R_HPPA_DLT_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_L21"}, + {R_HPPA_DLT_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R11"}, + {R_HPPA_DLT_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R14"}, /* 9.3.10. Relocations for unwinder tables */ - {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"}, - {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, false, true, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"}, + {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"}, + {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"}, /* 9.3.11. Relocation types for complex expressions */ - {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_CONST"}, - {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PC"}, - {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_SYM"}, - {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"}, - {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"}, - {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"}, - {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"}, -{R_HPPA_MAX, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MAX"}, -{R_HPPA_MIN, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MIN"}, -{R_HPPA_ADD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ADD"}, -{R_HPPA_SUB, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_SUB"}, - {R_HPPA_MULT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MULT"}, -{R_HPPA_DIV, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_DIV"}, -{R_HPPA_MOD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_MOD"}, -{R_HPPA_AND, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_AND"}, - {R_HPPA_OR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_OR"}, -{R_HPPA_XOR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_XOR"}, -{R_HPPA_NOT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_NOT"}, - {R_HPPA_LSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LSHIFT"}, - {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"}, - {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"}, -{R_HPPA_EXPR_F, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_L"}, - {R_HPPA_EXPR_L, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_L"}, - {R_HPPA_EXPR_R, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_R"}, - {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LS"}, - {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RS"}, - {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LD"}, - {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RD"}, - {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_LR"}, - {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_RR"}, - - {R_HPPA_EXPR_32, 0, 3, 32, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_32"}, - {R_HPPA_EXPR_21, 0, 3, 21, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_21"}, - {R_HPPA_EXPR_11, 0, 3, 11, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_11"}, - {R_HPPA_EXPR_14, 0, 3, 14, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_14"}, - {R_HPPA_EXPR_17, 0, 3, 17, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_17"}, - {R_HPPA_EXPR_12, 0, 3, 12, false, 0, false, true, hppa_elf_reloc, "R_HPPA_EXPR_12"}, - {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, false, false, NULL, "R_HPPA_UNIMPLEMENTED"}, + {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_CONST"}, + {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PC"}, + {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_SYM"}, + {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"}, + {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"}, + {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"}, + {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"}, +{R_HPPA_MAX, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MAX"}, +{R_HPPA_MIN, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MIN"}, +{R_HPPA_ADD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ADD"}, +{R_HPPA_SUB, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_SUB"}, + {R_HPPA_MULT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MULT"}, +{R_HPPA_DIV, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_DIV"}, +{R_HPPA_MOD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MOD"}, +{R_HPPA_AND, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_AND"}, + {R_HPPA_OR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_OR"}, +{R_HPPA_XOR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_XOR"}, +{R_HPPA_NOT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NOT"}, + {R_HPPA_LSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LSHIFT"}, + {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"}, + {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"}, +{R_HPPA_EXPR_F, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L"}, + {R_HPPA_EXPR_L, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_L"}, + {R_HPPA_EXPR_R, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_R"}, + {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LS"}, + {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RS"}, + {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LD"}, + {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RD"}, + {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LR"}, + {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RR"}, + + {R_HPPA_EXPR_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_32"}, + {R_HPPA_EXPR_21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_21"}, + {R_HPPA_EXPR_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_11"}, + {R_HPPA_EXPR_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_14"}, + {R_HPPA_EXPR_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_17"}, + {R_HPPA_EXPR_12, 0, 3, 12, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_12"}, + {R_HPPA_STUB_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_STUB_CALL_17"}, + {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_HPPA_UNIMPLEMENTED"}, }; -static symext_chainS *symext_rootP = NULL; -static symext_chainS *symext_lastP = NULL; +static symext_chainS *symext_rootP; +static symext_chainS *symext_lastP; static unsigned long DEFUN (hppa_elf_rebuild_insn, (abfd, insn, value, r_type, r_field, r_format), @@ -301,7 +302,7 @@ DEFUN (hppa_elf_relocate_insn, if (pcrel) sym_value -= address; sym_value = hppa_field_adjust (sym_value, constant_value, r_field); - return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_format, r_format); + return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format); case COMICLR: case SUBI: /* case SUBIO: */ @@ -407,32 +408,23 @@ DEFUN (hppa_elf_relocate_unwind_table, case R_HPPA_UNWIND_ENTRIES: for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long)) { - unsigned int fsize; + unsigned int adjustment; start_offset = bfd_get_32 (abfd, hit_data); /* Stuff the symbol value into the first word */ /* of the unwind descriptor */ bfd_put_32 (abfd, sym_value, hit_data); + adjustment = sym_value - start_offset; hit_data += sizeof (unsigned long); - end_offset = bfd_get_32 (abfd, hit_data); - /* We could also compute the ending offset for */ - /* the 2nd word of the unwind entry by */ - /* retrieving the st_size field of the Elf_Sym */ - /* structure stored with this symbol. We can */ - /* get it with: */ - /* e = (elf_symbol_type *)symp */ - /* fsize = e->internal_elf_sym.st_size */ - - fsize = end_offset - start_offset; - relocated_value = hppa_field_adjust (sym_value, fsize, r_field); - bfd_put_32 (abfd, relocated_value, hit_data); + end_offset = adjustment + bfd_get_32 (abfd, hit_data); + bfd_put_32 (abfd, end_offset, hit_data); /* If this is not the last unwind entry, */ /* adjust the symbol value. */ if (i + 1 < r_addend) { start_offset = bfd_get_32 (abfd, hit_data + 3 * sizeof (unsigned long)); - sym_value += fsize + start_offset - end_offset; + sym_value = start_offset + adjustment; } } break; @@ -495,7 +487,7 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field) int format; int field; { -#define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field); +#define UNDEFINED hppa_elf_gen_reloc_error(base_type,format,field) elf32_hppa_reloc_type *finaltype; elf32_hppa_reloc_type **final_types; @@ -1178,13 +1170,13 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field) #undef final_type -/* 12.4.4. Derive format from instruction */ +/* 12.4.4. Derive format from instruction -/* Given a machine instruction, this function determines its format. */ -/* The format can be determined solely from looking at the first six */ -/* bits (the major opcode) of the instruction. Several major opcodes */ -/* map to the same format. Opcodes which do not map to a known format */ -/* should probably be reported as an error. */ + Given a machine instruction, this function determines its format. + The format can be determined solely from looking at the first six + bits (the major opcode) of the instruction. Several major opcodes + map to the same format. Opcodes which do not map to a known format + should probably be reported as an error. */ unsigned char hppa_elf_insn2fmt (type, insn) @@ -1249,9 +1241,10 @@ hppa_elf_insn2fmt (type, insn) } /* this function is in charge of performing all the HP PA relocations */ -static long global_value = 0; -static long GOT_value = 0; /* XXX: need to calculate this! For HPUX, GOT == DP */ -static asymbol *global_symbol = (asymbol *) NULL; +static long global_value; +static long GOT_value; /* XXX: need to calculate this! For HPUX, GOT == DP */ +static asymbol *global_symbol; +static int global_sym_defined; static bfd_reloc_status_type DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, output_bfd), @@ -1293,20 +1286,15 @@ DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, outpu /* compute value of $global$ if it is there. */ - if (global_symbol == (asymbol *) NULL) + if (!global_sym_defined) { - struct elf_backend_data *bed - = (struct elf_backend_data *) abfd->xvec->backend_data; - - if (bed && bed->global_sym) + if (global_symbol) { - asymbol *gsym = &bed->global_sym->symbol; - global_value - = gsym->value - + gsym->section->output_section->vma - + gsym->section->output_offset; + global_value = (global_symbol->value + + global_symbol->section->output_section->vma + + global_symbol->section->output_offset); GOT_value = global_value; /* XXX: For HP-UX, GOT==DP */ - global_symbol = gsym; + global_sym_defined++; } } @@ -1618,6 +1606,21 @@ DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, outpu fprintf (stderr, "Unimplemented reloc type %d, in module %s\n", r_type, abfd->filename); return (bfd_reloc_notsupported); + case R_HPPA_STUB_CALL_17: + /* yes, a branch to a long branch stub. Change instruction to a BLE */ + /* or BLE,N */ + if ( *(unsigned *)hit_data & 2 ) + insn = BLE_N_XXX_0_0; + else + insn = BLE_XXX_0_0; + bfd_put_32 (abfd, insn, hit_data); + r_type = R_HPPA_ABS_CALL_17; + r_pcrel = 0; + insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr, + symbol_in, sym_value, r_addend, + r_type, r_format, r_field, r_pcrel); + break; + default: fprintf (stderr, "Relocation problem : "); fprintf (stderr, "Unrecognized reloc type %d, in module %s\n", @@ -1632,107 +1635,11 @@ DEFUN (hppa_elf_reloc, (abfd, reloc_entry, symbol_in, data, input_section, outpu } -struct elf_reloc_map - { - unsigned char bfd_reloc_val; - unsigned char elf_reloc_val; - }; - -static CONST struct elf_reloc_map elf_hppa_reloc_map[] = -{ - {BFD_RELOC_NONE, R_HPPA_NONE,}, - {BFD_RELOC_HPPA_32, R_HPPA_32,}, - {BFD_RELOC_HPPA_11, R_HPPA_11,}, - {BFD_RELOC_HPPA_14, R_HPPA_14,}, - {BFD_RELOC_HPPA_17, R_HPPA_17,}, - {BFD_RELOC_HPPA_L21, R_HPPA_L21,}, - {BFD_RELOC_HPPA_R11, R_HPPA_R11,}, - {BFD_RELOC_HPPA_R14, R_HPPA_R14,}, - {BFD_RELOC_HPPA_R17, R_HPPA_R17,}, - {BFD_RELOC_HPPA_LS21, R_HPPA_LS21,}, - {BFD_RELOC_HPPA_RS11, R_HPPA_RS11,}, - {BFD_RELOC_HPPA_RS14, R_HPPA_RS14,}, - {BFD_RELOC_HPPA_RS17, R_HPPA_RS17,}, - {BFD_RELOC_HPPA_LD21, R_HPPA_LD21,}, - {BFD_RELOC_HPPA_RD11, R_HPPA_RD11,}, - {BFD_RELOC_HPPA_RD14, R_HPPA_RD14,}, - {BFD_RELOC_HPPA_RD17, R_HPPA_RD17,}, - {BFD_RELOC_HPPA_LR21, R_HPPA_LR21,}, - {BFD_RELOC_HPPA_RR14, R_HPPA_RR14,}, - {BFD_RELOC_HPPA_RR17, R_HPPA_RR17,}, - {BFD_RELOC_HPPA_GOTOFF_11, R_HPPA_GOTOFF_11,}, - {BFD_RELOC_HPPA_GOTOFF_14, R_HPPA_GOTOFF_14,}, - {BFD_RELOC_HPPA_GOTOFF_L21, R_HPPA_GOTOFF_L21,}, - {BFD_RELOC_HPPA_GOTOFF_R11, R_HPPA_GOTOFF_R11,}, - {BFD_RELOC_HPPA_GOTOFF_R14, R_HPPA_GOTOFF_R14,}, - {BFD_RELOC_HPPA_GOTOFF_LS21, R_HPPA_GOTOFF_LS21,}, - {BFD_RELOC_HPPA_GOTOFF_RS11, R_HPPA_GOTOFF_RS11,}, - {BFD_RELOC_HPPA_GOTOFF_RS14, R_HPPA_GOTOFF_RS14,}, - {BFD_RELOC_HPPA_GOTOFF_LD21, R_HPPA_GOTOFF_LD21,}, - {BFD_RELOC_HPPA_GOTOFF_RD11, R_HPPA_GOTOFF_RD11,}, - {BFD_RELOC_HPPA_GOTOFF_RD14, R_HPPA_GOTOFF_RD14,}, - {BFD_RELOC_HPPA_GOTOFF_LR21, R_HPPA_GOTOFF_LR21,}, - {BFD_RELOC_HPPA_GOTOFF_RR14, R_HPPA_GOTOFF_RR14,}, - {BFD_RELOC_HPPA_ABS_CALL_11, R_HPPA_ABS_CALL_11,}, - {BFD_RELOC_HPPA_ABS_CALL_14, R_HPPA_ABS_CALL_14,}, - {BFD_RELOC_HPPA_ABS_CALL_17, R_HPPA_ABS_CALL_17,}, - {BFD_RELOC_HPPA_ABS_CALL_L21, R_HPPA_ABS_CALL_L21,}, - {BFD_RELOC_HPPA_ABS_CALL_R11, R_HPPA_ABS_CALL_R11,}, - {BFD_RELOC_HPPA_ABS_CALL_R14, R_HPPA_ABS_CALL_R14,}, - {BFD_RELOC_HPPA_ABS_CALL_R17, R_HPPA_ABS_CALL_R17,}, - {BFD_RELOC_HPPA_ABS_CALL_LS21, R_HPPA_ABS_CALL_LS21,}, - {BFD_RELOC_HPPA_ABS_CALL_RS11, R_HPPA_ABS_CALL_RS11,}, - {BFD_RELOC_HPPA_ABS_CALL_RS14, R_HPPA_ABS_CALL_RS14,}, - {BFD_RELOC_HPPA_ABS_CALL_RS17, R_HPPA_ABS_CALL_RS17,}, - {BFD_RELOC_HPPA_ABS_CALL_LD21, R_HPPA_ABS_CALL_LD21,}, - {BFD_RELOC_HPPA_ABS_CALL_RD11, R_HPPA_ABS_CALL_RD11,}, - {BFD_RELOC_HPPA_ABS_CALL_RD14, R_HPPA_ABS_CALL_RD14,}, - {BFD_RELOC_HPPA_ABS_CALL_RD17, R_HPPA_ABS_CALL_RD17,}, - {BFD_RELOC_HPPA_ABS_CALL_LR21, R_HPPA_ABS_CALL_LR21,}, - {BFD_RELOC_HPPA_ABS_CALL_RR14, R_HPPA_ABS_CALL_RR14,}, - {BFD_RELOC_HPPA_ABS_CALL_RR17, R_HPPA_ABS_CALL_RR17,}, - {BFD_RELOC_HPPA_PCREL_CALL_11, R_HPPA_PCREL_CALL_11,}, - {BFD_RELOC_HPPA_PCREL_CALL_14, R_HPPA_PCREL_CALL_14,}, - {BFD_RELOC_HPPA_PCREL_CALL_17, R_HPPA_PCREL_CALL_17,}, - {BFD_RELOC_HPPA_PCREL_CALL_12, R_HPPA_PCREL_CALL_12,}, - {BFD_RELOC_HPPA_PCREL_CALL_L21, R_HPPA_PCREL_CALL_L21,}, - {BFD_RELOC_HPPA_PCREL_CALL_R11, R_HPPA_PCREL_CALL_R11,}, - {BFD_RELOC_HPPA_PCREL_CALL_R14, R_HPPA_PCREL_CALL_R14,}, - {BFD_RELOC_HPPA_PCREL_CALL_R17, R_HPPA_PCREL_CALL_R17,}, - {BFD_RELOC_HPPA_PCREL_CALL_LS21, R_HPPA_PCREL_CALL_LS21,}, - {BFD_RELOC_HPPA_PCREL_CALL_RS11, R_HPPA_PCREL_CALL_RS11,}, - {BFD_RELOC_HPPA_PCREL_CALL_RS14, R_HPPA_PCREL_CALL_RS14,}, - {BFD_RELOC_HPPA_PCREL_CALL_RS17, R_HPPA_PCREL_CALL_RS17,}, - {BFD_RELOC_HPPA_PCREL_CALL_LD21, R_HPPA_PCREL_CALL_LD21,}, - {BFD_RELOC_HPPA_PCREL_CALL_RD11, R_HPPA_PCREL_CALL_RD11,}, - {BFD_RELOC_HPPA_PCREL_CALL_RD14, R_HPPA_PCREL_CALL_RD14,}, - {BFD_RELOC_HPPA_PCREL_CALL_RD17, R_HPPA_PCREL_CALL_RD17,}, - {BFD_RELOC_HPPA_PCREL_CALL_LR21, R_HPPA_PCREL_CALL_LR21,}, - {BFD_RELOC_HPPA_PCREL_CALL_RR14, R_HPPA_PCREL_CALL_RR14,}, - {BFD_RELOC_HPPA_PCREL_CALL_RR17, R_HPPA_PCREL_CALL_RR17,}, - {BFD_RELOC_HPPA_PLABEL_32, R_HPPA_PLABEL_32,}, - {BFD_RELOC_HPPA_PLABEL_11, R_HPPA_PLABEL_11,}, - {BFD_RELOC_HPPA_PLABEL_14, R_HPPA_PLABEL_14,}, - {BFD_RELOC_HPPA_PLABEL_L21, R_HPPA_PLABEL_L21,}, - {BFD_RELOC_HPPA_PLABEL_R11, R_HPPA_PLABEL_R11,}, - {BFD_RELOC_HPPA_PLABEL_R14, R_HPPA_PLABEL_R14,}, - {BFD_RELOC_HPPA_DLT_32, R_HPPA_DLT_32,}, - {BFD_RELOC_HPPA_DLT_11, R_HPPA_DLT_11,}, - {BFD_RELOC_HPPA_DLT_14, R_HPPA_DLT_14,}, - {BFD_RELOC_HPPA_DLT_L21, R_HPPA_DLT_L21,}, - {BFD_RELOC_HPPA_DLT_R11, R_HPPA_DLT_R11,}, - {BFD_RELOC_HPPA_DLT_R14, R_HPPA_DLT_R14,}, - {BFD_RELOC_HPPA_UNWIND_ENTRY, R_HPPA_UNWIND_ENTRY,}, - {BFD_RELOC_HPPA_UNWIND_ENTRIES, R_HPPA_UNWIND_ENTRIES,}, -}; - static reloc_howto_type * elf_hppa_reloc_type_lookup (arch, code) bfd_arch_info_type *arch; bfd_reloc_code_real_type code; { - int i; - if ((int) code < (int) R_HPPA_UNIMPLEMENTED) { BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code); @@ -1783,8 +1690,14 @@ DEFUN (elf_hppa_tc_symbol, (abfd, symbolP, sym_idx), } } -static symext_entryS *symextn_contents = NULL; -static unsigned int symextn_contents_real_size = 0; +/* Accessor function for the list of symbol extension records. */ +symext_chainS *elf32_hppa_get_symextn_chain() +{ + return symext_rootP; +} + +static symext_entryS *symextn_contents; +static unsigned int symextn_contents_real_size; void DEFUN (elf_hppa_tc_make_sections, (abfd, ignored), @@ -1792,11 +1705,9 @@ DEFUN (elf_hppa_tc_make_sections, (abfd, ignored), PTR ignored) { symext_chainS *symextP; - symext_entryS *outbound_symexts; int size; int n; int i; - extern char *stub_section_contents; /* forward declaration */ void hppa_elf_stub_finish (); /* forward declaration */ asection *symextn_sec; @@ -1894,6 +1805,9 @@ elf32_hppa_get_sym_extn (abfd, sym, type) retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc; break; } + /* This should never happen. */ + default: + abort(); } return retval; } @@ -1919,7 +1833,7 @@ typedef struct Elf32_hppa_Stub_list_struct struct Elf32_hppa_Stub_list_struct *next; } Elf32_hppa_Stub_list; -static Elf32_hppa_Stub_list *elf_hppa_stub_rootP = NULL; +static Elf32_hppa_Stub_list *elf_hppa_stub_rootP; /* Locate the stub section information for the given bfd. */ static Elf32_hppa_Stub_description * @@ -1995,8 +1909,12 @@ add_stub (stub) #define NO_ARG_RELOC 0 #define R_TO_FR 1 -#define FR_TO_R 2 -#define ARG_RELOC_ERR 3 +#define R01_TO_FR 2 +#define R23_TO_FR 3 +#define FR_TO_R 4 +#define FR_TO_R01 5 +#define FR_TO_R23 6 +#define ARG_RELOC_ERR 7 #define ARG0 0 #define ARG1 1 @@ -2008,34 +1926,55 @@ add_stub (stub) #define AR_GR 1 #define AR_FR 2 #define AR_FU 3 +/* FP register in arg0/arg1. This value can only appear in the arg0 location. */ +#define AR_DBL01 4 +/* FP register in arg2/arg3. This value can only appear in the arg2 location. */ +#define AR_DBL23 5 + +#define AR_WARN(type,loc) \ + fprintf(stderr,"WARNING: Illegal argument relocation: %s for %s\n", \ + reloc_type_strings[type],reloc_loc_strings[loc]) static CONST char *CONST reloc_type_strings[] = { - "NONE", "GR->FR", "FR->GR", "ERROR" + "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR" +}; + +static CONST char *CONST reloc_loc_strings[] = +{ + "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL" }; -static CONST char mismatches[4][4] = -{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU */ +static CONST char mismatches[6][6] = +{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */ /* CALLER NONE */ - {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC}, + {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC}, /* CALLER GR */ - {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR}, + {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR}, /* CALLER FR */ - {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC}, + {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR}, /* CALLER FU */ - {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC}, + {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR}, + /* CALLER DBL01 */ + {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR}, + /* CALLER DBL23 */ + {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC}, }; -static CONST char retval_mismatches[4][4] = -{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU */ +static CONST char retval_mismatches[6][6] = +{ /* CALLEE NONE CALLEE GR CALLEE FR CALLEE FU CALLEE DBL01 CALLEE DBL23 */ /* CALLER NONE */ - {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC}, + {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC}, /* CALLER GR */ - {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, R_TO_FR}, + {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR}, /* CALLER FR */ - {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC}, + {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR}, /* CALLER FU */ - {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, NO_ARG_RELOC}, + {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR}, + /* CALLER DBL01 */ + {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR}, + /* CALLER DBL23 */ + {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC}, }; static int @@ -2057,13 +1996,16 @@ type_of_mismatch (caller_bits, callee_bits, type) #define EXTRACT_ARBITS(ar,which) ((ar) >> (8-(which*2))) & 3 -#include "hppa_stubs.h" - #define NEW_INSTRUCTION(desc,insn) \ *((desc)->stub_secp)++ = (insn); \ (desc)->real_size += sizeof(int); \ bfd_set_section_size((desc)->this_bfd,(desc)->stub_sec,(desc)->real_size); +#define CURRENT_STUB_OFFSET(desc) \ + ((int)(desc)->stub_secp - (int)(desc)->stub_contents - 4) + +static boolean stubs_finished = false; + void hppa_elf_stub_finish (output_bfd) bfd *output_bfd; @@ -2073,6 +2015,9 @@ hppa_elf_stub_finish (output_bfd) /* All the stubs have been built. Finish up building */ /* stub section. Apply relocations to the section. */ + if ( stubs_finished ) + return; + for (; stub_list; stub_list = stub_list->next) { if (stub_list->stub->real_size) @@ -2140,16 +2085,17 @@ hppa_elf_stub_finish (output_bfd) free (reloc_vector); } } + stubs_finished = true; } void hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */ output_bfd, /* the output bfd */ - stub_sym, /* the stub symbol */ + target_sym, /* the target symbol */ offset) /* the offset within the stub buffer (pre-calculated) */ Elf32_hppa_Stub_description *stub_desc; bfd *output_bfd; - asymbol *stub_sym; + asymbol *target_sym; int offset; { /* Allocate a new relocation entry. */ @@ -2179,8 +2125,61 @@ hppa_elf_stub_branch_reloc (stub_desc, /* the bfd */ relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *)); BFD_ASSERT (relent.sym_ptr_ptr); - relent.sym_ptr_ptr[0] = stub_sym; - relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_ABS_CALL_17); + relent.sym_ptr_ptr[0] = target_sym; + relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_PCREL_CALL_17); + + /* Save it in the array of relocations for the stub section. */ + + memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++], + &relent, + sizeof (arelent)); +} + +void +hppa_elf_stub_reloc (stub_desc, /* the bfd */ + output_bfd, /* the output bfd */ + target_sym, /* the target symbol */ + offset, /* the offset within the stub buffer (pre-calculated) */ + type) +Elf32_hppa_Stub_description *stub_desc; +bfd *output_bfd; +asymbol *target_sym; +int offset; +elf32_hppa_reloc_type type; +{ + /* Allocate a new relocation entry. */ + arelent relent; + int size; + Elf_Internal_Shdr *rela_hdr; + + if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count) + { + if (stub_desc->stub_sec->relocation == NULL) + { + stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR; + size = sizeof (arelent) * stub_desc->relocs_allocated_cnt; + stub_desc->stub_sec->relocation = (arelent *) zalloc (size); + } + else + { + stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR; + size = sizeof (arelent) * stub_desc->relocs_allocated_cnt; + stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation, + size); + } + } + + rela_hdr = &elf_section_data(stub_desc->stub_sec)->rel_hdr; + rela_hdr->sh_size += sizeof(Elf32_External_Rela); + + /* Fill in the details. */ + relent.address = offset; + relent.addend = 0; + relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *)); + BFD_ASSERT (relent.sym_ptr_ptr); + + relent.sym_ptr_ptr[0] = target_sym; + relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, type); /* Save it in the array of relocations for the stub section. */ @@ -2199,6 +2198,7 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types) asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs"); Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, stub_sec); asymbol *stub_sym = NULL; + asymbol *target_sym = reloc_entry->sym_ptr_ptr[0]; asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text"); int i; char stub_sym_name[128]; @@ -2207,12 +2207,12 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types) { BFD_ASSERT (stub_desc == NULL); stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs"); - bfd_set_section_flags (output_bfd, + bfd_set_section_flags (abfd, stub_sec, SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_READONLY); stub_sec->output_section = output_text_section->output_section; stub_sec->output_offset = 0; - bfd_set_section_alignment (output_bfd, stub_sec, 2); + bfd_set_section_alignment (abfd, stub_sec, 2); stub_desc = new_stub (abfd, stub_sec); add_stub (stub_desc); } @@ -2247,7 +2247,7 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types) "_stub_%s_%02d_%02d_%02d_%02d_%02d\000", reloc_entry->sym_ptr_ptr[0]->name, stub_types[0], stub_types[1], stub_types[2], stub_types[3], stub_types[4]); - stub_sym->name = bfd_zalloc (output_bfd, strlen (stub_sym_name) + 1); + stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1); strcpy ((char *) stub_sym->name, stub_sym_name); stub_sym->value = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents; stub_sym->section = stub_sec; @@ -2275,62 +2275,128 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types) switch (i) { case ARG0: - NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG0); - NEW_INSTRUCTION (stub_desc, FSTWS_FARG0_M8SP); + NEW_INSTRUCTION (stub_desc, STWS_ARG0_M8SP); + NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG0); break; case ARG1: - NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1); - NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP); + NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP); + NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1); break; case ARG2: - NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1); - NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP); + NEW_INSTRUCTION (stub_desc, STWS_ARG2_M8SP); + NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG2); break; case ARG3: - NEW_INSTRUCTION (stub_desc, LDWS_M8SP_ARG1); - NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP); + NEW_INSTRUCTION (stub_desc, STWS_ARG3_M8SP); + NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG3); break; } + continue; + + case R01_TO_FR: + switch (i) + { + case ARG0: + NEW_INSTRUCTION(stub_desc, STWS_ARG0_M4SP); + NEW_INSTRUCTION(stub_desc, STWS_ARG1_M8SP); + NEW_INSTRUCTION(stub_desc, FLDDS_M8SP_FARG1); break; + default: + AR_WARN(stub_types[i],i); + break; + } + continue; + + case R23_TO_FR: + switch (i) + { + case ARG2: + NEW_INSTRUCTION(stub_desc, STWS_ARG2_M4SP); + NEW_INSTRUCTION(stub_desc, STWS_ARG3_M8SP); + NEW_INSTRUCTION(stub_desc, FLDDS_M8SP_FARG3); + break; + default: + AR_WARN(stub_types[i],i); + break; + } + continue; case FR_TO_R: switch (i) { case ARG0: - NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG0); - NEW_INSTRUCTION (stub_desc, STWS_ARG0_M8SP); + NEW_INSTRUCTION (stub_desc, FSTWS_FARG0_M8SP); + NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG0); break; case ARG1: - NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1); - NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP); + NEW_INSTRUCTION (stub_desc, FSTWS_FARG1_M8SP); + NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG1); break; case ARG2: - NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1); - NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP); + NEW_INSTRUCTION (stub_desc, FSTWS_FARG2_M8SP); + NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG2); break; case ARG3: - NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FARG1); - NEW_INSTRUCTION (stub_desc, STWS_ARG1_M8SP); + NEW_INSTRUCTION (stub_desc, FSTWS_FARG3_M8SP); + NEW_INSTRUCTION (stub_desc, LDWS_M4SP_ARG3); break; } + continue; + + case FR_TO_R01: + switch (i) + { + case ARG0: + NEW_INSTRUCTION(stub_desc, FSTDS_FARG1_M8SP); + NEW_INSTRUCTION(stub_desc, LDWS_M4SP_ARG0); + NEW_INSTRUCTION(stub_desc, LDWS_M8SP_ARG1); break; + default: + AR_WARN(stub_types[i],i); + break; + } + continue; + case FR_TO_R23: + switch (i) + { + case ARG2: + NEW_INSTRUCTION(stub_desc, FSTDS_FARG3_M8SP); + NEW_INSTRUCTION(stub_desc, LDWS_M4SP_ARG2); + NEW_INSTRUCTION(stub_desc, LDWS_M8SP_ARG3); + break; + default: + AR_WARN(stub_types[i],i); + break; } + continue; + } } + } + + NEW_INSTRUCTION (stub_desc, ADDI_M8_SP); /* generate the branch to the target routine */ NEW_INSTRUCTION (stub_desc, STW_RP_M8SP); /* First, save the return address */ - NEW_INSTRUCTION (stub_desc, BL_XXX_RP); /* set up a branch to the function */ - - /* Fix the branch to the function. We can do this with a relocation. */ - hppa_elf_stub_branch_reloc (stub_desc, - output_bfd, /* the output bfd */ - stub_sym, /* the stub symbol */ - (int) stub_desc->stub_secp - (int) stub_desc->stub_contents - 4); /* the offset within the stub buffer */ - - NEW_INSTRUCTION (stub_desc, NOP); + /* Branch to the target function. */ + /* (Make it a long call, so we do not */ + /* have to worry about generating a */ + /* long call stub.) */ + NEW_INSTRUCTION(stub_desc, LDIL_XXX_31); + hppa_elf_stub_reloc (stub_desc, + abfd, /* the output bfd */ + target_sym, /* the target symbol */ + CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */ + R_HPPA_L21); + NEW_INSTRUCTION(stub_desc,BLE_XXX_0_31); + hppa_elf_stub_reloc (stub_desc, + abfd, /* the output bfd */ + target_sym, /* the target symbol */ + CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */ + R_HPPA_ABS_CALL_R17); + NEW_INSTRUCTION(stub_desc,COPY_31_2); /* generate the code to move the return value around */ i = RETVAL; @@ -2340,13 +2406,13 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types) switch (stub_types[i]) { case R_TO_FR: - NEW_INSTRUCTION (stub_desc, LDWS_M8SP_RET0); - NEW_INSTRUCTION (stub_desc, FSTWS_FRET0_M8SP); + NEW_INSTRUCTION (stub_desc, STWS_RET0_M8SP); + NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FRET0); break; case FR_TO_R: - NEW_INSTRUCTION (stub_desc, FLDWS_M8SP_FRET0); - NEW_INSTRUCTION (stub_desc, STWS_RET0_M8SP); + NEW_INSTRUCTION (stub_desc, FSTWS_FRET0_M8SP); + NEW_INSTRUCTION (stub_desc, LDWS_M4SP_RET0); break; } } @@ -2354,7 +2420,6 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types) /* generate the ending common section for all stubs */ NEW_INSTRUCTION (stub_desc, LDW_M8SP_RP); /* restore return address */ - NEW_INSTRUCTION (stub_desc, SUBI_8_SP); /* XXX: can we assume this is a save return? */ NEW_INSTRUCTION (stub_desc, BV_N_0RP); @@ -2368,7 +2433,6 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types) arelent *reloc_entry; int stub_types[5]; { - int i; /* If the symbol is still undefined, there is */ /* no way to know if a stub is required. */ @@ -2407,22 +2471,22 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types) if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU) { - caller_loc[ARG0] = AR_FU; + caller_loc[ARG0] = AR_DBL01; caller_loc[ARG1] = AR_NO; } if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU) { - caller_loc[ARG2] = AR_FU; + caller_loc[ARG2] = AR_DBL23; caller_loc[ARG3] = AR_NO; } if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU) { - callee_loc[ARG0] = AR_FU; + callee_loc[ARG0] = AR_DBL01; callee_loc[ARG1] = AR_NO; } if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU) { - callee_loc[ARG2] = AR_FU; + callee_loc[ARG2] = AR_DBL23; callee_loc[ARG3] = AR_NO; } @@ -2432,10 +2496,7 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types) stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS); stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE); - /* XXX for now, just report a */ - /* warning */ - - /* But, when we start building stubs, here are the steps involved: */ + /* Steps involved in building stubs: */ /* 1. Determine what argument registers need to relocated. This */ /* step is already done here. */ /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */ @@ -2448,7 +2509,7 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types) /* 4. Change the instruction of the original branch into a branch to */ /* the stub routine. */ /* 5. Build a relocation entry for the instruction of the original */ - /* branch to be R_HPPA_ABS_CALL to the stub routine. */ + /* branch to be R_HPPA_PCREL_CALL to the stub routine. */ if (stub_types[0] @@ -2483,10 +2544,243 @@ hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types) } asymbol * -hppa_elf_stub_check (abfd, output_bfd, reloc_entry) +hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data) + bfd *abfd; + bfd *output_bfd; + arelent *reloc_entry; + asymbol *symbol; + unsigned *data; +{ + asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs"); + Elf32_hppa_Stub_description *stub_desc = find_stubs (abfd, stub_sec); + asymbol *stub_sym = NULL; + asymbol *target_sym = reloc_entry->sym_ptr_ptr[0]; + asymbol *return_sym = NULL; + asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text"); + char stub_sym_name[128]; + int milli = false; + + if (!stub_sec) + { + BFD_ASSERT (stub_desc == NULL); + stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs"); + bfd_set_section_flags (abfd, + stub_sec, + SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_READONLY); + stub_sec->output_section = output_text_section->output_section; + stub_sec->output_offset = 0; + /* set up the ELF section header for this new section. */ + /* This is basically the same processing as elf_make_sections() */ + /* (elf_make_sections() is static so it is not accessible from */ + /* here.) */ + + { + Elf_Internal_Shdr *this_hdr; + this_hdr = &elf_section_data (stub_sec)->this_hdr; + + this_hdr->sh_addr = stub_sec->vma; + this_hdr->sh_size = stub_sec->_raw_size; + /* contents already set by elf_set_section_contents */ + + if (stub_sec->flags & SEC_RELOC) + { + /* emit a reloc section, and thus strtab and symtab... */ + Elf_Internal_Shdr *rela_hdr; + int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; + + rela_hdr = &elf_section_data (stub_sec)->rel_hdr; + + /* orelocation has the data, reloc_count has the count... */ + if (use_rela_p) + { + rela_hdr->sh_type = SHT_RELA; + rela_hdr->sh_entsize = sizeof (Elf32_External_Rela); + } + else + /* REL relocations */ + { + rela_hdr->sh_type = SHT_REL; + rela_hdr->sh_entsize = sizeof (Elf32_External_Rel); + } + rela_hdr->sh_flags = 0; + rela_hdr->sh_addr = 0; + rela_hdr->sh_offset = 0; + rela_hdr->sh_addralign = 0; + rela_hdr->size = 0; + } + if (stub_sec->flags & SEC_ALLOC) + { + this_hdr->sh_flags |= SHF_ALLOC; + if (stub_sec->flags & SEC_LOAD) + { + /* @@ Do something with sh_type? */ + } + } + if (!(stub_sec->flags & SEC_READONLY)) + this_hdr->sh_flags |= SHF_WRITE; + + if (stub_sec->flags & SEC_CODE) + this_hdr->sh_flags |= SHF_EXECINSTR; + } + + bfd_set_section_alignment (abfd, stub_sec, 2); + stub_desc = new_stub (abfd, stub_sec); + add_stub (stub_desc); + } + + if (!stub_desc) + { + stub_desc = new_stub (abfd, stub_sec); + add_stub (stub_desc); + } + + /* allocate some space to write the stub */ + + if (!stub_desc->stub_contents) + { + stub_desc->allocated_size = STUB_BUFFER_INCR; + stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR); + } + else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE) + { + stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR; + stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents, + stub_desc->allocated_size); + } + + stub_desc->stub_secp = (int *) (stub_desc->stub_contents + stub_desc->real_size); + + /* create a symbol to point to this stub */ + stub_sym = bfd_make_empty_symbol (abfd); + sprintf (stub_sym_name, + "_lb_stub_%s\000", reloc_entry->sym_ptr_ptr[0]->name); + stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1); + strcpy ((char *) stub_sym->name, stub_sym_name); + stub_sym->value = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents; + stub_sym->section = stub_sec; + stub_sym->flags = BSF_LOCAL | BSF_FUNCTION; + + /* create a symbol to point to the return location */ + return_sym = bfd_make_empty_symbol (abfd); + sprintf (stub_sym_name, + "_lb_rtn_%s\000", reloc_entry->sym_ptr_ptr[0]->name); + return_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1); + strcpy ((char *) return_sym->name, stub_sym_name); + return_sym->value = reloc_entry->address + 8; + return_sym->section = stub_sec; + return_sym->flags = BSF_LOCAL | BSF_FUNCTION; + + /* redirect the original relocation from the old symbol (a function) */ + /* to the stub (the stub calls the function). */ + /* XXX do we need to change the relocation type? */ + reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *)); + reloc_entry->sym_ptr_ptr[0] = stub_sym; + reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17); + + /* Build the stub */ + + /* A millicode call? */ + /* If so, the return address comes in on r31 rather than r2 (rp) so a */ + /* slightly different code sequence is needed. */ + if ( ((*data & 0x03e00000) >> 21) == 31 ) + milli = true; + + /* 1. initialization for the call. */ + + NEW_INSTRUCTION(stub_desc, LDSID_31_RP); + NEW_INSTRUCTION(stub_desc, MTSP_RP_SR0); + if ( !milli ) + { + NEW_INSTRUCTION(stub_desc, COPY_31_2); + + NEW_INSTRUCTION(stub_desc, LDIL_XXX_31); + hppa_elf_stub_reloc (stub_desc, + abfd, /* the output bfd */ + target_sym, /* the target symbol */ + CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */ + R_HPPA_L21); + + /* 2. Make the call. */ + + NEW_INSTRUCTION(stub_desc,BE_N_XXX_0_31); + hppa_elf_stub_reloc (stub_desc, + abfd, /* the output bfd */ + target_sym, /* the target symbol */ + CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */ + R_HPPA_ABS_CALL_R17); + /* 3. Branch back to the original location. */ + /* (accomplished with the COPY_31_2 instruction) */ + } + else + { + NEW_INSTRUCTION(stub_desc, STW_31_M24SP); + NEW_INSTRUCTION(stub_desc, LDIL_XXX_RP); + hppa_elf_stub_reloc (stub_desc, + abfd, /* the output bfd */ + target_sym, /* the target symbol */ + CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */ + R_HPPA_L21); + + /* 2. Make the call. */ + + NEW_INSTRUCTION(stub_desc,BLE_XXX_0_RP); + hppa_elf_stub_reloc (stub_desc, + abfd, /* the output bfd */ + target_sym, /* the target symbol */ + CURRENT_STUB_OFFSET(stub_desc), /* offset in stub buffer */ + R_HPPA_ABS_CALL_R17); + NEW_INSTRUCTION(stub_desc,COPY_31_2); + + /* 3. Branch back to the original location. */ + NEW_INSTRUCTION(stub_desc, LDW_M24SP_RP); + NEW_INSTRUCTION(stub_desc, BV_N_0RP); + } + + return stub_sym; +} + +int +hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn) + bfd *abfd; + asection *asec; + arelent *reloc_entry; + asymbol *symbol; + unsigned insn; +{ + long sym_value = get_symbol_value(symbol); + int fmt = reloc_entry->howto->bitsize; + unsigned char op = get_opcode(insn); + unsigned raddr; + +#define too_far(val,num_bits) ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits))) + + BFD_ASSERT(fmt == hppa_elf_insn2fmt(reloc_entry->howto->type,insn)); + + switch (op) + { + case BL: + raddr = + reloc_entry->address + asec->output_offset + asec->output_section->vma; + if ( too_far(sym_value - raddr,fmt+1) ) + { +#ifdef DETECT_STUBS + fprintf(stderr,"long_branch needed on BL insn: abfd=%s,sym=%s,distance=0x%x\n",abfd->filename,symbol->name,sym_value - reloc_entry->address); +#endif + return 1; + } + break; + } + return 0; +} + +asymbol * +hppa_elf_stub_check (abfd, output_bfd, input_section, reloc_entry, symbol, hit_data) bfd *abfd; bfd *output_bfd; + asection *input_section; arelent *reloc_entry; + asymbol *symbol; + bfd_byte *hit_data; { int stub_types[5]; @@ -2533,7 +2827,15 @@ hppa_elf_stub_check (abfd, output_bfd, reloc_entry) if (hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types)) { /* generate a stub */ - return hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, stub_types); + return hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry, + stub_types); + } + if (hppa_elf_long_branch_needed_p (abfd, input_section, reloc_entry, symbol,*(unsigned *)hit_data)) + { + /* generate a stub */ + return hppa_elf_build_long_branch_stub (abfd, output_bfd, + reloc_entry, symbol, + (unsigned *)hit_data); } break; @@ -2547,7 +2849,8 @@ hppa_elf_stub_check (abfd, output_bfd, reloc_entry) #define STUB_SYM_BUFFER_INC 5 asymbol * -hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt) +hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec, syms, new_sym_cnt) + bfd *stub_bfd; bfd *abfd; bfd *output_bfd; asection *asec; @@ -2628,13 +2931,44 @@ hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt) { /* generate a stub */ /* keep track of the new symbol */ + + asymbol *r; + if (new_cnt == new_max) { new_max += STUB_SYM_BUFFER_INC; new_syms = (asymbol *) realloc (new_syms, new_max * sizeof (asymbol)); } - new_syms[new_cnt++] = *(hppa_elf_build_arg_reloc_stub (abfd, output_bfd, rle, stub_types)); + r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd, rle, + stub_types); + new_syms[new_cnt++] = *r; } + /* We need to retrieve the section contents to check for */ + /* long branch stubs. */ + { + unsigned insn; + + bfd_get_section_contents(abfd, asec, &insn, rle->address, sizeof(insn)); + if (hppa_elf_long_branch_needed_p (abfd, asec, rle, rle->sym_ptr_ptr[0], insn)) + { + /* generate a stub */ + /* keep track of the new symbol */ + + asymbol *r; + + if (new_cnt == new_max) + { + new_max += STUB_SYM_BUFFER_INC; + new_syms = (asymbol *) realloc (new_syms, new_max * sizeof (asymbol)); + } + r = hppa_elf_build_long_branch_stub (stub_bfd, + output_bfd, + rle, + rle->sym_ptr_ptr[0], + &insn); + new_syms[new_cnt++] = *r; + } + } break; default: @@ -2647,12 +2981,37 @@ hppa_look_for_stubs_in_section (abfd, output_bfd, asec, syms, new_sym_cnt) return new_syms; } -int -hppa_look_for_stubs (abfd, output_bfd) - bfd *abfd; - bfd *output_bfd; + +char *linker_stubs = NULL; +int linker_stubs_size = 0; +int linker_stubs_max_size = 0; +#define STUB_ALLOC_INCR 100 + +boolean +DEFUN (hppa_elf_set_section_contents, (abfd, section, location, offset, count), + bfd * abfd AND + sec_ptr section AND + PTR location AND + file_ptr offset AND + bfd_size_type count) { - /* bfd_map_over_sections(abfd,hppa_look_for_stubs_in_section,(PTR)output_bfd,NULL); */ + if ( strcmp(section->name, ".hppa_linker_stubs") == 0 ) + { + if ( linker_stubs_max_size < offset + count ) + { + linker_stubs_max_size = offset + count + STUB_ALLOC_INCR; + linker_stubs = (char *)realloc(linker_stubs, linker_stubs_max_size); + } + + if ( offset + count > linker_stubs_size ) + linker_stubs_size = offset + count; + + memcpy(linker_stubs + offset,location,count); + return (true); + } + else + return bfd_elf32_set_section_contents (abfd, section, location, + offset, count); } boolean @@ -2703,9 +3062,281 @@ DEFUN (elf_info_to_howto, (abfd, cache_ptr, dst), arelent * cache_ptr AND Elf32_Internal_Rela * dst) { - abort (); + BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED); + cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)]; +} + +static void +DEFUN (elf32_hppa_backend_symbol_processing, (abfd, sym), + bfd * abfd AND + asymbol * sym) +{ + /* Is this a definition of $global$? If so, keep it because it will be + needed if any relocations are performed. */ + + if (!strcmp (sym->name, "$global$") + && sym->section != &bfd_und_section) + { + global_symbol = sym; + } +} + +#define elf_backend_symbol_processing elf32_hppa_backend_symbol_processing + +struct elf32_hppa_symextn_map_struct +{ + int old_index; + bfd *bfd; + asymbol *sym; + int new_index; +}; + +static struct elf32_hppa_symextn_map_struct *elf32_hppa_symextn_map; +static int elf32_hppa_symextn_map_size; + +static boolean +DEFUN (elf32_hppa_backend_symbol_table_processing, (abfd, esyms,symcnt), + bfd * abfd AND + elf32_symbol_type *esyms AND + int symcnt) +{ + Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME); + int i; + int current_sym_idx = 0; + + /* If the symbol extension section does not exist, all the symbol */ + /* all the symbol extension information is assumed to be zero. */ + + if ( symextn_hdr == NULL ) + { + for ( i = 0; i < symcnt; i++ ) + { + esyms[i].tc_data.hppa_arg_reloc = 0; + } + return (true); + } + + /* allocate a buffer of the appropriate size for the symextn section */ + + symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size); + symextn_hdr->size = symextn_hdr->sh_size; + + /* read in the symextn section */ + + if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1) + { + bfd_error = system_call_error; + return (false); + } + if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->size, abfd) + != symextn_hdr->size) + { + free ((PTR)symextn_hdr->contents); + bfd_error = system_call_error; + return (false); + } + + /* parse the entries, updating the symtab entries as we go */ + + for ( i = 0; i < symextn_hdr->size / sizeof(symext_entryS); i++ ) + { + symext_entryS *seP = ((symext_entryS *)symextn_hdr->contents) + i; + int se_value = ELF32_HPPA_SX_VAL(*seP); + int se_type = ELF32_HPPA_SX_TYPE(*seP); + + switch ( se_type ) + { + case HPPA_SXT_NULL: + break; + + case HPPA_SXT_SYMNDX: + if ( se_value >= symcnt ) + { + bfd_error = bad_value; + bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index"); + return (false); + } + current_sym_idx = se_value - 1; + break; + + case HPPA_SXT_ARG_RELOC: + esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value; + break; + + default: + bfd_error = bad_value; + bfd_perror("elf32_hppa_backend_symbol_table_processing"); + return (false); + } + } + return (true); +} + +#define elf_backend_symbol_table_processing elf32_hppa_backend_symbol_table_processing + +static boolean +DEFUN (elf32_hppa_backend_section_processing, (abfd, secthdr), + bfd * abfd AND + Elf32_Internal_Shdr *secthdr) +{ + int i,j,k; + + if ( secthdr->sh_type == SHT_HPPA_SYMEXTN ) + { + for ( i = 0; i < secthdr->size / sizeof(symext_entryS); i++ ) + { + symext_entryS *seP = ((symext_entryS *)secthdr->contents) + i; + int se_value = ELF32_HPPA_SX_VAL(*seP); + int se_type = ELF32_HPPA_SX_TYPE(*seP); + + switch ( se_type ) + { + case HPPA_SXT_NULL: + break; + + case HPPA_SXT_SYMNDX: + for ( j = 0; j < abfd->symcount; j++ ) + { + /* locate the map entry for this symbol, if there is one. */ + /* modify the symbol extension section symbol index entry */ + /* to reflect the new symbol table index */ + + for ( k = 0; k < elf32_hppa_symextn_map_size; k++ ) + { + if ( elf32_hppa_symextn_map[k].old_index == se_value + && elf32_hppa_symextn_map[k].bfd == abfd->outsymbols[j]->the_bfd + && elf32_hppa_symextn_map[k].sym == abfd->outsymbols[j] ) + { + bfd_put_32(abfd, + ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, j), + (char *)seP); + } + } + } + break; + + case HPPA_SXT_ARG_RELOC: + break; + + default: + bfd_error = bad_value; + bfd_perror("elf32_hppa_backend_section_processing"); + return (false); + } + } + } + return true; +} + +#define elf_backend_section_processing elf32_hppa_backend_section_processing + +static boolean +DEFUN (elf32_hppa_backend_section_from_shdr, (abfd, hdr, name), + bfd * abfd AND + Elf32_Internal_Shdr *hdr AND + char * name) +{ + asection *newsect; + + if ( hdr->sh_type == SHT_HPPA_SYMEXTN ) + { + BFD_ASSERT ( strcmp(name,".hppa_symextn") == 0 ); + + /* Bits that get saved. This one is real. */ + if (!hdr->rawdata) + { + newsect = bfd_make_section (abfd, name); + if (newsect != NULL) + { + newsect->vma = hdr->sh_addr; + newsect->_raw_size = hdr->sh_size; + newsect->filepos = hdr->sh_offset; /* so we can read back the bits */ + newsect->flags |= SEC_HAS_CONTENTS; + newsect->alignment_power = hdr->sh_addralign; + + if (hdr->sh_flags & SHF_ALLOC) + { + newsect->flags |= SEC_ALLOC; + newsect->flags |= SEC_LOAD; + } + + if (!(hdr->sh_flags & SHF_WRITE)) + newsect->flags |= SEC_READONLY; + + if (hdr->sh_flags & SHF_EXECINSTR) + newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */ + else + newsect->flags |= SEC_DATA; + + hdr->rawdata = (void *) newsect; + } + } + return true; + } + return false; +} + +#define elf_backend_section_from_shdr elf32_hppa_backend_section_from_shdr + +static boolean +DEFUN (elf32_hppa_backend_fake_sections, (abfd, secthdr, asect), + bfd * abfd AND + Elf_Internal_Shdr *secthdr AND + asection *asect) +{ + + if ( strcmp(asect->name, ".hppa_symextn") == 0 ) + { + secthdr->sh_type = SHT_HPPA_SYMEXTN; + secthdr->sh_flags = 0; + secthdr->sh_info = elf_section_data(asect)->rel_hdr.sh_link; + secthdr->sh_link = elf_onesymtab(abfd); + return true; + } + + if (!strcmp (asect->name, ".hppa_unwind")) + { + secthdr->sh_type = SHT_PROGBITS; + /* Unwind descriptors are not part of the program memory image. */ + secthdr->sh_flags = 0; + secthdr->sh_info = 0; + secthdr->sh_link = 0; + secthdr->sh_entsize = 16; + return true; + } + + return false; +} + +#define elf_backend_fake_sections elf32_hppa_backend_fake_sections + +static boolean +DEFUN (elf32_hppa_backend_section_from_bfd_section, (abfd, hdr, asect), + bfd *abfd AND + Elf32_Internal_Shdr *hdr AND + asection *asect) +{ + + if ( hdr->sh_type == SHT_HPPA_SYMEXTN ) + { + if (hdr->rawdata) + { + if (((struct sec *) (hdr->rawdata)) == asect) + { + BFD_ASSERT( strcmp(asect->name, ".hppa_symextn") == 0 ); + return true; + } + } + } + + return false; } +#define elf_backend_section_from_bfd_section elf32_hppa_backend_section_from_bfd_section + +#define bfd_generic_get_section_contents hppa_elf_get_section_contents +#define bfd_elf32_set_section_contents hppa_elf_set_section_contents + #define TARGET_BIG_SYM bfd_elf32_hppa_vec #define TARGET_BIG_NAME "elf32-hppa" #define ELF_ARCH bfd_arch_hppa |