From c46b75158b4d6682705d556b9f69bd7fb6c11a18 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sun, 14 Jan 2001 07:03:49 +0000 Subject: [PATCH] Use SEGREL32 relocs for elf32-hppa unwind. --- bfd/ChangeLog | 16 +++++ bfd/cache.c | 4 +- bfd/elf-hppa.h | 148 +++++++++++++++++++++---------------------- bfd/elf32-hppa.c | 136 +++++++++++++++++++++++++++++++++++++-- gas/ChangeLog | 3 + gas/config/tc-hppa.c | 8 +-- 6 files changed, 229 insertions(+), 86 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7c3243980a..3fb1a51feb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,21 @@ 2001-01-14 Alan Modra + * elf32-hppa.c (elf32_hppa_link_hash_table): Add text_segment_base, + and data_segment_base fields. + (elf32_hppa_link_hash_table_create ): Init them. + (elf32_hppa_check_relocs): Update comments. + (hppa_record_segment_addr): New function. + (elf32_hppa_relocate_section): Call it. + (final_link_relocate): Handle R_PARISC_SEGREL32. + (elf32_hppa_final_link): New function. + (bfd_elf32_bfd_final_link): Define to call it. + (hppa_unwind_entry_compare): New function. + * cache.c (bfd_open_file): Create files in write+read mode. + + * elf-hppa.h (elf_hppa_howto_table): Set bitsize value for + SEGREL32 and numerous other relocs. Change duplicate + R_PARISC_NONE relocs to R_PARISC_UNIMPLEMENTED. + * opncls.c (bfd_fdopenr): Add parens like the comment says around O_ACCMODE. diff --git a/bfd/cache.c b/bfd/cache.c index c4becf8e32..063373c7f4 100644 --- a/bfd/cache.c +++ b/bfd/cache.c @@ -1,5 +1,5 @@ /* BFD library -- caching of file descriptors. - Copyright 1990, 91, 92, 93, 94, 95, 1996, 2000 + Copyright 1990, 91, 92, 93, 94, 95, 1996, 2000, 2001 Free Software Foundation, Inc. Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com). @@ -311,7 +311,7 @@ bfd_open_file (abfd) if (stat (abfd->filename, &s) == 0 && s.st_size != 0) unlink (abfd->filename); #endif - abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WB); + abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB); abfd->opened_once = true; } break; diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index ad049ddcc2..006a2c4a1f 100644 --- a/bfd/elf-hppa.h +++ b/bfd/elf-hppa.h @@ -1,5 +1,5 @@ /* Common code for PA ELF implementations. - Copyright (C) 1999, 2000 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -143,9 +143,9 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_DPREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL21L", false, 0, 0, false }, - { R_PARISC_DPREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DPREL14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL14WR", false, 0, 0, false }, - { R_PARISC_DPREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DPREL14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DPREL14DR", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, @@ -190,7 +190,7 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = /* 40 */ { R_PARISC_SETBASE, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SETBASE", false, 0, 0, false }, - { R_PARISC_SECREL32, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_SECREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SECREL32", false, 0, 0, false }, { R_PARISC_BASEREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL21L", false, 0, 0, false }, @@ -207,9 +207,9 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = /* 48 */ { R_PARISC_SEGBASE, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SEGBASE", false, 0, 0, false }, - { R_PARISC_SEGREL32, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_SEGREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SEGREL32", false, 0, 0, false }, - { R_PARISC_PLTOFF21L, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF21L", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, @@ -217,16 +217,16 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_PLTOFF14R, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14R", false, 0, 0, false }, - { R_PARISC_PLTOFF14F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF14F, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14F", false, 0, 0, false }, /* 56 */ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR32, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR32, 0, 0, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR32", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR21L, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR21L", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, @@ -234,12 +234,12 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR14R, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14R", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, /* 64 */ - { R_PARISC_FPTR64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_FPTR64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_FPTR64", false, 0, 0, false }, { R_PARISC_PLABEL32, 0, 0, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLABEL32", false, 0, 0, false }, @@ -256,81 +256,81 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, /* 72 */ - { R_PARISC_PCREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL64", false, 0, 0, false }, - { R_PARISC_PCREL22C, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL22C, 0, 0, 22, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL22C", false, 0, 0, false }, - { R_PARISC_PCREL22F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL22F, 0, 0, 22, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL22F", false, 0, 0, false }, - { R_PARISC_PCREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL14WR", false, 0, 0, false }, - { R_PARISC_PCREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL14DR", false, 0, 0, false }, - { R_PARISC_PCREL16F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL16F, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL16F", false, 0, 0, false }, - { R_PARISC_PCREL16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL16WF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL16WF", false, 0, 0, false }, - { R_PARISC_PCREL16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PCREL16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PCREL16DF", false, 0, 0, false }, /* 80 */ - { R_PARISC_DIR64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DIR64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR64", false, 0, 0, false }, - { R_PARISC_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_PARISC_NONE", false, 0, 0, false }, - { R_PARISC_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield, - bfd_elf_generic_reloc, "R_PARISC_NONE", false, 0, 0, false }, - { R_PARISC_DIR14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, + { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, + { R_PARISC_DIR14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR14WR", false, 0, 0, false }, - { R_PARISC_DIR14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DIR14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR14DR", false, 0, 0, false }, - { R_PARISC_DIR16F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DIR16F, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR16F", false, 0, 0, false }, - { R_PARISC_DIR16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DIR16WF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR16WF", false, 0, 0, false }, - { R_PARISC_DIR16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DIR16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DIR16DF", false, 0, 0, false }, /* 88 */ - { R_PARISC_GPREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_GPREL64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL64", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_DLTREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DLTREL14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTREL14WR", false, 0, 0, false }, - { R_PARISC_DLTREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DLTREL14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTREL14DR", false, 0, 0, false }, - { R_PARISC_GPREL16F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_GPREL16F, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL16F", false, 0, 0, false }, - { R_PARISC_GPREL16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_GPREL16WF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL16WF", false, 0, 0, false }, - { R_PARISC_GPREL16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_GPREL16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_GPREL16DF", false, 0, 0, false }, /* 96 */ - { R_PARISC_LTOFF64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF64", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_DLTIND14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DLTIND14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTIND14WR", false, 0, 0, false }, - { R_PARISC_DLTIND14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_DLTIND14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_DLTIND14DR", false, 0, 0, false }, - { R_PARISC_LTOFF16F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF16F, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF16F", false, 0, 0, false }, - { R_PARISC_LTOFF16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF16WF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF16DF", false, 0, 0, false }, - { R_PARISC_LTOFF16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF16DF", false, 0, 0, false }, /* 104 */ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_BASEREL14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_BASEREL14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL14WR", false, 0, 0, false }, - { R_PARISC_BASEREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_BASEREL14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_BASEREL14DR", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, @@ -341,38 +341,38 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, /* 112 */ - { R_PARISC_SEGREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_SEGREL64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_SEGREL64", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_PLTOFF14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14WR", false, 0, 0, false }, - { R_PARISC_PLTOFF14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF14DR", false, 0, 0, false }, - { R_PARISC_PLTOFF16F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF16F, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF16F", false, 0, 0, false }, - { R_PARISC_PLTOFF16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF16WF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF16WF", false, 0, 0, false }, - { R_PARISC_PLTOFF16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_PLTOFF16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_PLTOFF16DF", false, 0, 0, false }, /* 120 */ - { R_PARISC_LTOFF_FPTR64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14WR", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14DR", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR16F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR16F, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16F", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR16WF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16WF", false, 0, 0, false }, - { R_PARISC_LTOFF_FPTR16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_FPTR16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, /* 128 */ { R_PARISC_COPY, 0, 0, 0, false, 0, complain_overflow_bitfield, @@ -428,9 +428,9 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = /* 152 */ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_TPREL32, 0, 0, 0, false, 0, complain_overflow_dont, + { R_PARISC_TPREL32, 0, 0, 32, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_TPREL32", false, 0, 0, false }, - { R_PARISC_TPREL21L, 0, 0, 0, false, 0, complain_overflow_dont, + { R_PARISC_TPREL21L, 0, 0, 21, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_TPREL21L", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, @@ -438,7 +438,7 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_TPREL14R, 0, 0, 0, false, 0, complain_overflow_dont, + { R_PARISC_TPREL14R, 0, 0, 14, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_TPREL14R", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, @@ -447,7 +447,7 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_LTOFF_TP21L, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP21L, 0, 0, 21, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP21L", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, @@ -455,9 +455,9 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_LTOFF_TP14R, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP14R, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_LTOFF_TP14F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP14F, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14F", false, 0, 0, false }, /* 168 */ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, @@ -562,38 +562,38 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, /* 216 */ - { R_PARISC_TPREL64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_TPREL64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL64", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_TPREL14WR, 0, 0, 0, false, 0, complain_overflow_dont, + { R_PARISC_TPREL14WR, 0, 0, 14, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_TPREL14WR", false, 0, 0, false }, - { R_PARISC_TPREL14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_TPREL14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL14DR", false, 0, 0, false }, - { R_PARISC_TPREL16F, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_TPREL16F, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL16F", false, 0, 0, false }, - { R_PARISC_TPREL16WF, 0, 0, 0, false, 0, complain_overflow_dont, + { R_PARISC_TPREL16WF, 0, 0, 16, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_TPREL16WF", false, 0, 0, false }, - { R_PARISC_TPREL16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_TPREL16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_TPREL16DF", false, 0, 0, false }, /* 224 */ - { R_PARISC_LTOFF_TP64, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP64, 0, 0, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP64", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, { R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false }, - { R_PARISC_LTOFF_TP14WR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP14WR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14WR", false, 0, 0, false }, - { R_PARISC_LTOFF_TP14DR, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP14DR, 0, 0, 14, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14DR", false, 0, 0, false }, - { R_PARISC_LTOFF_TP16F, 0, 0, 0, false, 0, complain_overflow_dont, + { R_PARISC_LTOFF_TP16F, 0, 0, 16, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16F", false, 0, 0, false }, - { R_PARISC_LTOFF_TP16WF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP16WF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16WF", false, 0, 0, false }, - { R_PARISC_LTOFF_TP16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, + { R_PARISC_LTOFF_TP16DF, 0, 0, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16DF", false, 0, 0, false }, /* 232 */ { R_PARISC_GNU_VTENTRY, 0, 0, 0, false, 0, complain_overflow_dont, diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index e67a1ed5f6..10253fef71 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1,5 +1,5 @@ /* BFD back-end for HP PA-RISC ELF files. - Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 + Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc. Original code by @@ -272,6 +272,11 @@ struct elf32_hppa_link_hash_table { asection *sdynbss; asection *srelbss; + /* Used during a final link to store the base of the text and data + segments so that we can perform SEGREL relocations. */ + bfd_vma text_segment_base; + bfd_vma data_segment_base; + /* Whether we support multiple sub-spaces for shared libs. */ unsigned int multi_subspace:1; @@ -369,6 +374,12 @@ static boolean clobber_millicode_symbols static boolean elf32_hppa_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); +static boolean elf32_hppa_final_link + PARAMS ((bfd *, struct bfd_link_info *)); + +static void hppa_record_segment_addr + PARAMS ((bfd *, asection *, PTR)); + static bfd_reloc_status_type final_link_relocate PARAMS ((asection *, bfd_byte *, const Elf_Internal_Rela *, bfd_vma, struct elf32_hppa_link_hash_table *, asection *, @@ -378,6 +389,9 @@ static boolean elf32_hppa_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); +static int hppa_unwind_entry_compare + PARAMS ((const PTR, const PTR)); + static boolean elf32_hppa_finish_dynamic_symbol PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); @@ -515,6 +529,8 @@ elf32_hppa_link_hash_table_create (abfd) ret->srelplt = NULL; ret->sdynbss = NULL; ret->srelbss = NULL; + ret->text_segment_base = (bfd_vma) -1; + ret->data_segment_base = (bfd_vma) -1; ret->multi_subspace = 0; ret->has_12bit_branch = 0; ret->has_17bit_branch = 0; @@ -1305,7 +1321,7 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs) break; case R_PARISC_SEGBASE: /* Used to set segment base. */ - case R_PARISC_SEGREL32: /* Relative reloc. */ + case R_PARISC_SEGREL32: /* Relative reloc, used for unwind. */ case R_PARISC_PCREL14F: /* PC relative load/store. */ case R_PARISC_PCREL14R: case R_PARISC_PCREL17R: /* External branches. */ @@ -1347,7 +1363,7 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs) /* Fall through. */ #endif - case R_PARISC_DIR32: /* .word, PARISC.unwind relocs. */ + case R_PARISC_DIR32: /* .word relocs. */ /* We may want to output a dynamic relocation later. */ need_entry = NEED_DYNREL; break; @@ -3095,6 +3111,76 @@ elf32_hppa_build_stubs (info) return true; } +/* Perform a final link. */ + +static boolean +elf32_hppa_final_link (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + asection *s; + + /* Invoke the regular ELF garbage collecting linker to do all the + work. */ + if (!_bfd_elf32_gc_common_final_link (abfd, info)) + return false; + + /* If we're producing a final executable, sort the contents of the + unwind section. Magic section names, but this is much safer than + having elf32_hppa_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 / 16, 16, hppa_unwind_entry_compare); + + if (! bfd_set_section_contents (abfd, s, contents, (file_ptr) 0, size)) + return false; + } + return true; +} + +/* Record the lowest address for the data and text segments. */ + +static void +hppa_record_segment_addr (abfd, section, data) + bfd *abfd ATTRIBUTE_UNUSED; + asection *section; + PTR data; +{ + struct elf32_hppa_link_hash_table *hplink; + + hplink = (struct elf32_hppa_link_hash_table *) data; + + if ((section->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)) + { + bfd_vma value = section->vma - section->filepos; + + if ((section->flags & SEC_READONLY) != 0) + { + if (value < hplink->text_segment_base) + hplink->text_segment_base = value; + } + else + { + if (value < hplink->data_segment_base) + hplink->data_segment_base = value; + } + } +} + /* Perform a relocation as part of a final link. */ static bfd_reloc_status_type @@ -3220,6 +3306,13 @@ final_link_relocate (input_section, contents, rel, value, hplink, sym_sec, h) value -= elf_gp (input_section->output_section->owner); break; + case R_PARISC_SEGREL32: + if ((sym_sec->flags & SEC_CODE) != 0) + value -= hplink->text_segment_base; + else + value -= hplink->data_segment_base; + break; + default: break; } @@ -3579,6 +3672,15 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, + hplink->sgot->output_section->vma); break; + case R_PARISC_SEGREL32: + /* If this is the first SEGREL relocation, then initialize + the segment base values. */ + if (hplink->text_segment_base == (bfd_vma) -1) + bfd_map_over_sections (output_bfd, + hppa_record_segment_addr, + hplink); + break; + case R_PARISC_PLABEL14R: case R_PARISC_PLABEL21L: case R_PARISC_PLABEL32: @@ -3823,6 +3925,32 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, return true; } +/* 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; +} + /* Finish up dynamic symbol handling. We set the contents of various dynamic sections here. */ @@ -4125,7 +4253,7 @@ elf32_hppa_elf_get_symbol_type (elf_sym, type) #define elf_info_to_howto_rel elf_hppa_info_to_howto_rel /* Stuff for the BFD linker. */ -#define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link +#define bfd_elf32_bfd_final_link elf32_hppa_final_link #define bfd_elf32_bfd_link_hash_table_create elf32_hppa_link_hash_table_create #define elf_backend_add_symbol_hook elf32_hppa_add_symbol_hook #define elf_backend_adjust_dynamic_symbol elf32_hppa_adjust_dynamic_symbol diff --git a/gas/ChangeLog b/gas/ChangeLog index 11bc523c66..b52480cea9 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,8 @@ 2001-01-14 Alan Modra + * config/tc-hppa.c (pa_build_unwind_subspace): Use SEGREL32 for + both 32 and 64 bit ELF. + * config/tc-hppa.c (pa_ip): Store `a' flag in bit zero of operand and don't bother storing `m' for "ce" completer. Tidy handling of 'J' and 'K' operands to suit. Handle '<' and '>' operands. diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 69c1e044a2..ab45da6ea4 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1,5 +1,5 @@ /* tc-hppa.c -- Assemble for the PA - Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 + Copyright 1989, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -6056,11 +6056,7 @@ pa_build_unwind_subspace (call_info) if (now_seg != text_section) return; - if (bfd_get_arch_info (stdoutput)->bits_per_address == 32) - reloc = R_PARISC_DIR32; - else - reloc = R_PARISC_SEGREL32; - + reloc = R_PARISC_SEGREL32; save_seg = now_seg; save_subseg = now_subseg; /* Get into the right seg/subseg. This may involve creating