diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 22 | ||||
-rw-r--r-- | bfd/cpu-d10v.c | 55 | ||||
-rw-r--r-- | bfd/cpu-d30v.c | 35 | ||||
-rw-r--r-- | bfd/cpu-i370.c | 77 | ||||
-rw-r--r-- | bfd/cpu-xstormy16.c | 24 | ||||
-rw-r--r-- | bfd/elf32-arc.c | 210 | ||||
-rw-r--r-- | bfd/elf32-d10v.c | 441 | ||||
-rw-r--r-- | bfd/elf32-d30v.c | 551 | ||||
-rw-r--r-- | bfd/elf32-dlx.c | 446 | ||||
-rw-r--r-- | bfd/elf32-i370.c | 381 | ||||
-rw-r--r-- | bfd/elf32-i960.c | 171 | ||||
-rw-r--r-- | bfd/elf32-ip2k.c | 1228 | ||||
-rw-r--r-- | bfd/elf32-m32r.c | 1287 | ||||
-rw-r--r-- | bfd/elf32-mcore.c | 312 | ||||
-rw-r--r-- | bfd/elf32-openrisc.c | 216 | ||||
-rw-r--r-- | bfd/elf32-or32.c | 547 | ||||
-rw-r--r-- | bfd/elf32-pj.c | 236 | ||||
-rw-r--r-- | bfd/elf32-v850.c | 1445 | ||||
-rw-r--r-- | bfd/elf32-xstormy16.c | 244 |
19 files changed, 3595 insertions, 4333 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index aa7a2588396..72e3bdf42ee 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,25 @@ +2005-07-01 Nick Clifton <nickc@redhat.com> + + * cpu-d10v.c: Update to ISO C90 style function declarations and + fix formatting. + * cpu-d30v.c: Likewsie. + * cpu-i370.c: Likewsie. + * cpu-xstormy16.c: Likewsie. + * elf32-arc.c: Likewsie. + * elf32-d10v.c: Likewsie. + * elf32-d30v.c: Likewsie. + * elf32-dlx.c: Likewsie. + * elf32-i370.c: Likewsie. + * elf32-i960.c: Likewsie. + * elf32-ip2k.c: Likewsie. + * elf32-m32r.c: Likewsie. + * elf32-mcore.c: Likewsie. + * elf32-openrisc.c: Likewsie. + * elf32-or32.c: Likewsie. + * elf32-pj.c: Likewsie. + * elf32-v850.c: Likewsie. + * elf32-xstormy16.c: Likewsie. + 2005-07-01 Alan Modra <amodra@bigpond.net.au> * elf64-alpha.c (elf64_alpha_create_got_section): Always create diff --git a/bfd/cpu-d10v.c b/bfd/cpu-d10v.c index 59bc0cd7b9e..18061a13797 100644 --- a/bfd/cpu-d10v.c +++ b/bfd/cpu-d10v.c @@ -1,22 +1,23 @@ /* BFD support for the D10V processor - Copyright 1996, 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright 1996, 1999, 2000, 2002, 2005 Free Software Foundation, Inc. Contributed by Martin Hunt (hunt@cygnus.com). -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -24,14 +25,14 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. static const bfd_arch_info_type d10v_ts3_info = { - 16, /* 16 bits in a word */ - 16, /* 16 bits in an address */ - 8, /* 8 bits in a byte */ + 16, /* 16 bits in a word. */ + 16, /* 16 bits in an address. */ + 8, /* 8 bits in a byte. */ bfd_arch_d10v, bfd_mach_d10v_ts3, "d10v", "d10v:ts3", - 4, /* section alignment power */ + 4, /* Section alignment power. */ FALSE, bfd_default_compatible, bfd_default_scan, @@ -40,32 +41,32 @@ static const bfd_arch_info_type d10v_ts3_info = static const bfd_arch_info_type d10v_ts2_info = { - 16, /* 16 bits in a word */ - 16, /* 16 bits in an address */ - 8, /* 8 bits in a byte */ + 16, /* 16 bits in a word. */ + 16, /* 16 bits in an address. */ + 8, /* 8 bits in a byte. */ bfd_arch_d10v, bfd_mach_d10v_ts2, "d10v", "d10v:ts2", - 4, /* section alignment power */ + 4, /* Section alignment power. */ FALSE, bfd_default_compatible, bfd_default_scan, - &d10v_ts3_info, + & d10v_ts3_info, }; const bfd_arch_info_type bfd_d10v_arch = { - 16, /* 16 bits in a word */ - 16, /* 16 bits in an address */ - 8, /* 8 bits in a byte */ + 16, /* 16 bits in a word. */ + 16, /* 16 bits in an address. */ + 8, /* 8 bits in a byte. */ bfd_arch_d10v, bfd_mach_d10v, "d10v", "d10v", - 4, /* section alignment power */ + 4, /* Section alignment power. */ TRUE, bfd_default_compatible, bfd_default_scan, - &d10v_ts2_info, + & d10v_ts2_info, }; diff --git a/bfd/cpu-d30v.c b/bfd/cpu-d30v.c index 2eed66dcd0c..5346cb3219f 100644 --- a/bfd/cpu-d30v.c +++ b/bfd/cpu-d30v.c @@ -1,22 +1,23 @@ /* BFD support for the Mitsubishi D30V processor - Copyright 1997, 2002 Free Software Foundation, Inc. + Copyright 1997, 2002, 2005 Free Software Foundation, Inc. Contributed by Martin Hunt (hunt@cygnus.com). -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -24,14 +25,14 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. const bfd_arch_info_type bfd_d30v_arch = { - 32, /* bits in a word */ - 32, /* bits in an address */ - 8, /* bits in a byte */ + 32, /* Bits in a word. */ + 32, /* Bits in an address. */ + 8, /* Bits in a byte. */ bfd_arch_d30v, 0, "d30v", "d30v", - 4, /* section alignment power */ + 4, /* Section alignment power. */ TRUE, bfd_default_compatible, bfd_default_scan, diff --git a/bfd/cpu-i370.c b/bfd/cpu-i370.c index 42e81f6e9e2..d7d712f3ff9 100644 --- a/bfd/cpu-i370.c +++ b/bfd/cpu-i370.c @@ -1,24 +1,25 @@ /* BFD i370 CPU definition - Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2002 + Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2005 Free Software Foundation, Inc. Contributed by Ian Lance Taylor, Cygnus Support. Hacked by Linas Vepstas <linas@linas.org> in 1998, 1999 -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -26,31 +27,31 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. static const bfd_arch_info_type arch_info_struct[] = { - /* hack alert: old old machines are really 16 and 24 bit arch ... */ + /* Hack alert: old old machines are really 16 and 24 bit arch ... */ { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ + 32, /* 32 bits in a word. */ + 32, /* 32 bits in an address. */ + 8, /* 8 bits in a byte. */ bfd_arch_i370, - 360, /* for the 360 */ + 360, /* For the 360. */ "i370", "i370:360", 3, - FALSE, /* not the default */ + FALSE, /* Not the default. */ bfd_default_compatible, bfd_default_scan, &arch_info_struct[1] }, { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ + 32, /* 32 bits in a word. */ + 32, /* 32 bits in an address. */ + 8, /* 8 bits in a byte. */ bfd_arch_i370, - 370, /* for the 370 */ + 370, /* For the 370. */ "i370", "i370:370", 3, - FALSE, /* not the default */ + FALSE, /* Not the default. */ bfd_default_compatible, bfd_default_scan, 0 @@ -58,17 +59,17 @@ static const bfd_arch_info_type arch_info_struct[] = }; const bfd_arch_info_type bfd_i370_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i370, - 0, /* for the 360/370 common architecture */ - "i370", - "i370:common", - 3, - TRUE, /* the default */ - bfd_default_compatible, - bfd_default_scan, - &arch_info_struct[0] - }; +{ + 32, /* 32 bits in a word. */ + 32, /* 32 bits in an address. */ + 8, /* 8 bits in a byte. */ + bfd_arch_i370, + 0, /* For the 360/370 common architecture. */ + "i370", + "i370:common", + 3, + TRUE, /* The default. */ + bfd_default_compatible, + bfd_default_scan, + & arch_info_struct[0] +}; diff --git a/bfd/cpu-xstormy16.c b/bfd/cpu-xstormy16.c index 1bb9968a25c..62c5302222d 100644 --- a/bfd/cpu-xstormy16.c +++ b/bfd/cpu-xstormy16.c @@ -1,21 +1,21 @@ /* BFD support for the XSTORMY16 processor. Copyright 2001, 2002 Free Software Foundation, Inc. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index 4643e71503e..a6011bdb32d 100644 --- a/bfd/elf32-arc.c +++ b/bfd/elf32-arc.c @@ -1,5 +1,5 @@ /* ARC-specific support for 32-bit ELF - Copyright 1994, 1995, 1997, 1999, 2001, 2002 + Copyright 1994, 1995, 1997, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. Contributed by Doug Evans (dje@cygnus.com). @@ -17,7 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -26,83 +27,94 @@ #include "elf/arc.h" #include "libiberty.h" -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void arc_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_boolean arc_elf_object_p - PARAMS ((bfd *)); -static void arc_elf_final_write_processing - PARAMS ((bfd *, bfd_boolean)); -static bfd_reloc_status_type arc_elf_b22_pcrel - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - /* Try to minimize the amount of space occupied by relocation tables on the ROM (not that the ROM won't be swamped by other ELF overhead). */ #define USE_REL 1 +static bfd_reloc_status_type +arc_elf_b22_pcrel (bfd * abfd, + arelent * reloc_entry, + asymbol * symbol, + void * data, + asection * input_section, + bfd * output_bfd, + char ** error_message) +{ + /* If linking, back up the final symbol address by the address of the + reloc. This cannot be accomplished by setting the pcrel_offset + field to TRUE, as bfd_install_relocation will detect this and refuse + to install the offset in the first place, but bfd_perform_relocation + will still insist on removing it. */ + if (output_bfd == NULL) + reloc_entry->addend -= reloc_entry->address; + + /* Fall through to the default elf reloc handler. */ + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); +} + static reloc_howto_type elf_arc_howto_table[] = { /* This reloc does nothing. */ - HOWTO (R_ARC_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_ARC_NONE", /* name */ - TRUE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ + HOWTO (R_ARC_NONE, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_ARC_NONE", /* Name. */ + TRUE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ /* A standard 32 bit relocation. */ - HOWTO (R_ARC_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_ARC_32", /* name */ - TRUE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ + HOWTO (R_ARC_32, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_ARC_32", /* Name. */ + TRUE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ /* A 26 bit absolute branch, right shifted by 2. */ - HOWTO (R_ARC_B26, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_ARC_B26", /* name */ - TRUE, /* partial_inplace */ - 0x00ffffff, /* src_mask */ - 0x00ffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ + HOWTO (R_ARC_B26, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 26, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_ARC_B26", /* Name. */ + TRUE, /* Partial_inplace. */ + 0x00ffffff, /* Src_mask. */ + 0x00ffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ /* A relative 22 bit branch; bits 21-2 are stored in bits 26-7. */ - HOWTO (R_ARC_B22_PCREL, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 22, /* bitsize */ - TRUE, /* pc_relative */ - 7, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - arc_elf_b22_pcrel, /* special_function */ - "R_ARC_B22_PCREL", /* name */ - TRUE, /* partial_inplace */ - 0x07ffff80, /* src_mask */ - 0x07ffff80, /* dst_mask */ - FALSE), /* pcrel_offset */ + HOWTO (R_ARC_B22_PCREL, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 22, /* Bitsize. */ + TRUE, /* PC_relative. */ + 7, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + arc_elf_b22_pcrel, /* Special_function. */ + "R_ARC_B22_PCREL", /* Name. */ + TRUE, /* Partial_inplace. */ + 0x07ffff80, /* Src_mask. */ + 0x07ffff80, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ }; /* Map BFD reloc types to ARC ELF reloc types. */ @@ -123,9 +135,8 @@ static const struct arc_reloc_map arc_reloc_map[] = }; static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -139,10 +150,9 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code) /* Set the howto pointer for an ARC ELF reloc. */ static void -arc_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +arc_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; @@ -154,8 +164,7 @@ arc_info_to_howto_rel (abfd, cache_ptr, dst) /* Set the right machine number for an ARC ELF file. */ static bfd_boolean -arc_elf_object_p (abfd) - bfd *abfd; +arc_elf_object_p (bfd *abfd) { unsigned int mach = bfd_mach_arc_6; @@ -187,9 +196,8 @@ arc_elf_object_p (abfd) This gets the ARC architecture right based on the machine number. */ static void -arc_elf_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +arc_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { unsigned long val; @@ -213,41 +221,17 @@ arc_elf_final_write_processing (abfd, linker) elf_elfheader (abfd)->e_flags |= val; } -bfd_reloc_status_type -arc_elf_b22_pcrel (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd * abfd; - arelent * reloc_entry; - asymbol * symbol; - PTR data; - asection * input_section; - bfd * output_bfd; - char ** error_message; -{ - /* If linking, back up the final symbol address by the address of the - reloc. This cannot be accomplished by setting the pcrel_offset - field to TRUE, as bfd_install_relocation will detect this and refuse - to install the offset in the first place, but bfd_perform_relocation - will still insist on removing it. */ - if (output_bfd == (bfd *) NULL) - reloc_entry->addend -= reloc_entry->address; - - /* Fall through to the default elf reloc handler. */ - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -#define TARGET_LITTLE_SYM bfd_elf32_littlearc_vec -#define TARGET_LITTLE_NAME "elf32-littlearc" -#define TARGET_BIG_SYM bfd_elf32_bigarc_vec -#define TARGET_BIG_NAME "elf32-bigarc" -#define ELF_ARCH bfd_arch_arc -#define ELF_MACHINE_CODE EM_ARC -#define ELF_MAXPAGESIZE 0x1000 - -#define elf_info_to_howto 0 -#define elf_info_to_howto_rel arc_info_to_howto_rel -#define elf_backend_object_p arc_elf_object_p -#define elf_backend_final_write_processing arc_elf_final_write_processing +#define TARGET_LITTLE_SYM bfd_elf32_littlearc_vec +#define TARGET_LITTLE_NAME "elf32-littlearc" +#define TARGET_BIG_SYM bfd_elf32_bigarc_vec +#define TARGET_BIG_NAME "elf32-bigarc" +#define ELF_ARCH bfd_arch_arc +#define ELF_MACHINE_CODE EM_ARC +#define ELF_MAXPAGESIZE 0x1000 + +#define elf_info_to_howto 0 +#define elf_info_to_howto_rel arc_info_to_howto_rel +#define elf_backend_object_p arc_elf_object_p +#define elf_backend_final_write_processing arc_elf_final_write_processing #include "elf32-target.h" diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c index 6d5c5d270d7..a0e506a8835 100644 --- a/bfd/elf32-d10v.c +++ b/bfd/elf32-d10v.c @@ -1,23 +1,24 @@ /* D10V-specific support for 32-bit ELF - Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Martin Hunt (hunt@cygnus.com). -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -25,206 +26,179 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "elf-bfd.h" #include "elf/d10v.h" -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void d10v_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static asection * elf32_d10v_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static bfd_boolean elf32_d10v_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean elf32_d10v_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_vma extract_rel_addend - PARAMS ((bfd *, bfd_byte *, reloc_howto_type *)); -static void insert_rel_addend - PARAMS ((bfd *, bfd_byte *, reloc_howto_type *, bfd_vma)); -static bfd_boolean elf32_d10v_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, - asection **)); - /* Use REL instead of RELA to save space. */ #define USE_REL 1 static reloc_howto_type elf_d10v_howto_table[] = - { - /* This reloc does nothing. */ - HOWTO (R_D10V_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D10V_NONE", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* An PC Relative 10-bit relocation, shifted by 2 */ - /* right container */ - HOWTO (R_D10V_10_PCREL_R, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 7, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D10V_10_PCREL_R", /* name */ - FALSE, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* An PC Relative 10-bit relocation, shifted by 2 */ - /* left container */ - HOWTO (R_D10V_10_PCREL_L, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 7, /* bitsize */ - TRUE, /* pc_relative */ - 15, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D10V_10_PCREL_L", /* name */ - FALSE, /* partial_inplace */ - 0x07f8000, /* src_mask */ - 0x07f8000, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A 16 bit absolute relocation */ - HOWTO (R_D10V_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D10V_16", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* An 18 bit absolute relocation, right shifted 2 */ - HOWTO (R_D10V_18, /* type */ - 2, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D10V_18", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A relative 18 bit relocation, right shifted by 2 */ - HOWTO (R_D10V_18_PCREL, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 15, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D10V_18_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A 32 bit absolute relocation */ - HOWTO (R_D10V_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D10V_32", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable hierarchy */ - HOWTO (R_D10V_GNU_VTINHERIT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "R_D10V_GNU_VTINHERIT", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable member usage */ - HOWTO (R_D10V_GNU_VTENTRY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - _bfd_elf_rel_vtable_reloc_fn, /* special_function */ - "R_D10V_GNU_VTENTRY", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - }; +{ + /* This reloc does nothing. */ + HOWTO (R_D10V_NONE, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D10V_NONE", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* An PC Relative 10-bit relocation, shifted by 2, right container. */ + HOWTO (R_D10V_10_PCREL_R, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 7, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D10V_10_PCREL_R", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xff, /* Src_mask. */ + 0xff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* An PC Relative 10-bit relocation, shifted by 2, left container. */ + HOWTO (R_D10V_10_PCREL_L, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 7, /* Bitsize. */ + TRUE, /* PC_relative. */ + 15, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D10V_10_PCREL_L", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x07f8000, /* Src_mask. */ + 0x07f8000, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A 16 bit absolute relocation. */ + HOWTO (R_D10V_16, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D10V_16", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* An 18 bit absolute relocation, right shifted 2. */ + HOWTO (R_D10V_18, /* Type. */ + 2, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D10V_18", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* A relative 18 bit relocation, right shifted by 2. */ + HOWTO (R_D10V_18_PCREL, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 15, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D10V_18_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A 32 bit absolute relocation. */ + HOWTO (R_D10V_32, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D10V_32", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* GNU extension to record C++ vtable hierarchy. */ + HOWTO (R_D10V_GNU_VTINHERIT, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + NULL, /* Special_function. */ + "R_D10V_GNU_VTINHERIT",/* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* GNU extension to record C++ vtable member usage. */ + HOWTO (R_D10V_GNU_VTENTRY, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + _bfd_elf_rel_vtable_reloc_fn, /* Special_function. */ + "R_D10V_GNU_VTENTRY", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ +}; /* Map BFD reloc types to D10V ELF reloc types. */ struct d10v_reloc_map - { - bfd_reloc_code_real_type bfd_reloc_val; - unsigned char elf_reloc_val; - }; +{ + bfd_reloc_code_real_type bfd_reloc_val; + unsigned char elf_reloc_val; +}; static const struct d10v_reloc_map d10v_reloc_map[] = - { - { BFD_RELOC_NONE, R_D10V_NONE, }, - { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R }, - { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L }, - { BFD_RELOC_16, R_D10V_16 }, - { BFD_RELOC_D10V_18, R_D10V_18 }, - { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL }, - { BFD_RELOC_32, R_D10V_32 }, - { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY }, - }; +{ + { BFD_RELOC_NONE, R_D10V_NONE, }, + { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R }, + { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L }, + { BFD_RELOC_16, R_D10V_16 }, + { BFD_RELOC_D10V_18, R_D10V_18 }, + { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL }, + { BFD_RELOC_32, R_D10V_32 }, + { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY }, +}; static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; for (i = 0; i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map); i++) - { - if (d10v_reloc_map[i].bfd_reloc_val == code) - return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val]; - } + if (d10v_reloc_map[i].bfd_reloc_val == code) + return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val]; return NULL; } @@ -232,10 +206,9 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code) /* Set the howto pointer for an D10V ELF reloc. */ static void -d10v_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +d10v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; @@ -245,12 +218,11 @@ d10v_info_to_howto_rel (abfd, cache_ptr, dst) } static asection * -elf32_d10v_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +elf32_d10v_gc_mark_hook (asection *sec, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { if (h != NULL) { @@ -282,13 +254,12 @@ elf32_d10v_gc_mark_hook (sec, info, rel, h, sym) } static bfd_boolean -elf32_d10v_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - asection *sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; +elf32_d10v_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) { - /* we don't use got and plt entries for d10v */ + /* We don't use got and plt entries for d10v. */ return TRUE; } @@ -297,11 +268,10 @@ elf32_d10v_gc_sweep_hook (abfd, info, sec, relocs) virtual table relocs for gc. */ static bfd_boolean -elf32_d10v_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +elf32_d10v_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; @@ -356,10 +326,9 @@ elf32_d10v_check_relocs (abfd, info, sec, relocs) } static bfd_vma -extract_rel_addend (abfd, where, howto) - bfd *abfd; - bfd_byte *where; - reloc_howto_type *howto; +extract_rel_addend (bfd *abfd, + bfd_byte *where, + reloc_howto_type *howto) { bfd_vma insn, val; @@ -392,11 +361,10 @@ extract_rel_addend (abfd, where, howto) } static void -insert_rel_addend (abfd, where, howto, addend) - bfd *abfd; - bfd_byte *where; - reloc_howto_type *howto; - bfd_vma addend; +insert_rel_addend (bfd *abfd, + bfd_byte *where, + reloc_howto_type *howto, + bfd_vma addend) { bfd_vma insn; @@ -425,17 +393,16 @@ insert_rel_addend (abfd, where, howto, addend) } /* Relocate a D10V ELF section. */ + static bfd_boolean -elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +elf32_d10v_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -462,7 +429,7 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section, r_type = ELF32_R_TYPE (rel->r_info); if (r_type == R_D10V_GNU_VTENTRY - || r_type == R_D10V_GNU_VTINHERIT ) + || r_type == R_D10V_GNU_VTINHERIT) continue; howto = elf_d10v_howto_table + r_type; @@ -552,7 +519,7 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section, { case bfd_reloc_overflow: if (!((*info->callbacks->reloc_overflow) - (info, (h ? &h->root : NULL), name, howto->name, + (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_offset))) return FALSE; diff --git a/bfd/elf32-d30v.c b/bfd/elf32-d30v.c index b9bab632225..c96937d5da0 100644 --- a/bfd/elf32-d30v.c +++ b/bfd/elf32-d30v.c @@ -1,23 +1,24 @@ /* D30V-specific support for 32-bit ELF - Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Martin Hunt (hunt@cygnus.com). -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -25,240 +26,17 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "elf-bfd.h" #include "elf/d30v.h" -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void d30v_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static void d30v_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_reloc_status_type bfd_elf_d30v_reloc PARAMS (( - bfd *abfd, - arelent *reloc_entry, - asymbol *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -static bfd_reloc_status_type bfd_elf_d30v_reloc_21 PARAMS (( - bfd *abfd, - arelent *reloc_entry, - asymbol *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); - -static reloc_howto_type elf_d30v_howto_table[] = -{ - /* This reloc does nothing. */ - HOWTO (R_D30V_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D30V_NONE", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A 6 bit absolute relocation */ - HOWTO (R_D30V_6, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 6, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D30V_6", /* name */ - FALSE, /* partial_inplace */ - 0x3f, /* src_mask */ - 0x3f, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A relative 9 bit relocation, right shifted by 3 */ - HOWTO (R_D30V_9_PCREL, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 6, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_d30v_reloc_21, /* special_function */ - "R_D30V_9_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0x3f, /* src_mask */ - 0x3f, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A relative 9 bit relocation, right shifted by 3 */ - HOWTO (R_D30V_9_PCREL_R, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 6, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_d30v_reloc_21, /* special_function */ - "R_D30V_9_PCREL_R", /* name */ - FALSE, /* partial_inplace */ - 0x3f, /* src_mask */ - 0x3f, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* An absolute 15 bit relocation, right shifted by 3 */ - HOWTO (R_D30V_15, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 12, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D30V_15", /* name */ - FALSE, /* partial_inplace */ - 0xfff, /* src_mask */ - 0xfff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A relative 15 bit relocation, right shifted by 3 */ - HOWTO (R_D30V_15_PCREL, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 12, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_d30v_reloc_21, /* special_function */ - "R_D30V_15_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0xfff, /* src_mask */ - 0xfff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A relative 15 bit relocation, right shifted by 3 */ - HOWTO (R_D30V_15_PCREL_R, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 12, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_d30v_reloc_21, /* special_function */ - "R_D30V_15_PCREL_R", /* name */ - FALSE, /* partial_inplace */ - 0xfff, /* src_mask */ - 0xfff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* An absolute 21 bit relocation, right shifted by 3 */ - HOWTO (R_D30V_21, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 18, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D30V_21", /* name */ - FALSE, /* partial_inplace */ - 0x3ffff, /* src_mask */ - 0x3ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A relative 21 bit relocation, right shifted by 3 */ - HOWTO (R_D30V_21_PCREL, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 18, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_d30v_reloc_21, /* special_function */ - "R_D30V_21_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0x3ffff, /* src_mask */ - 0x3ffff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A relative 21 bit relocation, right shifted by 3, in the Right container */ - HOWTO (R_D30V_21_PCREL_R, /* type */ - 3, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 18, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_d30v_reloc_21, /* special_function */ - "R_D30V_21_PCREL_R", /* name */ - FALSE, /* partial_inplace */ - 0x3ffff, /* src_mask */ - 0x3ffff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A D30V 32 bit absolute relocation */ - HOWTO (R_D30V_32, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_d30v_reloc, /* special_function */ - "R_D30V_32", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A relative 32 bit relocation */ - HOWTO (R_D30V_32_PCREL, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_d30v_reloc, /* special_function */ - "R_D30V_32_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A regular 32 bit absolute relocation */ - HOWTO (R_D30V_32_NORMAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_D30V_32_NORMAL", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - -}; - #define MAX32 ((bfd_signed_vma) 0x7fffffff) #define MIN32 (- MAX32 - 1) static bfd_reloc_status_type -bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +bfd_elf_d30v_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message) { bfd_signed_vma relocation; bfd_vma in1, in2, num; @@ -271,7 +49,7 @@ bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, reloc_howto_type *howto = reloc_entry->howto; int make_absolute = 0; - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { /* Partial linking -- do nothing. */ reloc_entry->address += input_section->output_offset; @@ -283,10 +61,10 @@ bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, if (r != bfd_reloc_continue) return r; - /* a hacked-up version of bfd_perform_reloc() follows */ + /* A hacked-up version of bfd_perform_reloc() follows. */ if (bfd_is_und_section (symbol->section) && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == (bfd *) NULL) + && output_bfd == NULL) flag = bfd_reloc_undefined; /* Is the address of the relocation really within the section? */ @@ -313,10 +91,10 @@ bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, /* Here the variable relocation holds the final address of the symbol we are relocating against, plus any addend. */ - if (howto->pc_relative) { - tmp_addr = input_section->output_section->vma + input_section->output_offset + tmp_addr = input_section->output_section->vma + + input_section->output_offset + reloc_entry->address; relocation -= tmp_addr; } @@ -324,7 +102,7 @@ bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, in1 = bfd_get_32 (abfd, (bfd_byte *) data + addr); in2 = bfd_get_32 (abfd, (bfd_byte *) data + addr + 4); - /* extract the addend */ + /* Extract the addend. */ num = ((in2 & 0x3FFFF) | ((in2 & 0xFF00000) >> 2) | ((in1 & 0x3F) << 26)); @@ -345,12 +123,12 @@ bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, } } - in1 |= (relocation >> 26) & 0x3F; /* top 6 bits */ - in2 |= ((relocation & 0x03FC0000) << 2); /* next 8 bits */ - in2 |= relocation & 0x0003FFFF; /* bottom 18 bits */ + in1 |= (relocation >> 26) & 0x3F; /* Top 6 bits. */ + in2 |= ((relocation & 0x03FC0000) << 2); /* Next 8 bits. */ + in2 |= relocation & 0x0003FFFF; /* Bottom 18 bits. */ - /* change a PC-relative instruction to its absolute equivalent */ - /* with this simple hack */ + /* Change a PC-relative instruction to its + absolute equivalent with this simple hack. */ if (make_absolute) in1 |= 0x00100000; @@ -361,14 +139,13 @@ bfd_elf_d30v_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, } static bfd_reloc_status_type -bfd_elf_d30v_reloc_21 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +bfd_elf_d30v_reloc_21 (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message) { bfd_vma relocation; bfd_vma in1, num; @@ -380,7 +157,7 @@ bfd_elf_d30v_reloc_21 (abfd, reloc_entry, symbol, data, input_section, output_bf reloc_howto_type *howto = reloc_entry->howto; int mask, max; - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { /* Partial linking -- do nothing. */ reloc_entry->address += input_section->output_offset; @@ -392,10 +169,10 @@ bfd_elf_d30v_reloc_21 (abfd, reloc_entry, symbol, data, input_section, output_bf if (r != bfd_reloc_continue) return r; - /* a hacked-up version of bfd_perform_reloc() follows */ - if (bfd_is_und_section (symbol->section) + /* A hacked-up version of bfd_perform_reloc() follows. */ + if (bfd_is_und_section (symbol->section) && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == (bfd *) NULL) + && output_bfd == NULL) flag = bfd_reloc_undefined; /* Is the address of the relocation really within the section? */ @@ -438,30 +215,30 @@ bfd_elf_d30v_reloc_21 (abfd, reloc_entry, symbol, data, input_section, output_bf mask <<= 12; max = (1 << (howto->bitsize + 2)) - 1; - /* extract the addend */ - num = in1 & mask; /* 18 bits */ + /* Extract the addend. */ + num = in1 & mask; /* 18 bits. */ if (howto->bitsize == 6) num >>= 12; - num <<= 3; /* shift left 3 */ - in1 &= ~mask; /* mask out addend */ + num <<= 3; /* shift left 3. */ + in1 &= ~mask; /* Mask out addend. */ relocation += num; - if (howto->type == R_D30V_21_PCREL_R || howto->type == R_D30V_15_PCREL_R || - howto->type == R_D30V_9_PCREL_R ) - { - relocation += 4; - } + if (howto->type == R_D30V_21_PCREL_R + || howto->type == R_D30V_15_PCREL_R + || howto->type == R_D30V_9_PCREL_R) + relocation += 4; - if ((int)relocation < 0 ) + if ((int) relocation < 0) { - if (~(int)relocation > max) + if (~ (int) relocation > max) flag = bfd_reloc_overflow; } else { - if ((int)relocation > max) + if ((int) relocation > max) flag = bfd_reloc_overflow; } + relocation >>= 3; if (howto->bitsize == 6) in1 |= ((relocation & (mask >> 12)) << 12); @@ -473,6 +250,205 @@ bfd_elf_d30v_reloc_21 (abfd, reloc_entry, symbol, data, input_section, output_bf return flag; } +static reloc_howto_type elf_d30v_howto_table[] = +{ + /* This reloc does nothing. */ + HOWTO (R_D30V_NONE, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D30V_NONE", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* A 6 bit absolute relocation. */ + HOWTO (R_D30V_6, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 6, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D30V_6", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x3f, /* Src_mask. */ + 0x3f, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* A relative 9 bit relocation, right shifted by 3. */ + HOWTO (R_D30V_9_PCREL, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 6, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc_21, /* Special_function. */ + "R_D30V_9_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x3f, /* Src_mask. */ + 0x3f, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A relative 9 bit relocation, right shifted by 3. */ + HOWTO (R_D30V_9_PCREL_R, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 6, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc_21, /* Special_function. */ + "R_D30V_9_PCREL_R", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x3f, /* Src_mask. */ + 0x3f, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* An absolute 15 bit relocation, right shifted by 3. */ + HOWTO (R_D30V_15, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 12, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D30V_15", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xfff, /* Src_mask. */ + 0xfff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* A relative 15 bit relocation, right shifted by 3. */ + HOWTO (R_D30V_15_PCREL, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 12, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc_21, /* Special_function. */ + "R_D30V_15_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xfff, /* Src_mask. */ + 0xfff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A relative 15 bit relocation, right shifted by 3. */ + HOWTO (R_D30V_15_PCREL_R, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 12, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc_21, /* Special_function. */ + "R_D30V_15_PCREL_R", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xfff, /* Src_mask. */ + 0xfff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* An absolute 21 bit relocation, right shifted by 3. */ + HOWTO (R_D30V_21, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 18, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D30V_21", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x3ffff, /* Src_mask. */ + 0x3ffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* A relative 21 bit relocation, right shifted by 3. */ + HOWTO (R_D30V_21_PCREL, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 18, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc_21, /* Special_function. */ + "R_D30V_21_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x3ffff, /* Src_mask. */ + 0x3ffff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A relative 21 bit relocation, right shifted by 3, in the Right container. */ + HOWTO (R_D30V_21_PCREL_R, /* Type. */ + 3, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 18, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc_21, /* Special_function. */ + "R_D30V_21_PCREL_R", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x3ffff, /* Src_mask. */ + 0x3ffff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A D30V 32 bit absolute relocation. */ + HOWTO (R_D30V_32, /* Type. */ + 0, /* Rightshift. */ + 4, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc, /* Special_function. */ + "R_D30V_32", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* A relative 32 bit relocation. */ + HOWTO (R_D30V_32_PCREL, /* Type. */ + 0, /* Rightshift. */ + 4, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + bfd_elf_d30v_reloc, /* Special_function. */ + "R_D30V_32_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A regular 32 bit absolute relocation. */ + HOWTO (R_D30V_32_NORMAL, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_D30V_32_NORMAL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + +}; + /* Map BFD reloc types to D30V ELF reloc types. */ struct d30v_reloc_map @@ -499,9 +475,8 @@ static const struct d30v_reloc_map d30v_reloc_map[] = }; static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -519,10 +494,9 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code) /* Set the howto pointer for an D30V ELF reloc (type REL). */ static void -d30v_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +d30v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; @@ -534,10 +508,9 @@ d30v_info_to_howto_rel (abfd, cache_ptr, dst) /* Set the howto pointer for an D30V ELF reloc (type RELA). */ static void -d30v_info_to_howto_rela (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +d30v_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; diff --git a/bfd/elf32-dlx.c b/bfd/elf32-dlx.c index 220a49b853f..ae42baf3a63 100644 --- a/bfd/elf32-dlx.c +++ b/bfd/elf32-dlx.c @@ -15,7 +15,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -23,27 +24,6 @@ #include "elf-bfd.h" #include "elf/dlx.h" -int set_dlx_skip_hi16_flag PARAMS ((int)); - -static bfd_boolean elf32_dlx_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static void elf32_dlx_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static void elf32_dlx_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_reloc_status_type elf32_dlx_relocate16 - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type elf32_dlx_relocate26 - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *elf32_dlx_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static bfd_reloc_status_type _bfd_dlx_elf_hi16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type * dlx_rtype_to_howto - PARAMS ((unsigned int)); - - #define USE_REL 1 #define bfd_elf32_bfd_reloc_type_lookup elf32_dlx_reloc_type_lookup @@ -51,164 +31,6 @@ static reloc_howto_type * dlx_rtype_to_howto #define elf_info_to_howto_rel elf32_dlx_info_to_howto_rel #define elf_backend_check_relocs elf32_dlx_check_relocs -static reloc_howto_type dlx_elf_howto_table[]= - { - /* No relocation. */ - HOWTO (R_DLX_NONE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_DLX_NONE", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 8 bit relocation. */ - HOWTO (R_DLX_RELOC_8, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_DLX_RELOC_8", /* name */ - TRUE, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 16 bit relocation. */ - HOWTO (R_DLX_RELOC_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_DLX_RELOC_16", /* name */ - TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 32 bit relocation. */ - HOWTO (R_DLX_RELOC_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_DLX_RELOC_32", /* name */ - TRUE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable hierarchy */ - HOWTO (R_DLX_GNU_VTINHERIT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - NULL, /* special_function */ - "R_DLX_GNU_VTINHERIT", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable member usage */ - HOWTO (R_DLX_GNU_VTENTRY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - _bfd_elf_rel_vtable_reloc_fn,/* special_function */ - "R_DLX_GNU_VTENTRY", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE) /* pcrel_offset */ - }; - -/* 16 bit offset for pc-relative branches. */ -static reloc_howto_type elf_dlx_gnu_rel16_s2 = -HOWTO (R_DLX_RELOC_16_PCREL, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - elf32_dlx_relocate16, /* special_function */ - "R_DLX_RELOC_16_PCREL",/* name */ - TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - TRUE); /* pcrel_offset */ - -/* 26 bit offset for pc-relative branches. */ -static reloc_howto_type elf_dlx_gnu_rel26_s2 = -HOWTO (R_DLX_RELOC_26_PCREL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - elf32_dlx_relocate26, /* special_function */ - "R_DLX_RELOC_26_PCREL",/* name */ - TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - TRUE); /* pcrel_offset */ - -/* High 16 bits of symbol value. */ -static reloc_howto_type elf_dlx_reloc_16_hi = -HOWTO (R_DLX_RELOC_16_HI, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - _bfd_dlx_elf_hi16_reloc,/* special_function */ - "R_DLX_RELOC_16_HI", /* name */ - TRUE, /* partial_inplace */ - 0xFFFF, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE); /* pcrel_offset */ - - /* Low 16 bits of symbol value. */ -static reloc_howto_type elf_dlx_reloc_16_lo = -HOWTO (R_DLX_RELOC_16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_DLX_RELOC_16_LO", /* name */ - TRUE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE); /* pcrel_offset */ - - /* The gas default behavior is not to preform the %hi modifier so that the GNU assembler can have the lower 16 bits offset placed in the insn, BUT we do like the gas to indicate it is %hi reloc type so when we in the link @@ -217,24 +39,23 @@ HOWTO (R_DLX_RELOC_16_LO, /* type */ static int skip_dlx_elf_hi16_reloc = 0; +extern int set_dlx_skip_hi16_flag (int); + int -set_dlx_skip_hi16_flag (flag) - int flag; +set_dlx_skip_hi16_flag (int flag) { skip_dlx_elf_hi16_reloc = flag; return flag; } static bfd_reloc_status_type -_bfd_dlx_elf_hi16_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +_bfd_dlx_elf_hi16_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message) { bfd_reloc_status_type ret; bfd_vma relocation; @@ -288,15 +109,13 @@ _bfd_dlx_elf_hi16_reloc (abfd, reloc_entry, symbol, data, relocatable output against an external symbol. */ static bfd_reloc_status_type -elf32_dlx_relocate16 (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +elf32_dlx_relocate16 (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { unsigned long insn, vallo, allignment; int val; @@ -310,12 +129,12 @@ elf32_dlx_relocate16 (abfd, reloc_entry, symbol, data, return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); - /* Check undefined section and undefined symbols */ + /* Check undefined section and undefined symbols. */ if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL) return bfd_reloc_undefined; - /* Can not support a long jump to sections other then .text */ + /* Can not support a long jump to sections other then .text. */ if (strcmp (input_section->name, symbol->section->output_section->name) != 0) { fprintf (stderr, @@ -353,15 +172,13 @@ elf32_dlx_relocate16 (abfd, reloc_entry, symbol, data, } static bfd_reloc_status_type -elf32_dlx_relocate26 (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +elf32_dlx_relocate26 (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { unsigned long insn, vallo, allignment; int val; @@ -416,6 +233,163 @@ elf32_dlx_relocate26 (abfd, reloc_entry, symbol, data, return bfd_reloc_ok; } +static reloc_howto_type dlx_elf_howto_table[]= +{ + /* No relocation. */ + HOWTO (R_DLX_NONE, /* Type. */ + 0, /* Rightshift. */ + 0, /* size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_DLX_NONE", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 8 bit relocation. */ + HOWTO (R_DLX_RELOC_8, /* Type. */ + 0, /* Rightshift. */ + 0, /* Size (0 = byte, 1 = short, 2 = long). */ + 8, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_DLX_RELOC_8", /* Name. */ + TRUE, /* Partial_inplace. */ + 0xff, /* Src_mask. */ + 0xff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 16 bit relocation. */ + HOWTO (R_DLX_RELOC_16, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_DLX_RELOC_16", /* Name. */ + TRUE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 32 bit relocation. */ + HOWTO (R_DLX_RELOC_32, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_DLX_RELOC_32", /* Name. */ + TRUE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* GNU extension to record C++ vtable hierarchy. */ + HOWTO (R_DLX_GNU_VTINHERIT, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + NULL, /* Special_function. */ + "R_DLX_GNU_VTINHERIT", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* GNU extension to record C++ vtable member usage. */ + HOWTO (R_DLX_GNU_VTENTRY, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + _bfd_elf_rel_vtable_reloc_fn,/* Special_function. */ + "R_DLX_GNU_VTENTRY", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE) /* PCrel_offset. */ +}; + +/* 16 bit offset for pc-relative branches. */ +static reloc_howto_type elf_dlx_gnu_rel16_s2 = + HOWTO (R_DLX_RELOC_16_PCREL, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + elf32_dlx_relocate16, /* Special_function. */ + "R_DLX_RELOC_16_PCREL",/* Name. */ + TRUE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + TRUE); /* PCrel_offset. */ + +/* 26 bit offset for pc-relative branches. */ +static reloc_howto_type elf_dlx_gnu_rel26_s2 = + HOWTO (R_DLX_RELOC_26_PCREL, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 26, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + elf32_dlx_relocate26, /* Special_function. */ + "R_DLX_RELOC_26_PCREL",/* Name. */ + TRUE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + TRUE); /* PCrel_offset. */ + +/* High 16 bits of symbol value. */ +static reloc_howto_type elf_dlx_reloc_16_hi = + HOWTO (R_DLX_RELOC_16_HI, /* Type. */ + 16, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + _bfd_dlx_elf_hi16_reloc,/* Special_function. */ + "R_DLX_RELOC_16_HI", /* Name. */ + TRUE, /* Partial_inplace. */ + 0xFFFF, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE); /* PCrel_offset. */ + + /* Low 16 bits of symbol value. */ +static reloc_howto_type elf_dlx_reloc_16_lo = + HOWTO (R_DLX_RELOC_16_LO, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont,/* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_DLX_RELOC_16_LO", /* Name. */ + TRUE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE); /* PCrel_offset. */ + /* A mapping from BFD reloc types to DLX ELF reloc types. Stolen from elf32-mips.c. @@ -431,27 +405,25 @@ struct elf_reloc_map }; static const struct elf_reloc_map dlx_reloc_map[] = - { - { BFD_RELOC_NONE, R_DLX_NONE }, - { BFD_RELOC_16, R_DLX_RELOC_16 }, - { BFD_RELOC_32, R_DLX_RELOC_32 }, - { BFD_RELOC_DLX_HI16_S, R_DLX_RELOC_16_HI }, - { BFD_RELOC_DLX_LO16, R_DLX_RELOC_16_LO }, - { BFD_RELOC_VTABLE_INHERIT, R_DLX_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_DLX_GNU_VTENTRY } - }; - +{ + { BFD_RELOC_NONE, R_DLX_NONE }, + { BFD_RELOC_16, R_DLX_RELOC_16 }, + { BFD_RELOC_32, R_DLX_RELOC_32 }, + { BFD_RELOC_DLX_HI16_S, R_DLX_RELOC_16_HI }, + { BFD_RELOC_DLX_LO16, R_DLX_RELOC_16_LO }, + { BFD_RELOC_VTABLE_INHERIT, R_DLX_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_DLX_GNU_VTENTRY } +}; /* Look through the relocs for a section during the first phase. Since we don't do .gots or .plts, we just need to consider the virtual table relocs for gc. */ static bfd_boolean -elf32_dlx_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +elf32_dlx_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; @@ -508,9 +480,8 @@ elf32_dlx_check_relocs (abfd, info, sec, relocs) /* Given a BFD reloc type, return a howto structure. */ static reloc_howto_type * -elf32_dlx_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +elf32_dlx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -535,8 +506,7 @@ elf32_dlx_reloc_type_lookup (abfd, code) } static reloc_howto_type * -dlx_rtype_to_howto (r_type) - unsigned int r_type; +dlx_rtype_to_howto (unsigned int r_type) { switch (r_type) { @@ -561,19 +531,17 @@ dlx_rtype_to_howto (r_type) } static void -elf32_dlx_info_to_howto (abfd, cache_ptr, dst) - bfd * abfd ATTRIBUTE_UNUSED; - arelent * cache_ptr ATTRIBUTE_UNUSED; - Elf_Internal_Rela * dst ATTRIBUTE_UNUSED; +elf32_dlx_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr ATTRIBUTE_UNUSED, + Elf_Internal_Rela * dst ATTRIBUTE_UNUSED) { abort (); } static void -elf32_dlx_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +elf32_dlx_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index 2982474cf99..d0a28d5b8ad 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1,31 +1,31 @@ /* i370-specific support for 32-bit ELF - Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004 + Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. Hacked by Linas Vepstas for i370 linas@linas.org -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ /* This file is based on a preliminary PowerPC ELF ABI. But its been hacked on for the IBM 360/370 architectures. Basically, the 31bit relocation works, and just about everything else is a wild card. In particular, don't expect shared libs or - dynamic loading to work ... its never been tested ... -*/ + dynamic loading to work ... its never been tested. */ #include "bfd.h" #include "sysdep.h" @@ -98,7 +98,7 @@ static reloc_howto_type i370_elf_howto_raw[] = 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 31-bit PC relative */ + /* 31-bit PC relative. */ HOWTO (R_I370_REL31, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -113,7 +113,7 @@ static reloc_howto_type i370_elf_howto_raw[] = 0x7fffffff, /* dst_mask */ TRUE), /* pcrel_offset */ - /* 32-bit PC relative */ + /* 32-bit PC relative. */ HOWTO (R_I370_REL32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -143,7 +143,7 @@ static reloc_howto_type i370_elf_howto_raw[] = 0xfff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 12-bit PC relative */ + /* 12-bit PC relative. */ HOWTO (R_I370_REL12, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ @@ -173,7 +173,7 @@ static reloc_howto_type i370_elf_howto_raw[] = 0xff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 8-bit PC relative */ + /* 8-bit PC relative. */ HOWTO (R_I370_REL8, /* type */ 0, /* rightshift */ 0, /* size (0 = byte, 1 = short, 2 = long) */ @@ -226,19 +226,10 @@ static reloc_howto_type i370_elf_howto_raw[] = }; -static void i370_elf_howto_init - PARAMS ((void)); -static reloc_howto_type *i370_elf_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void i370_elf_info_to_howto - PARAMS ((bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)); -static bfd_boolean i370_elf_set_private_flags - PARAMS ((bfd *, flagword)); - /* Initialize the i370_elf_howto_table, so that linear accesses can be done. */ static void -i370_elf_howto_init () +i370_elf_howto_init (void) { unsigned int i, type; @@ -249,21 +240,21 @@ i370_elf_howto_init () i370_elf_howto_table[type] = &i370_elf_howto_raw[i]; } } - + static reloc_howto_type * -i370_elf_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +i370_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { enum i370_reloc_type i370_reloc = R_I370_NONE; - if (!i370_elf_howto_table[ R_I370_ADDR31 ]) /* Initialize howto table if needed */ + if (!i370_elf_howto_table[ R_I370_ADDR31 ]) + /* Initialize howto table if needed. */ i370_elf_howto_init (); - switch ((int)code) + switch ((int) code) { default: - return (reloc_howto_type *)NULL; + return NULL; case BFD_RELOC_NONE: i370_reloc = R_I370_NONE; break; case BFD_RELOC_32: i370_reloc = R_I370_ADDR31; break; @@ -276,30 +267,6 @@ i370_elf_reloc_type_lookup (abfd, code) return i370_elf_howto_table[ (int)i370_reloc ]; }; -static bfd_boolean i370_elf_merge_private_bfd_data - PARAMS ((bfd *, bfd *)); -static bfd_boolean i370_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *info, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms, - asection **)); -static void i370_elf_post_process_headers - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean i370_elf_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean i370_elf_fake_sections - PARAMS ((bfd *, Elf_Internal_Shdr *, asection *)); -static bfd_boolean i370_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean i370_elf_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static bfd_boolean i370_elf_adjust_dynindx - PARAMS ((struct elf_link_hash_entry *, PTR)); -static bfd_boolean i370_elf_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean i370_elf_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - /* The name of the dynamic interpreter. This is put in the .interp section. */ @@ -308,26 +275,24 @@ static bfd_boolean i370_elf_finish_dynamic_sections /* Set the howto pointer for an i370 ELF reloc. */ static void -i370_elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +i370_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { - if (!i370_elf_howto_table[ R_I370_ADDR31 ]) /* Initialize howto table */ + if (!i370_elf_howto_table[ R_I370_ADDR31 ]) + /* Initialize howto table. */ i370_elf_howto_init (); BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_I370_max); cache_ptr->howto = i370_elf_howto_table[ELF32_R_TYPE (dst->r_info)]; } -/* hack alert -- the following several routines look generic to me ... - * why are we bothering with them ??? - */ +/* Hack alert -- the following several routines look generic to me ... + why are we bothering with them ? */ /* Function to set whether a module needs the -mrelocatable bit set. */ + static bfd_boolean -i370_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; +i370_elf_set_private_flags (bfd *abfd, flagword flags) { BFD_ASSERT (!elf_flags_init (abfd) || elf_elfheader (abfd)->e_flags == flags); @@ -338,11 +303,10 @@ i370_elf_set_private_flags (abfd, flags) } /* Merge backend specific data from an object file to the output - object file when linking */ + object file when linking. */ + static bfd_boolean -i370_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +i370_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { flagword old_flags; flagword new_flags; @@ -353,16 +317,16 @@ i370_elf_merge_private_bfd_data (ibfd, obfd) new_flags = elf_elfheader (ibfd)->e_flags; old_flags = elf_elfheader (obfd)->e_flags; - if (!elf_flags_init (obfd)) /* First call, no flags set */ + if (!elf_flags_init (obfd)) /* First call, no flags set. */ { elf_flags_init (obfd) = TRUE; elf_elfheader (obfd)->e_flags = new_flags; } - else if (new_flags == old_flags) /* Compatible flags are ok */ + else if (new_flags == old_flags) /* Compatible flags are ok. */ ; - else /* Incompatible flags */ + else /* Incompatible flags. */ { (*_bfd_error_handler) ("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)", @@ -378,9 +342,8 @@ i370_elf_merge_private_bfd_data (ibfd, obfd) /* Handle an i370 specific section when reading an object file. This is called when elfcode.h finds a section with an unknown type. */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean i370_elf_section_from_shdr (bfd *abfd, @@ -408,15 +371,13 @@ i370_elf_section_from_shdr (bfd *abfd, /* Set up any other section flags and such that may be necessary. */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean -i370_elf_fake_sections (abfd, shdr, asect) - bfd *abfd ATTRIBUTE_UNUSED; - Elf_Internal_Shdr *shdr; - asection *asect; +i370_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *shdr, + asection *asect) { if ((asect->flags & SEC_EXCLUDE) != 0) shdr->sh_flags |= SHF_EXCLUDE; @@ -431,16 +392,13 @@ i370_elf_fake_sections (abfd, shdr, asect) to output sections (just like _bfd_elf_create_dynamic_sections has to create .dynbss and .rela.bss). */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean -i370_elf_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +i370_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) { - register asection *s; + asection *s; flagword flags; if (!_bfd_elf_create_dynamic_sections(abfd, info)) @@ -463,7 +421,7 @@ i370_elf_create_dynamic_sections (abfd, info) return FALSE; } - /* xxx beats me, seem to need a rela.text ... */ + /* XXX beats me, seem to need a rela.text ... */ s = bfd_make_section_with_flags (abfd, ".rela.text", flags | SEC_READONLY); if (s == NULL @@ -478,14 +436,12 @@ i370_elf_create_dynamic_sections (abfd, info) change the definition to something the rest of the link can understand. */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean -i370_elf_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; +i370_elf_adjust_dynamic_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) { bfd *dynobj = elf_hash_table (info)->dynobj; asection *s; @@ -594,14 +550,11 @@ i370_elf_adjust_dynamic_symbol (info, h) /* Increment the index of a dynamic symbol by a given amount. Called via elf_link_hash_traverse. */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean -i370_elf_adjust_dynindx (h, cparg) - struct elf_link_hash_entry *h; - PTR cparg; +i370_elf_adjust_dynindx (struct elf_link_hash_entry *h, void * cparg) { int *cp = (int *) cparg; @@ -622,14 +575,12 @@ i370_elf_adjust_dynindx (h, cparg) /* Set the sizes of the dynamic sections. */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean -i370_elf_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +i370_elf_size_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) { bfd *dynobj; asection *s; @@ -664,10 +615,10 @@ i370_elf_size_dynamic_sections (output_bfd, info) stripped from the output file below. */ static char *rela_sections[] = { ".rela.got", ".rela.sdata", ".rela.sdata2", ".rela.sbss", - (char *)0 }; + NULL }; char **p; - for (p = rela_sections; *p != (char *)0; p++) + for (p = rela_sections; *p != NULL; p++) { s = bfd_get_section_by_name (dynobj, *p); if (s != NULL) @@ -697,32 +648,26 @@ i370_elf_size_dynamic_sections (output_bfd, info) if (strcmp (name, ".plt") == 0) { if (s->size == 0) - { - /* Strip this section if we don't need it; see the - comment below. */ - strip = TRUE; - } + /* Strip this section if we don't need it; see the + comment below. */ + strip = TRUE; else - { - /* Remember whether there is a PLT. */ - plt = TRUE; - } + /* Remember whether there is a PLT. */ + plt = TRUE; } else if (strncmp (name, ".rela", 5) == 0) { if (s->size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = TRUE; - } + /* If we don't need this section, strip it from the + output file. This is mostly to handle .rela.bss and + .rela.plt. We must create both sections in + create_dynamic_sections, because they must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + strip = TRUE; else { asection *target; @@ -749,10 +694,8 @@ i370_elf_size_dynamic_sections (output_bfd, info) else if (strcmp (name, ".got") != 0 && strcmp (name, ".sdata") != 0 && strcmp (name, ".sdata2") != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } + /* It's not one of our sections, so don't allocate space. */ + continue; if (strip) { @@ -766,7 +709,7 @@ i370_elf_size_dynamic_sections (output_bfd, info) continue; } /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); + s->contents = bfd_zalloc (dynobj, s->size); if (s->contents == NULL && s->size != 0) return FALSE; } @@ -845,8 +788,7 @@ i370_elf_size_dynamic_sections (output_bfd, info) } elf_link_hash_traverse (elf_hash_table (info), - i370_elf_adjust_dynindx, - (PTR) &c); + i370_elf_adjust_dynindx, & c); elf_hash_table (info)->dynsymcount += c; } @@ -857,16 +799,14 @@ i370_elf_size_dynamic_sections (output_bfd, info) allocate space in the global offset table or procedure linkage table. */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean -i370_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +i370_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { bfd *dynobj; Elf_Internal_Shdr *symtab_hdr; @@ -963,14 +903,12 @@ i370_elf_check_relocs (abfd, info, sec, relocs) /* Finish up the dynamic sections. */ /* XXX hack alert bogus This routine is mostly all junk and almost - * certainly does the wrong thing. Its here simply because it does - * just enough to allow glibc-2.1 ld.so to compile & link. - */ + certainly does the wrong thing. Its here simply because it does + just enough to allow glibc-2.1 ld.so to compile & link. */ static bfd_boolean -i370_elf_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +i370_elf_finish_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) { asection *sdyn; bfd *dynobj = elf_hash_table (info)->dynobj; @@ -1078,7 +1016,7 @@ i370_elf_finish_dynamic_sections (output_bfd, info) sym.st_shndx = indx; esym = (Elf32_External_Sym *) sdynsym->contents + dindx; - bfd_elf32_swap_symbol_out (output_bfd, &sym, (PTR) esym, (PTR) 0); + bfd_elf32_swap_symbol_out (output_bfd, &sym, esym, NULL); } } @@ -1121,16 +1059,14 @@ i370_elf_finish_dynamic_sections (output_bfd, info) accordingly. */ static bfd_boolean -i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +i370_elf_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); @@ -1151,27 +1087,28 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, (info->relocatable) ? " (relocatable)" : ""); #endif - if (!i370_elf_howto_table[ R_I370_ADDR31 ]) /* Initialize howto table if needed */ + if (!i370_elf_howto_table[ R_I370_ADDR31 ]) + /* Initialize howto table if needed. */ i370_elf_howto_init (); local_got_offsets = elf_local_got_offsets (input_bfd); for (; rel < relend; rel++) { - enum i370_reloc_type r_type = (enum i370_reloc_type)ELF32_R_TYPE (rel->r_info); - bfd_vma offset = rel->r_offset; - bfd_vma addend = rel->r_addend; - bfd_reloc_status_type r = bfd_reloc_other; - Elf_Internal_Sym *sym = (Elf_Internal_Sym *)0; - asection *sec = (asection *)0; - struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)0; - const char *sym_name = (const char *)0; + enum i370_reloc_type r_type = (enum i370_reloc_type) ELF32_R_TYPE (rel->r_info); + bfd_vma offset = rel->r_offset; + bfd_vma addend = rel->r_addend; + bfd_reloc_status_type r = bfd_reloc_other; + Elf_Internal_Sym *sym = NULL; + asection *sec = NULL; + struct elf_link_hash_entry * h = NULL; + const char *sym_name = NULL; reloc_howto_type *howto; unsigned long r_symndx; bfd_vma relocation; - /* Unknown relocation handling */ - if ((unsigned)r_type >= (unsigned)R_I370_max + /* Unknown relocation handling. */ + if ((unsigned) r_type >= (unsigned) R_I370_max || !i370_elf_howto_table[(int)r_type]) { (*_bfd_error_handler) ("%B: unknown relocation type %d", @@ -1183,7 +1120,7 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, continue; } - howto = i370_elf_howto_table[(int)r_type]; + howto = i370_elf_howto_table[(int) r_type]; r_symndx = ELF32_R_SYM (rel->r_info); if (r_symndx < symtab_hdr->sh_info) @@ -1192,7 +1129,7 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, sec = local_sections[r_symndx]; sym_name = "<local symbol>"; - relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel); addend = rel->r_addend; } else @@ -1214,12 +1151,10 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, || r_type == R_I370_COPY || r_type == R_I370_ADDR16 || r_type == R_I370_RELATIVE)) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } + /* In these cases, we don't need the relocation + value. We check specially because in some + obscure cases sec->output_section will be NULL. */ + relocation = 0; else relocation = (h->root.u.def.value + sec->output_section->vma @@ -1256,23 +1191,23 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, ret = FALSE; continue; - case (int)R_I370_NONE: + case (int) R_I370_NONE: continue; /* Relocations that may need to be propagated if this is a shared object. */ - case (int)R_I370_REL31: + case (int) R_I370_REL31: /* If these relocations are not to a named symbol, they can be handled right here, no need to bother the dynamic linker. */ if (h == NULL || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) break; - /* fall through */ + /* Fall through. */ /* Relocations that always need to be propagated if this is a shared object. */ - case (int)R_I370_ADDR31: - case (int)R_I370_ADDR16: + case (int) R_I370_ADDR31: + case (int) R_I370_ADDR16: if (info->shared && r_symndx != 0) { @@ -1387,8 +1322,8 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, } break; - case (int)R_I370_COPY: - case (int)R_I370_RELATIVE: + case (int) R_I370_COPY: + case (int) R_I370_RELATIVE: (*_bfd_error_handler) ("%B: Relocation %s is not yet supported for symbol %s.", input_bfd, @@ -1406,17 +1341,12 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, (int)r_type, sym_name, r_symndx, - (long)offset, - (long)addend); + (long) offset, + (long) addend); #endif - r = _bfd_final_link_relocate (howto, - input_bfd, - input_section, - contents, - offset, - relocation, - addend); + r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, + offset, relocation, addend); if (r != bfd_reloc_ok) { @@ -1454,7 +1384,6 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, offset); } break; - } } } @@ -1467,11 +1396,10 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, } static void -i370_elf_post_process_headers (abfd, link_info) - bfd * abfd; - struct bfd_link_info * link_info ATTRIBUTE_UNUSED; +i370_elf_post_process_headers (bfd * abfd, + struct bfd_link_info * link_info ATTRIBUTE_UNUSED) { - Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form */ + Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form. */ i_ehdrp = elf_elfheader (abfd); i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX; @@ -1488,16 +1416,15 @@ i370_elf_post_process_headers (abfd, link_info) #define elf_info_to_howto i370_elf_info_to_howto #define elf_backend_plt_not_loaded 1 -#define elf_backend_rela_normal 1 +#define elf_backend_rela_normal 1 #define bfd_elf32_bfd_reloc_type_lookup i370_elf_reloc_type_lookup #define bfd_elf32_bfd_set_private_flags i370_elf_set_private_flags #define bfd_elf32_bfd_merge_private_bfd_data i370_elf_merge_private_bfd_data #define elf_backend_relocate_section i370_elf_relocate_section -/* dynamic loader support is mostly broken; just enough here to be able to - * link glibc's ld.so without errors. - */ +/* Dynamic loader support is mostly broken; just enough here to be able to + link glibc's ld.so without errors. */ #define elf_backend_create_dynamic_sections i370_elf_create_dynamic_sections #define elf_backend_size_dynamic_sections i370_elf_size_dynamic_sections #define elf_backend_finish_dynamic_sections i370_elf_finish_dynamic_sections @@ -1505,37 +1432,27 @@ i370_elf_post_process_headers (abfd, link_info) #define elf_backend_section_from_shdr i370_elf_section_from_shdr #define elf_backend_adjust_dynamic_symbol i370_elf_adjust_dynamic_symbol #define elf_backend_check_relocs i370_elf_check_relocs - -/* -#define elf_backend_add_symbol_hook i370_elf_add_symbol_hook -#define elf_backend_finish_dynamic_symbol i370_elf_finish_dynamic_symbol -#define elf_backend_additional_program_headers i370_elf_additional_program_headers -#define elf_backend_modify_segment_map i370_elf_modify_segment_map -*/ - #define elf_backend_post_process_headers i370_elf_post_process_headers -static int i370_noop - PARAMS ((void)); - -static int i370_noop () +static int +i370_noop (void) { return 1; } -/* we need to define these at least as no-ops to link glibc ld.so */ +/* We need to define these at least as no-ops to link glibc ld.so. */ #define elf_backend_add_symbol_hook \ (bfd_boolean (*) \ - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *, \ - const char **, flagword *, asection **, bfd_vma *))) i370_noop + (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, \ + const char **, flagword *, asection **, bfd_vma *)) i370_noop #define elf_backend_finish_dynamic_symbol \ (bfd_boolean (*) \ - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, \ - Elf_Internal_Sym *))) i370_noop + (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, \ + Elf_Internal_Sym *)) i370_noop #define elf_backend_additional_program_headers \ - (int (*) PARAMS ((bfd *))) i370_noop + (int (*) (bfd *)) i370_noop #define elf_backend_modify_segment_map \ - (bfd_boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) i370_noop + (bfd_boolean (*) (bfd *, struct bfd_link_info *)) i370_noop #include "elf32-target.h" diff --git a/bfd/elf32-i960.c b/bfd/elf32-i960.c index 93db43559c1..f458320655b 100644 --- a/bfd/elf32-i960.c +++ b/bfd/elf32-i960.c @@ -1,21 +1,22 @@ /* Intel 960 specific support for 32-bit ELF - Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -23,33 +24,73 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "elf-bfd.h" #include "elf/i960.h" -static bfd_reloc_status_type elf32_i960_relocate - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *elf32_i960_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf32_i960_info_to_howto - PARAMS ((bfd *, arelent *cache_ptr, Elf_Internal_Rela *)); -static void elf32_i960_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); - #define USE_REL 1 #define bfd_elf32_bfd_reloc_type_lookup elf32_i960_reloc_type_lookup #define elf_info_to_howto elf32_i960_info_to_howto #define elf_info_to_howto_rel elf32_i960_info_to_howto_rel +/* ELF relocs are against symbols. If we are producing relocatable + output, and the reloc is against an external symbol, and nothing + has given us any additional addend, the resulting reloc will also + be against the same symbol. In such a case, we don't want to + change anything about the way the reloc is handled, since it will + all be done at final link time. Rather than put special case code + into bfd_perform_relocation, all the reloc types use this howto + function. It just short circuits the reloc if producing + relocatable output against an external symbol. */ + +static bfd_reloc_status_type +elf32_i960_relocate (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + PTR data ATTRIBUTE_UNUSED, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + /* HACK: I think this first condition is necessary when producing + relocatable output. After the end of HACK, the code is identical + to bfd_elf_generic_reloc(). I would _guess_ the first change + belongs there rather than here. martindo 1998-10-23. */ + if (output_bfd != (bfd *) NULL + && reloc_entry->howto->pc_relative + && !reloc_entry->howto->pcrel_offset) + reloc_entry->addend -= symbol->value; + + /* This is more dubious. */ + else if (output_bfd != (bfd *) NULL + && (symbol->flags & BSF_SECTION_SYM) != 0) + reloc_entry->addend -= symbol->section->output_section->vma; + + else + { + /* ...end of HACK. */ + if (output_bfd != (bfd *) NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && (! reloc_entry->howto->partial_inplace + || reloc_entry->addend == 0)) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + } + + return bfd_reloc_continue; +} + static reloc_howto_type elf_howto_table[]= { - HOWTO(R_960_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield, - elf32_i960_relocate, "R_960_NONE", TRUE, - 0x00000000, 0x00000000, FALSE), + HOWTO (R_960_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield, + elf32_i960_relocate, "R_960_NONE", TRUE, + 0x00000000, 0x00000000, FALSE), EMPTY_HOWTO (1), HOWTO (R_960_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, - elf32_i960_relocate, "R_960_32", TRUE, - 0xffffffff, 0xffffffff, FALSE), + elf32_i960_relocate, "R_960_32", TRUE, + 0xffffffff, 0xffffffff, FALSE), HOWTO (R_960_IP24, 0, 2, 24, TRUE, 0, complain_overflow_signed, - elf32_i960_relocate, "R_960_IP24 ", TRUE, - 0x00ffffff, 0x00ffffff, FALSE), + elf32_i960_relocate, "R_960_IP24 ", TRUE, + 0x00ffffff, 0x00ffffff, FALSE), EMPTY_HOWTO (4), EMPTY_HOWTO (5), EMPTY_HOWTO (6), @@ -74,19 +115,17 @@ elf32_i960_bfd_to_reloc_type (bfd_reloc_code_real_type code) } static void -elf32_i960_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr ATTRIBUTE_UNUSED; - Elf_Internal_Rela *dst ATTRIBUTE_UNUSED; +elf32_i960_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr ATTRIBUTE_UNUSED, + Elf_Internal_Rela * dst ATTRIBUTE_UNUSED) { abort (); } static void -elf32_i960_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +elf32_i960_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { enum elf_i960_reloc_type type; @@ -96,63 +135,9 @@ elf32_i960_info_to_howto_rel (abfd, cache_ptr, dst) cache_ptr->howto = &elf_howto_table[(int) type]; } -/* ELF relocs are against symbols. If we are producing relocatable - output, and the reloc is against an external symbol, and nothing - has given us any additional addend, the resulting reloc will also - be against the same symbol. In such a case, we don't want to - change anything about the way the reloc is handled, since it will - all be done at final link time. Rather than put special case code - into bfd_perform_relocation, all the reloc types use this howto - function. It just short circuits the reloc if producing - relocatable output against an external symbol. */ - -bfd_reloc_status_type -elf32_i960_relocate (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - /* HACK: I think this first condition is necessary when producing - relocatable output. After the end of HACK, the code is identical - to bfd_elf_generic_reloc(). I would _guess_ the first change - belongs there rather than here. martindo 1998-10-23. */ - if (output_bfd != (bfd *) NULL - && reloc_entry->howto->pc_relative - && !reloc_entry->howto->pcrel_offset) - { - reloc_entry->addend -= symbol->value; - } - /* This is more dubious. */ - else if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) != 0) - { - reloc_entry->addend -= symbol->section->output_section->vma; - } - else - { - /* end of HACK */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - } - - return bfd_reloc_continue; -} - static reloc_howto_type * -elf32_i960_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +elf32_i960_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { return elf_howto_table + elf32_i960_bfd_to_reloc_type (code); } diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c index 4645fa2046b..135ef1314ba 100644 --- a/bfd/elf32-ip2k.c +++ b/bfd/elf32-ip2k.c @@ -16,7 +16,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -39,59 +40,12 @@ struct ip2k_opcode unsigned short opcode; unsigned short mask; }; - -/* Prototypes. */ -static reloc_howto_type *ip2k_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static int ip2k_is_opcode - PARAMS ((bfd_byte *, const struct ip2k_opcode *)); -static bfd_vma symbol_value - PARAMS ((bfd *, Elf_Internal_Shdr *, Elf_Internal_Sym *, - Elf_Internal_Rela *)); -static void ip2k_get_mem - PARAMS ((bfd *, bfd_byte *, int, bfd_byte *)); -static bfd_vma ip2k_nominal_page_bits - PARAMS ((bfd *, asection *, bfd_vma, bfd_byte *)); -static bfd_boolean ip2k_test_page_insn - PARAMS ((bfd *, asection *, Elf_Internal_Rela *, struct misc *)); -static bfd_boolean ip2k_delete_page_insn - PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_boolean *, struct misc *)); -static int ip2k_is_switch_table_128 - PARAMS ((bfd *, asection *, bfd_vma, bfd_byte *)); -static bfd_boolean ip2k_relax_switch_table_128 - PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_boolean *, struct misc *)); -static int ip2k_is_switch_table_256 - PARAMS ((bfd *, asection *, bfd_vma, bfd_byte *)); -static bfd_boolean ip2k_relax_switch_table_256 - PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_boolean *, struct misc *)); -static bfd_boolean ip2k_elf_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *)); -static bfd_boolean ip2k_elf_relax_section_page - PARAMS ((bfd *, asection *, bfd_boolean *, struct misc *, unsigned long, unsigned long)); -static void adjust_all_relocations - PARAMS ((bfd *, asection *, bfd_vma, bfd_vma, int, int)); -static bfd_boolean ip2k_elf_relax_delete_bytes - PARAMS ((bfd *, asection *, bfd_vma, int)); -static void ip2k_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_reloc_status_type ip2k_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, bfd_vma)); -static bfd_boolean ip2k_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static asection *ip2k_elf_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static bfd_boolean ip2k_elf_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); static bfd_boolean ip2k_relaxed = FALSE; static const struct ip2k_opcode ip2k_page_opcode[] = { - {0x0010, 0xFFF8}, /* page */ + {0x0010, 0xFFF8}, /* Page. */ {0x0000, 0x0000}, }; @@ -100,7 +54,7 @@ static const struct ip2k_opcode ip2k_page_opcode[] = static const struct ip2k_opcode ip2k_jmp_opcode[] = { - {0xE000, 0xE000}, /* jmp */ + {0xE000, 0xE000}, /* Jmp. */ {0x0000, 0x0000}, }; @@ -109,7 +63,7 @@ static const struct ip2k_opcode ip2k_jmp_opcode[] = static const struct ip2k_opcode ip2k_snc_opcode[] = { - {0xA00B, 0xFFFF}, /* snc */ + {0xA00B, 0xFFFF}, /* Snc. */ {0x0000, 0x0000}, }; @@ -118,7 +72,7 @@ static const struct ip2k_opcode ip2k_snc_opcode[] = static const struct ip2k_opcode ip2k_inc_1sp_opcode[] = { - {0x2B81, 0xFFFF}, /* inc 1(SP) */ + {0x2B81, 0xFFFF}, /* Inc 1(SP). */ {0x0000, 0x0000}, }; @@ -127,7 +81,7 @@ static const struct ip2k_opcode ip2k_inc_1sp_opcode[] = static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] = { - {0x1F82, 0xFFFF}, /* add 2(SP),w */ + {0x1F82, 0xFFFF}, /* Add 2(SP),w. */ {0x0000, 0x0000}, }; @@ -136,8 +90,8 @@ static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] = static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] = { - {0x1C0A, 0xFFFF}, /* add w,wreg */ - {0x1E0A, 0xFFFF}, /* add wreg,w */ + {0x1C0A, 0xFFFF}, /* Add w,wreg. */ + {0x1E0A, 0xFFFF}, /* Add wreg,w. */ {0x0000, 0x0000}, }; @@ -146,7 +100,7 @@ static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] = static const struct ip2k_opcode ip2k_add_pcl_w_opcode[] = { - {0x1E09, 0xFFFF}, /* add pcl,w */ + {0x1E09, 0xFFFF}, /* Add pcl,w. */ {0x0000, 0x0000}, }; @@ -220,10 +174,10 @@ static reloc_howto_type ip2k_elf_howto_table [] = /* Map BFD reloc types to IP2K ELF reloc types. */ + static reloc_howto_type * -ip2k_reloc_type_lookup (abfd, code) - bfd * abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +ip2k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { /* Note that the ip2k_elf_howto_table is indxed by the R_ constants. Thus, the order that the howto records appear in the @@ -270,20 +224,17 @@ ip2k_reloc_type_lookup (abfd, code) } static void -ip2k_get_mem (abfd, addr, length, ptr) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_byte *addr; - int length; - bfd_byte *ptr; +ip2k_get_mem (bfd *abfd ATTRIBUTE_UNUSED, + bfd_byte *addr, + int length, + bfd_byte *ptr) { while (length --) * ptr ++ = bfd_get_8 (abfd, addr ++); } static bfd_boolean -ip2k_is_opcode (code, opcodes) - bfd_byte *code; - const struct ip2k_opcode *opcodes; +ip2k_is_opcode (bfd_byte *code, const struct ip2k_opcode *opcodes) { unsigned short insn = (code[0] << 8) | code[1]; @@ -306,11 +257,10 @@ ip2k_is_opcode (code, opcodes) /* Return the value of the symbol associated with the relocation IREL. */ static bfd_vma -symbol_value (abfd, symtab_hdr, isymbuf, irel) - bfd *abfd; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Sym *isymbuf; - Elf_Internal_Rela *irel; +symbol_value (bfd *abfd, + Elf_Internal_Shdr *symtab_hdr, + Elf_Internal_Sym *isymbuf, + Elf_Internal_Rela *irel) { if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) { @@ -346,15 +296,177 @@ symbol_value (abfd, symtab_hdr, isymbuf, irel) } } +/* Determine if the instruction sequence matches that for + the prologue of a switch dispatch table with fewer than + 128 entries. + + sc + page $nnn0 + jmp $nnn0 + add w,wreg + add pcl,w + addr=> + page $nnn1 + jmp $nnn1 + page $nnn2 + jmp $nnn2 + ... + page $nnnN + jmp $nnnN + + After relaxation. + sc + page $nnn0 + jmp $nnn0 + add pcl,w + addr=> + jmp $nnn1 + jmp $nnn2 + ... + jmp $nnnN */ + +static int +ip2k_is_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + bfd_vma addr, + bfd_byte *contents) +{ + bfd_byte code[4]; + int index = 0; + + /* Check current page-jmp. */ + if (addr + 4 > sec->size) + return -1; + + ip2k_get_mem (abfd, contents + addr, 4, code); + + if ((! IS_PAGE_OPCODE (code + 0)) + || (! IS_JMP_OPCODE (code + 2))) + return -1; + + /* Search back. */ + while (1) + { + if (addr < 4) + return -1; + + /* Check previous 2 instructions. */ + ip2k_get_mem (abfd, contents + addr - 4, 4, code); + if ((IS_ADD_W_WREG_OPCODE (code + 0)) + && (IS_ADD_PCL_W_OPCODE (code + 2))) + return index; + + if ((! IS_PAGE_OPCODE (code + 0)) + || (! IS_JMP_OPCODE (code + 2))) + return -1; + + index++; + addr -= 4; + } +} + +/* Determine if the instruction sequence matches that for + the prologue switch dispatch table with fewer than + 256 entries but more than 127. + + Before relaxation. + push %lo8insn(label) ; Push address of table + push %hi8insn(label) + add w,wreg ; index*2 => offset + snc ; CARRY SET? + inc 1(sp) ; Propagate MSB into table address + add 2(sp),w ; Add low bits of offset to table address + snc ; and handle any carry-out + inc 1(sp) + addr=> + page __indjmp ; Do an indirect jump to that location + jmp __indjmp + label: ; case dispatch table starts here + page $nnn1 + jmp $nnn1 + page $nnn2 + jmp $nnn2 + ... + page $nnnN + jmp $nnnN + + After relaxation. + push %lo8insn(label) ; Push address of table + push %hi8insn(label) + add 2(sp),w ; Add low bits of offset to table address + snc ; and handle any carry-out + inc 1(sp) + addr=> + page __indjmp ; Do an indirect jump to that location + jmp __indjmp + label: ; case dispatch table starts here + jmp $nnn1 + jmp $nnn2 + ... + jmp $nnnN */ + +static int +ip2k_is_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + bfd_vma addr, + bfd_byte *contents) +{ + bfd_byte code[16]; + int index = 0; + + /* Check current page-jmp. */ + if (addr + 4 > sec->size) + return -1; + + ip2k_get_mem (abfd, contents + addr, 4, code); + if ((! IS_PAGE_OPCODE (code + 0)) + || (! IS_JMP_OPCODE (code + 2))) + return -1; + + /* Search back. */ + while (1) + { + if (addr < 16) + return -1; + + /* Check previous 8 instructions. */ + ip2k_get_mem (abfd, contents + addr - 16, 16, code); + if ((IS_ADD_W_WREG_OPCODE (code + 0)) + && (IS_SNC_OPCODE (code + 2)) + && (IS_INC_1SP_OPCODE (code + 4)) + && (IS_ADD_2SP_W_OPCODE (code + 6)) + && (IS_SNC_OPCODE (code + 8)) + && (IS_INC_1SP_OPCODE (code + 10)) + && (IS_PAGE_OPCODE (code + 12)) + && (IS_JMP_OPCODE (code + 14))) + return index; + + if ((IS_ADD_W_WREG_OPCODE (code + 2)) + && (IS_SNC_OPCODE (code + 4)) + && (IS_INC_1SP_OPCODE (code + 6)) + && (IS_ADD_2SP_W_OPCODE (code + 8)) + && (IS_SNC_OPCODE (code + 10)) + && (IS_INC_1SP_OPCODE (code + 12)) + && (IS_JMP_OPCODE (code + 14))) + return index; + + if ((! IS_PAGE_OPCODE (code + 0)) + || (! IS_JMP_OPCODE (code + 2))) + return -1; + + index++; + addr -= 4; + } +} + /* Returns the expected page state for the given instruction not including the effect of page instructions. */ static bfd_vma -ip2k_nominal_page_bits (abfd, sec, addr, contents) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - bfd_vma addr; - bfd_byte *contents; +ip2k_nominal_page_bits (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + bfd_vma addr, + bfd_byte *contents) { bfd_vma page = PAGENO (BASEADDR (sec) + addr); @@ -405,11 +517,10 @@ ip2k_nominal_page_bits (abfd, sec, addr, contents) } static bfd_boolean -ip2k_test_page_insn (abfd, sec, irel, misc) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - Elf_Internal_Rela *irel; - struct misc *misc; +ip2k_test_page_insn (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + Elf_Internal_Rela *irel, + struct misc *misc) { bfd_vma symval; @@ -429,13 +540,269 @@ ip2k_test_page_insn (abfd, sec, irel, misc) return TRUE; } +/* Parts of a Stabs entry. */ + +#define STRDXOFF 0 +#define TYPEOFF 4 +#define OTHEROFF 5 +#define DESCOFF 6 +#define VALOFF 8 +#define STABSIZE 12 + +/* Adjust all the relocations entries after adding or inserting instructions. */ + +static void +adjust_all_relocations (bfd *abfd, + asection *sec, + bfd_vma addr, + bfd_vma endaddr, + int count, + int noadj) +{ + Elf_Internal_Shdr *symtab_hdr; + Elf_Internal_Sym *isymbuf, *isym, *isymend; + unsigned int shndx; + bfd_byte *contents; + Elf_Internal_Rela *irel, *irelend, *irelbase; + struct elf_link_hash_entry **sym_hashes; + struct elf_link_hash_entry **end_hashes; + unsigned int symcount; + asection *stab; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; + + shndx = _bfd_elf_section_from_bfd_section (abfd, sec); + + contents = elf_section_data (sec)->this_hdr.contents; + + irelbase = elf_section_data (sec)->relocs; + irelend = irelbase + sec->reloc_count; + + for (irel = irelbase; irel < irelend; irel++) + { + if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE) + { + /* Get the value of the symbol referred to by the reloc. */ + if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) + { + asection *sym_sec; + + /* A local symbol. */ + isym = isymbuf + ELF32_R_SYM (irel->r_info); + sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); + + if (isym->st_shndx == shndx) + { + bfd_vma baseaddr = BASEADDR (sec); + bfd_vma symval = BASEADDR (sym_sec) + isym->st_value + + irel->r_addend; + + if ((baseaddr + addr + noadj) <= symval + && symval < (baseaddr + endaddr)) + irel->r_addend += count; + } + } + } + + /* Do this only for PC space relocations. */ + if (addr <= irel->r_offset && irel->r_offset < endaddr) + irel->r_offset += count; + } + + /* Now fix the stab relocations. */ + stab = bfd_get_section_by_name (abfd, ".stab"); + if (stab) + { + bfd_byte *stabcontents, *stabend, *stabp; + bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size; + + irelbase = elf_section_data (stab)->relocs; + irelend = irelbase + stab->reloc_count; + + /* Pull out the contents of the stab section. */ + if (elf_section_data (stab)->this_hdr.contents != NULL) + stabcontents = elf_section_data (stab)->this_hdr.contents; + else + { + if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents)) + { + if (stabcontents != NULL) + free (stabcontents); + return; + } + + /* We need to remember this. */ + elf_section_data (stab)->this_hdr.contents = stabcontents; + } + + stabend = stabcontents + stab_size; + + for (irel = irelbase; irel < irelend; irel++) + { + if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE) + { + /* Get the value of the symbol referred to by the reloc. */ + if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) + { + asection *sym_sec; + + /* A local symbol. */ + isym = isymbuf + ELF32_R_SYM (irel->r_info); + sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); + + if (sym_sec == sec) + { + const char *name; + unsigned long strx; + unsigned char type, other; + unsigned short desc; + bfd_vma value; + bfd_vma baseaddr = BASEADDR (sec); + bfd_vma symval = BASEADDR (sym_sec) + isym->st_value + + irel->r_addend; + + if ((baseaddr + addr) <= symval + && symval <= (baseaddr + endaddr)) + irel->r_addend += count; + + /* Go hunt up a function and fix its line info if needed. */ + stabp = stabcontents + irel->r_offset - 8; + + /* Go pullout the stab entry. */ + strx = bfd_h_get_32 (abfd, stabp + STRDXOFF); + type = bfd_h_get_8 (abfd, stabp + TYPEOFF); + other = bfd_h_get_8 (abfd, stabp + OTHEROFF); + desc = bfd_h_get_16 (abfd, stabp + DESCOFF); + value = bfd_h_get_32 (abfd, stabp + VALOFF); + + name = bfd_get_stab_name (type); + + if (strcmp (name, "FUN") == 0) + { + int function_adjusted = 0; + + if (symval > (baseaddr + addr)) + /* Not in this function. */ + continue; + + /* Hey we got a function hit. */ + stabp += STABSIZE; + for (;stabp < stabend; stabp += STABSIZE) + { + /* Go pullout the stab entry. */ + strx = bfd_h_get_32 (abfd, stabp + STRDXOFF); + type = bfd_h_get_8 (abfd, stabp + TYPEOFF); + other = bfd_h_get_8 (abfd, stabp + OTHEROFF); + desc = bfd_h_get_16 (abfd, stabp + DESCOFF); + value = bfd_h_get_32 (abfd, stabp + VALOFF); + + name = bfd_get_stab_name (type); + + if (strcmp (name, "FUN") == 0) + { + /* Hit another function entry. */ + if (function_adjusted) + { + /* Adjust the value. */ + value += count; + + /* We need to put it back. */ + bfd_h_put_32 (abfd, value,stabp + VALOFF); + } + + /* And then bale out. */ + break; + } + + if (strcmp (name, "SLINE") == 0) + { + /* Got a line entry. */ + if ((baseaddr + addr) <= (symval + value)) + { + /* Adjust the line entry. */ + value += count; + + /* We need to put it back. */ + bfd_h_put_32 (abfd, value,stabp + VALOFF); + function_adjusted = 1; + } + } + } + } + } + } + } + } + } + + /* When adding an instruction back it is sometimes necessary to move any + global or local symbol that was referencing the first instruction of + the moved block to refer to the first instruction of the inserted block. + + For example adding a PAGE instruction before a CALL or JMP requires + that any label on the CALL or JMP is moved to the PAGE insn. */ + addr += noadj; + + /* Adjust the local symbols defined in this section. */ + isymend = isymbuf + symtab_hdr->sh_info; + for (isym = isymbuf; isym < isymend; isym++) + { + if (isym->st_shndx == shndx + && addr <= isym->st_value + && isym->st_value < endaddr) + isym->st_value += count; + } + + /* Now adjust the global symbols defined in this section. */ + symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) + - symtab_hdr->sh_info); + sym_hashes = elf_sym_hashes (abfd); + end_hashes = sym_hashes + symcount; + for (; sym_hashes < end_hashes; sym_hashes++) + { + struct elf_link_hash_entry *sym_hash = *sym_hashes; + + if ((sym_hash->root.type == bfd_link_hash_defined + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec) + { + if (addr <= sym_hash->root.u.def.value + && sym_hash->root.u.def.value < endaddr) + sym_hash->root.u.def.value += count; + } + } + + return; +} + +/* Delete some bytes from a section while relaxing. */ + +static bfd_boolean +ip2k_elf_relax_delete_bytes (bfd *abfd, + asection *sec, + bfd_vma addr, + int count) +{ + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; + bfd_vma endaddr = sec->size; + + /* Actually delete the bytes. */ + memmove (contents + addr, contents + addr + count, + endaddr - addr - count); + + sec->size -= count; + + adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0); + return TRUE; +} + static bfd_boolean -ip2k_delete_page_insn (abfd, sec, irel, again, misc) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - Elf_Internal_Rela *irel; - bfd_boolean *again; - struct misc *misc; +ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + Elf_Internal_Rela *irel, + bfd_boolean *again, + struct misc *misc) { /* Note that we've changed the relocs, section contents, etc. */ elf_section_data (sec)->relocs = misc->irelbase; @@ -455,83 +822,12 @@ ip2k_delete_page_insn (abfd, sec, irel, again, misc) return TRUE; } -/* Determine if the instruction sequence matches that for - the prologue of a switch dispatch table with fewer than - 128 entries. - - sc - page $nnn0 - jmp $nnn0 - add w,wreg - add pcl,w - addr=> - page $nnn1 - jmp $nnn1 - page $nnn2 - jmp $nnn2 - ... - page $nnnN - jmp $nnnN - - After relaxation. - sc - page $nnn0 - jmp $nnn0 - add pcl,w - addr=> - jmp $nnn1 - jmp $nnn2 - ... - jmp $nnnN */ - -static int -ip2k_is_switch_table_128 (abfd, sec, addr, contents) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - bfd_vma addr; - bfd_byte *contents; -{ - bfd_byte code[4]; - int index = 0; - - /* Check current page-jmp. */ - if (addr + 4 > sec->size) - return -1; - - ip2k_get_mem (abfd, contents + addr, 4, code); - - if ((! IS_PAGE_OPCODE (code + 0)) - || (! IS_JMP_OPCODE (code + 2))) - return -1; - - /* Search back. */ - while (1) - { - if (addr < 4) - return -1; - - /* Check previous 2 instructions. */ - ip2k_get_mem (abfd, contents + addr - 4, 4, code); - if ((IS_ADD_W_WREG_OPCODE (code + 0)) - && (IS_ADD_PCL_W_OPCODE (code + 2))) - return index; - - if ((! IS_PAGE_OPCODE (code + 0)) - || (! IS_JMP_OPCODE (code + 2))) - return -1; - - index++; - addr -= 4; - } -} - static bfd_boolean -ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - Elf_Internal_Rela *irel; - bfd_boolean *again; - struct misc *misc; +ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + Elf_Internal_Rela *irel, + bfd_boolean *again, + struct misc *misc) { Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count; Elf_Internal_Rela *ireltest = irel; @@ -597,108 +893,12 @@ ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc) return TRUE; } -/* Determine if the instruction sequence matches that for - the prologue switch dispatch table with fewer than - 256 entries but more than 127. - - Before relaxation. - push %lo8insn(label) ; Push address of table - push %hi8insn(label) - add w,wreg ; index*2 => offset - snc ; CARRY SET? - inc 1(sp) ; Propagate MSB into table address - add 2(sp),w ; Add low bits of offset to table address - snc ; and handle any carry-out - inc 1(sp) - addr=> - page __indjmp ; Do an indirect jump to that location - jmp __indjmp - label: ; case dispatch table starts here - page $nnn1 - jmp $nnn1 - page $nnn2 - jmp $nnn2 - ... - page $nnnN - jmp $nnnN - - After relaxation. - push %lo8insn(label) ; Push address of table - push %hi8insn(label) - add 2(sp),w ; Add low bits of offset to table address - snc ; and handle any carry-out - inc 1(sp) - addr=> - page __indjmp ; Do an indirect jump to that location - jmp __indjmp - label: ; case dispatch table starts here - jmp $nnn1 - jmp $nnn2 - ... - jmp $nnnN */ - -static int -ip2k_is_switch_table_256 (abfd, sec, addr, contents) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - bfd_vma addr; - bfd_byte *contents; -{ - bfd_byte code[16]; - int index = 0; - - /* Check current page-jmp. */ - if (addr + 4 > sec->size) - return -1; - - ip2k_get_mem (abfd, contents + addr, 4, code); - if ((! IS_PAGE_OPCODE (code + 0)) - || (! IS_JMP_OPCODE (code + 2))) - return -1; - - /* Search back. */ - while (1) - { - if (addr < 16) - return -1; - - /* Check previous 8 instructions. */ - ip2k_get_mem (abfd, contents + addr - 16, 16, code); - if ((IS_ADD_W_WREG_OPCODE (code + 0)) - && (IS_SNC_OPCODE (code + 2)) - && (IS_INC_1SP_OPCODE (code + 4)) - && (IS_ADD_2SP_W_OPCODE (code + 6)) - && (IS_SNC_OPCODE (code + 8)) - && (IS_INC_1SP_OPCODE (code + 10)) - && (IS_PAGE_OPCODE (code + 12)) - && (IS_JMP_OPCODE (code + 14))) - return index; - - if ((IS_ADD_W_WREG_OPCODE (code + 2)) - && (IS_SNC_OPCODE (code + 4)) - && (IS_INC_1SP_OPCODE (code + 6)) - && (IS_ADD_2SP_W_OPCODE (code + 8)) - && (IS_SNC_OPCODE (code + 10)) - && (IS_INC_1SP_OPCODE (code + 12)) - && (IS_JMP_OPCODE (code + 14))) - return index; - - if ((! IS_PAGE_OPCODE (code + 0)) - || (! IS_JMP_OPCODE (code + 2))) - return -1; - - index++; - addr -= 4; - } -} - static bfd_boolean -ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - Elf_Internal_Rela *irel; - bfd_boolean *again; - struct misc *misc; +ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + Elf_Internal_Rela *irel, + bfd_boolean *again, + struct misc *misc) { Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count; Elf_Internal_Rela *ireltest = irel; @@ -777,6 +977,75 @@ ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc) return TRUE; } +/* This function handles relaxation of a section in a specific page. */ + +static bfd_boolean +ip2k_elf_relax_section_page (bfd *abfd, + asection *sec, + bfd_boolean *again, + struct misc *misc, + unsigned long page_start, + unsigned long page_end) +{ + Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count; + Elf_Internal_Rela *irel; + int switch_table_128; + int switch_table_256; + + /* Walk thru the section looking for relaxation opportunities. */ + for (irel = misc->irelbase; irel < irelend; irel++) + { + if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3) + /* Ignore non page instructions. */ + continue; + + if (BASEADDR (sec) + irel->r_offset < page_start) + /* Ignore page instructions on earlier page - they have + already been processed. Remember that there is code flow + that crosses a page boundary. */ + continue; + + if (BASEADDR (sec) + irel->r_offset > page_end) + /* Flow beyond end of page => nothing more to do for this page. */ + return TRUE; + + /* Detect switch tables. */ + switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents); + switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents); + + if ((switch_table_128 > 0) || (switch_table_256 > 0)) + /* If the index is greater than 0 then it has already been processed. */ + continue; + + if (switch_table_128 == 0) + { + if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc)) + return FALSE; + + continue; + } + + if (switch_table_256 == 0) + { + if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc)) + return FALSE; + + continue; + } + + /* Simple relax. */ + if (ip2k_test_page_insn (abfd, sec, irel, misc)) + { + if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc)) + return FALSE; + + continue; + } + } + + return TRUE; +} + /* This function handles relaxing for the ip2k. Principle: Start with the first page and remove page instructions that @@ -788,11 +1057,10 @@ ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc) only policy to be used - pages can be removed but are never reinserted. */ static bfd_boolean -ip2k_elf_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - bfd_boolean *again; +ip2k_elf_relax_section (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + bfd_boolean *again) { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *internal_relocs; @@ -834,8 +1102,7 @@ ip2k_elf_relax_section (abfd, sec, link_info, again) symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, - (Elf_Internal_Rela *)NULL, + internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory); if (internal_relocs == NULL) goto error_return; @@ -848,8 +1115,7 @@ ip2k_elf_relax_section (abfd, sec, link_info, again) /* So stab does exits. */ Elf_Internal_Rela * irelbase; - irelbase = _bfd_elf_link_read_relocs (abfd, stab, NULL, - (Elf_Internal_Rela *)NULL, + irelbase = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL, link_info->keep_memory); } @@ -973,371 +1239,29 @@ ip2k_elf_relax_section (abfd, sec, link_info, again) return FALSE; } -/* This function handles relaxation of a section in a specific page. */ - -static bfd_boolean -ip2k_elf_relax_section_page (abfd, sec, again, misc, page_start, page_end) - bfd *abfd; - asection *sec; - bfd_boolean *again; - struct misc *misc; - unsigned long page_start; - unsigned long page_end; -{ - Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count; - Elf_Internal_Rela *irel; - int switch_table_128; - int switch_table_256; - - /* Walk thru the section looking for relaxation opportunities. */ - for (irel = misc->irelbase; irel < irelend; irel++) - { - if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3) - /* Ignore non page instructions. */ - continue; - - if (BASEADDR (sec) + irel->r_offset < page_start) - /* Ignore page instructions on earlier page - they have - already been processed. Remember that there is code flow - that crosses a page boundary. */ - continue; - - if (BASEADDR (sec) + irel->r_offset > page_end) - /* Flow beyond end of page => nothing more to do for this page. */ - return TRUE; - - /* Detect switch tables. */ - switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents); - switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents); - - if ((switch_table_128 > 0) || (switch_table_256 > 0)) - /* If the index is greater than 0 then it has already been processed. */ - continue; - - if (switch_table_128 == 0) - { - if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc)) - return FALSE; - - continue; - } - - if (switch_table_256 == 0) - { - if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc)) - return FALSE; - - continue; - } - - /* Simple relax. */ - if (ip2k_test_page_insn (abfd, sec, irel, misc)) - { - if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc)) - return FALSE; - - continue; - } - } - - return TRUE; -} - -/* Parts of a Stabs entry. */ - -#define STRDXOFF (0) -#define TYPEOFF (4) -#define OTHEROFF (5) -#define DESCOFF (6) -#define VALOFF (8) -#define STABSIZE (12) - -/* Adjust all the relocations entries after adding or inserting instructions. */ - -static void -adjust_all_relocations (abfd, sec, addr, endaddr, count, noadj) - bfd *abfd; - asection *sec; - bfd_vma addr; - bfd_vma endaddr; - int count; - int noadj; -{ - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Sym *isymbuf, *isym, *isymend; - unsigned int shndx; - bfd_byte *contents; - Elf_Internal_Rela *irel, *irelend, *irelbase; - struct elf_link_hash_entry **sym_hashes; - struct elf_link_hash_entry **end_hashes; - unsigned int symcount; - asection *stab; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; - - shndx = _bfd_elf_section_from_bfd_section (abfd, sec); - - contents = elf_section_data (sec)->this_hdr.contents; - - irelbase = elf_section_data (sec)->relocs; - irelend = irelbase + sec->reloc_count; - - for (irel = irelbase; irel < irelend; irel++) - { - if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE) - { - /* Get the value of the symbol referred to by the reloc. */ - if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) - { - asection *sym_sec; - - /* A local symbol. */ - isym = isymbuf + ELF32_R_SYM (irel->r_info); - sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); - - if (isym->st_shndx == shndx) - { - bfd_vma baseaddr = BASEADDR (sec); - bfd_vma symval = BASEADDR (sym_sec) + isym->st_value - + irel->r_addend; - - if ((baseaddr + addr + noadj) <= symval - && symval < (baseaddr + endaddr)) - irel->r_addend += count; - } - } - } - - /* Do this only for PC space relocations. */ - if (addr <= irel->r_offset && irel->r_offset < endaddr) - irel->r_offset += count; - } - - /* Now fix the stab relocations. */ - stab = bfd_get_section_by_name (abfd, ".stab"); - if (stab) - { - bfd_byte *stabcontents, *stabend, *stabp; - bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size; - - irelbase = elf_section_data (stab)->relocs; - irelend = irelbase + stab->reloc_count; - - /* Pull out the contents of the stab section. */ - if (elf_section_data (stab)->this_hdr.contents != NULL) - stabcontents = elf_section_data (stab)->this_hdr.contents; - else - { - if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents)) - { - if (stabcontents != NULL) - free (stabcontents); - return; - } - - /* We need to remember this. */ - elf_section_data (stab)->this_hdr.contents = stabcontents; - } - - stabend = stabcontents + stab_size; - - for (irel = irelbase; irel < irelend; irel++) - { - if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE) - { - /* Get the value of the symbol referred to by the reloc. */ - if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) - { - asection *sym_sec; - - /* A local symbol. */ - isym = isymbuf + ELF32_R_SYM (irel->r_info); - sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); - - if (sym_sec == sec) - { - const char *name; - unsigned long strx; - unsigned char type, other; - unsigned short desc; - bfd_vma value; - bfd_vma baseaddr = BASEADDR (sec); - bfd_vma symval = BASEADDR (sym_sec) + isym->st_value - + irel->r_addend; - - if ((baseaddr + addr) <= symval - && symval <= (baseaddr + endaddr)) - irel->r_addend += count; - - /* Go hunt up a function and fix its line info if needed. */ - stabp = stabcontents + irel->r_offset - 8; - - /* Go pullout the stab entry. */ - strx = bfd_h_get_32 (abfd, stabp + STRDXOFF); - type = bfd_h_get_8 (abfd, stabp + TYPEOFF); - other = bfd_h_get_8 (abfd, stabp + OTHEROFF); - desc = bfd_h_get_16 (abfd, stabp + DESCOFF); - value = bfd_h_get_32 (abfd, stabp + VALOFF); - - name = bfd_get_stab_name (type); - - if (strcmp (name, "FUN") == 0) - { - int function_adjusted = 0; - - if (symval > (baseaddr + addr)) - /* Not in this function. */ - continue; - - /* Hey we got a function hit. */ - stabp += STABSIZE; - for (;stabp < stabend; stabp += STABSIZE) - { - /* Go pullout the stab entry. */ - strx = bfd_h_get_32 (abfd, stabp + STRDXOFF); - type = bfd_h_get_8 (abfd, stabp + TYPEOFF); - other = bfd_h_get_8 (abfd, stabp + OTHEROFF); - desc = bfd_h_get_16 (abfd, stabp + DESCOFF); - value = bfd_h_get_32 (abfd, stabp + VALOFF); - - name = bfd_get_stab_name (type); - - if (strcmp (name, "FUN") == 0) - { - /* Hit another function entry. */ - if (function_adjusted) - { - /* Adjust the value. */ - value += count; - - /* We need to put it back. */ - bfd_h_put_32 (abfd, value,stabp + VALOFF); - } - - /* And then bale out. */ - break; - } - - if (strcmp (name, "SLINE") == 0) - { - /* Got a line entry. */ - if ((baseaddr + addr) <= (symval + value)) - { - /* Adjust the line entry. */ - value += count; - - /* We need to put it back. */ - bfd_h_put_32 (abfd, value,stabp + VALOFF); - function_adjusted = 1; - } - } - } - } - } - } - } - } - } - - /* When adding an instruction back it is sometimes necessary to move any - global or local symbol that was referencing the first instruction of - the moved block to refer to the first instruction of the inserted block. - - For example adding a PAGE instruction before a CALL or JMP requires - that any label on the CALL or JMP is moved to the PAGE insn. */ - addr += noadj; - - /* Adjust the local symbols defined in this section. */ - isymend = isymbuf + symtab_hdr->sh_info; - for (isym = isymbuf; isym < isymend; isym++) - { - if (isym->st_shndx == shndx - && addr <= isym->st_value - && isym->st_value < endaddr) - isym->st_value += count; - } - - /* Now adjust the global symbols defined in this section. */ - symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) - - symtab_hdr->sh_info); - sym_hashes = elf_sym_hashes (abfd); - end_hashes = sym_hashes + symcount; - for (; sym_hashes < end_hashes; sym_hashes++) - { - struct elf_link_hash_entry *sym_hash = *sym_hashes; - - if ((sym_hash->root.type == bfd_link_hash_defined - || sym_hash->root.type == bfd_link_hash_defweak) - && sym_hash->root.u.def.section == sec) - { - if (addr <= sym_hash->root.u.def.value - && sym_hash->root.u.def.value < endaddr) - sym_hash->root.u.def.value += count; - } - } - - return; -} - -/* Delete some bytes from a section while relaxing. */ - -static bfd_boolean -ip2k_elf_relax_delete_bytes (abfd, sec, addr, count) - bfd *abfd; - asection *sec; - bfd_vma addr; - int count; -{ - bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; - bfd_vma endaddr = sec->size; - - /* Actually delete the bytes. */ - memmove (contents + addr, contents + addr + count, - endaddr - addr - count); - - sec->size -= count; - - adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0); - return TRUE; -} - -/* -------------------------------------------------------------------- */ - -/* XXX: The following code is the result of a cut&paste. This unfortunate - practice is very widespread in the various target back-end files. */ - /* Set the howto pointer for a IP2K ELF reloc. */ static void -ip2k_info_to_howto_rela (abfd, cache_ptr, dst) - bfd * abfd ATTRIBUTE_UNUSED; - arelent * cache_ptr; - Elf_Internal_Rela * dst; +ip2k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr, + Elf_Internal_Rela * dst) { unsigned int r_type; r_type = ELF32_R_TYPE (dst->r_info); - switch (r_type) - { - default: - cache_ptr->howto = & ip2k_elf_howto_table [r_type]; - break; - } + cache_ptr->howto = & ip2k_elf_howto_table [r_type]; } /* Perform a single relocation. By default we use the standard BFD routines. */ static bfd_reloc_status_type -ip2k_final_link_relocate (howto, input_bfd, input_section, contents, rel, - relocation) - reloc_howto_type * howto; - bfd * input_bfd; - asection * input_section; - bfd_byte * contents; - Elf_Internal_Rela * rel; - bfd_vma relocation; +ip2k_final_link_relocate (reloc_howto_type * howto, + bfd * input_bfd, + asection * input_section, + bfd_byte * contents, + Elf_Internal_Rela * rel, + bfd_vma relocation) { static bfd_vma page_addr = 0; @@ -1383,11 +1307,13 @@ ip2k_final_link_relocate (howto, input_bfd, input_section, contents, rel, /* Preceding page instruction. Verify that the page instruction is really needed. One reason for the relaxation to miss a page is if the section is not marked as executable. */ - if (!ip2k_is_switch_table_128 (input_bfd, input_section, rel->r_offset - 2, contents) && - !ip2k_is_switch_table_256 (input_bfd, input_section, rel->r_offset - 2, contents) && - (PAGENO (relocation + rel->r_addend) == - ip2k_nominal_page_bits (input_bfd, input_section, - rel->r_offset - 2, contents))) + if (!ip2k_is_switch_table_128 (input_bfd, input_section, + rel->r_offset - 2, contents) + && !ip2k_is_switch_table_256 (input_bfd, input_section, + rel->r_offset - 2, contents) + && (PAGENO (relocation + rel->r_addend) == + ip2k_nominal_page_bits (input_bfd, input_section, + rel->r_offset - 2, contents))) _bfd_error_handler (_("ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."), page_addr, relocation + rel->r_addend); @@ -1459,16 +1385,14 @@ ip2k_final_link_relocate (howto, input_bfd, input_section, contents, rel, accordingly. */ static bfd_boolean -ip2k_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1531,7 +1455,7 @@ ip2k_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (r != bfd_reloc_ok) { - const char * msg = (const char *) NULL; + const char * msg = NULL; switch (r) { @@ -1579,12 +1503,11 @@ ip2k_elf_relocate_section (output_bfd, info, input_bfd, input_section, } static asection * -ip2k_elf_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +ip2k_elf_gc_mark_hook (asection *sec, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { if (h != NULL) { @@ -1617,11 +1540,10 @@ ip2k_elf_gc_mark_hook (sec, info, rel, h, sym) } static bfd_boolean -ip2k_elf_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - asection *sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; +ip2k_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) { /* We don't use got and plt entries for ip2k. */ return TRUE; diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index a95a5c104bb..ea6a40d1a46 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -24,85 +24,6 @@ #include "elf-bfd.h" #include "elf/m32r.h" -static bfd_reloc_status_type m32r_elf_10_pcrel_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type m32r_elf_do_10_pcrel_reloc - PARAMS ((bfd *, reloc_howto_type *, asection *, - bfd_byte *, bfd_vma, asection *, bfd_vma, bfd_vma)); -static bfd_reloc_status_type m32r_elf_hi16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static void m32r_elf_relocate_hi16 - PARAMS ((bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, - bfd_byte *, bfd_vma)); -bfd_reloc_status_type m32r_elf_lo16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -bfd_reloc_status_type m32r_elf_generic_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type m32r_elf_sda16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void m32r_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static void m32r_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -bfd_boolean _bfd_m32r_elf_section_from_bfd_section - PARAMS ((bfd *, asection *, int *)); -void _bfd_m32r_elf_symbol_processing - PARAMS ((bfd *, asymbol *)); -static bfd_boolean m32r_elf_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); -static bfd_boolean m32r_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_reloc_status_type m32r_elf_final_sda_base - PARAMS ((bfd *, struct bfd_link_info *, const char **, bfd_vma *)); -static bfd_boolean m32r_elf_object_p - PARAMS ((bfd *)); -static void m32r_elf_final_write_processing - PARAMS ((bfd *, bfd_boolean)); -static bfd_boolean m32r_elf_set_private_flags - PARAMS ((bfd *, flagword)); -static bfd_boolean m32r_elf_merge_private_bfd_data - PARAMS ((bfd *, bfd *)); -static bfd_boolean m32r_elf_print_private_bfd_data - PARAMS ((bfd *, PTR)); -static bfd_boolean m32r_elf_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean m32r_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); - -static bfd_boolean m32r_elf_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static bfd_boolean m32r_elf_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -asection * m32r_elf_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); - -static bfd_boolean m32r_elf_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -static bfd_boolean m32r_elf_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -static bfd_boolean m32r_elf_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); - -static bfd_boolean allocate_dynrelocs - PARAMS ((struct elf_link_hash_entry *, PTR)); -static bfd_boolean readonly_dynrelocs - PARAMS ((struct elf_link_hash_entry *, PTR)); -static enum elf_reloc_type_class m32r_elf_reloc_type_class - PARAMS ((const Elf_Internal_Rela *)); -static bfd_boolean m32r_elf_fake_sections - PARAMS ((bfd *, Elf_Internal_Shdr *, asection *)); - #define NOP_INSN 0x7000 #define MAKE_PARALLEL(insn) ((insn) | 0x8000) @@ -115,7 +36,7 @@ static bfd_boolean m32r_elf_fake_sections #ifndef USE_REL #define USE_REL 0 #endif */ -/* Use RELA. But use REL to link old objects for backwords compatibility. */ +/* Use RELA. But use REL to link old objects for backwords compatibility. */ /* Functions for the M32R ELF linker. */ @@ -160,6 +81,394 @@ static bfd_boolean m32r_elf_fake_sections #define PLT_ENTRY_WORD4 0xff000000 /* bra .plt0. */ +/* Utility to actually perform an R_M32R_10_PCREL reloc. */ + +static bfd_reloc_status_type +m32r_elf_do_10_pcrel_reloc (bfd *abfd, + reloc_howto_type *howto, + asection *input_section, + bfd_byte *data, + bfd_vma offset, + asection *symbol_section ATTRIBUTE_UNUSED, + bfd_vma symbol_value, + bfd_vma addend) +{ + bfd_signed_vma relocation; + unsigned long x; + bfd_reloc_status_type status; + + /* Sanity check the address (offset in section). */ + if (offset > bfd_get_section_limit (abfd, input_section)) + return bfd_reloc_outofrange; + + relocation = symbol_value + addend; + /* Make it pc relative. */ + relocation -= (input_section->output_section->vma + + input_section->output_offset); + /* These jumps mask off the lower two bits of the current address + before doing pcrel calculations. */ + relocation -= (offset & -(bfd_vma) 4); + + if (relocation < -0x200 || relocation > 0x1ff) + status = bfd_reloc_overflow; + else + status = bfd_reloc_ok; + + x = bfd_get_16 (abfd, data + offset); + relocation >>= howto->rightshift; + relocation <<= howto->bitpos; + x = (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask); + bfd_put_16 (abfd, (bfd_vma) x, data + offset); + + return status; +} + +/* Handle the R_M32R_10_PCREL reloc. */ + +static bfd_reloc_status_type +m32r_elf_10_pcrel_reloc (bfd * abfd, + arelent * reloc_entry, + asymbol * symbol, + void * data, + asection * input_section, + bfd * output_bfd, + char ** error_message ATTRIBUTE_UNUSED) +{ + /* This part is from bfd_elf_generic_reloc. */ + if (output_bfd != NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && (! reloc_entry->howto->partial_inplace + || reloc_entry->addend == 0)) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (output_bfd != NULL) + /* FIXME: See bfd_perform_relocation. Is this right? */ + return bfd_reloc_continue; + + return m32r_elf_do_10_pcrel_reloc (abfd, reloc_entry->howto, + input_section, + data, reloc_entry->address, + symbol->section, + (symbol->value + + symbol->section->output_section->vma + + symbol->section->output_offset), + reloc_entry->addend); +} + +/* Do generic partial_inplace relocation. + This is a local replacement for bfd_elf_generic_reloc. */ + +static bfd_reloc_status_type +m32r_elf_generic_reloc (bfd *input_bfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + bfd_reloc_status_type ret; + bfd_vma relocation; + bfd_byte *inplace_address; + + /* This part is from bfd_elf_generic_reloc. + If we're relocating, and this an external symbol, we don't want + to change anything. */ + if (output_bfd != NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && reloc_entry->addend == 0) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + /* Now do the reloc in the usual way. + ??? It would be nice to call bfd_elf_generic_reloc here, + but we have partial_inplace set. bfd_elf_generic_reloc will + pass the handling back to bfd_install_relocation which will install + a section relative addend which is wrong. */ + + /* Sanity check the address (offset in section). */ + if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section)) + return bfd_reloc_outofrange; + + ret = bfd_reloc_ok; + if (bfd_is_und_section (symbol->section) + && output_bfd == NULL) + ret = bfd_reloc_undefined; + + if (bfd_is_com_section (symbol->section) + || output_bfd != NULL) + relocation = 0; + else + relocation = symbol->value; + + /* Only do this for a final link. */ + if (output_bfd == NULL) + { + relocation += symbol->section->output_section->vma; + relocation += symbol->section->output_offset; + } + + relocation += reloc_entry->addend; + inplace_address = (bfd_byte *) data + reloc_entry->address; + +#define DOIT(x) \ + x = ( (x & ~reloc_entry->howto->dst_mask) | \ + (((x & reloc_entry->howto->src_mask) + relocation) & \ + reloc_entry->howto->dst_mask)) + + switch (reloc_entry->howto->size) + { + case 1: + { + short x = bfd_get_16 (input_bfd, inplace_address); + DOIT (x); + bfd_put_16 (input_bfd, (bfd_vma) x, inplace_address); + } + break; + case 2: + { + unsigned long x = bfd_get_32 (input_bfd, inplace_address); + DOIT (x); + bfd_put_32 (input_bfd, (bfd_vma)x , inplace_address); + } + break; + default: + BFD_ASSERT (0); + } + + if (output_bfd != NULL) + reloc_entry->address += input_section->output_offset; + + return ret; +} + +/* Handle the R_M32R_SDA16 reloc. + This reloc is used to compute the address of objects in the small data area + and to perform loads and stores from that area. + The lower 16 bits are sign extended and added to the register specified + in the instruction, which is assumed to point to _SDA_BASE_. */ + +static bfd_reloc_status_type +m32r_elf_sda16_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + void * data ATTRIBUTE_UNUSED, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + /* This part is from bfd_elf_generic_reloc. */ + if (output_bfd != NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && (! reloc_entry->howto->partial_inplace + || reloc_entry->addend == 0)) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (output_bfd != NULL) + /* FIXME: See bfd_perform_relocation. Is this right? */ + return bfd_reloc_continue; + + /* FIXME: not sure what to do here yet. But then again, the linker + may never call us. */ + abort (); +} + + +/* Handle the R_M32R_HI16_[SU]LO relocs. + HI16_SLO is for the add3 and load/store with displacement instructions. + HI16_ULO is for the or3 instruction. + For R_M32R_HI16_SLO, the lower 16 bits are sign extended when added to + the high 16 bytes so if the lower 16 bits are negative (bit 15 == 1) then + we must add one to the high 16 bytes (which will get subtracted off when + the low 16 bits are added). + These relocs have to be done in combination with an R_M32R_LO16 reloc + because there is a carry from the LO16 to the HI16. Here we just save + the information we need; we do the actual relocation when we see the LO16. + This code is copied from the elf32-mips.c. We also support an arbitrary + number of HI16 relocs to be associated with a single LO16 reloc. The + assembler sorts the relocs to ensure each HI16 immediately precedes its + LO16. However if there are multiple copies, the assembler may not find + the real LO16 so it picks the first one it finds. */ + +struct m32r_hi16 +{ + struct m32r_hi16 *next; + bfd_byte *addr; + bfd_vma addend; +}; + +/* FIXME: This should not be a static variable. */ + +static struct m32r_hi16 *m32r_hi16_list; + +static bfd_reloc_status_type +m32r_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + bfd_reloc_status_type ret; + bfd_vma relocation; + struct m32r_hi16 *n; + + /* This part is from bfd_elf_generic_reloc. + If we're relocating, and this an external symbol, we don't want + to change anything. */ + if (output_bfd != NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && reloc_entry->addend == 0) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + /* Sanity check the address (offset in section). */ + if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + return bfd_reloc_outofrange; + + ret = bfd_reloc_ok; + if (bfd_is_und_section (symbol->section) + && output_bfd == NULL) + ret = bfd_reloc_undefined; + + if (bfd_is_com_section (symbol->section)) + relocation = 0; + else + relocation = symbol->value; + + relocation += symbol->section->output_section->vma; + relocation += symbol->section->output_offset; + relocation += reloc_entry->addend; + + /* Save the information, and let LO16 do the actual relocation. */ + n = bfd_malloc ((bfd_size_type) sizeof *n); + if (n == NULL) + return bfd_reloc_outofrange; + n->addr = (bfd_byte *) data + reloc_entry->address; + n->addend = relocation; + n->next = m32r_hi16_list; + m32r_hi16_list = n; + + if (output_bfd != NULL) + reloc_entry->address += input_section->output_offset; + + return ret; +} + +/* Handle an M32R ELF HI16 reloc. */ + +static void +m32r_elf_relocate_hi16 (bfd *input_bfd, + int type, + Elf_Internal_Rela *relhi, + Elf_Internal_Rela *rello, + bfd_byte *contents, + bfd_vma addend) +{ + unsigned long insn; + bfd_vma addlo; + + insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); + + addlo = bfd_get_32 (input_bfd, contents + rello->r_offset); + if (type == R_M32R_HI16_SLO) + addlo = ((addlo & 0xffff) ^ 0x8000) - 0x8000; + else + addlo &= 0xffff; + + addend += ((insn & 0xffff) << 16) + addlo; + + /* Reaccount for sign extension of low part. */ + if (type == R_M32R_HI16_SLO + && (addend & 0x8000) != 0) + addend += 0x10000; + + bfd_put_32 (input_bfd, + (insn & 0xffff0000) | ((addend >> 16) & 0xffff), + contents + relhi->r_offset); +} + +/* Do an R_M32R_LO16 relocation. This is a straightforward 16 bit + inplace relocation; this function exists in order to do the + R_M32R_HI16_[SU]LO relocation described above. */ + +static bfd_reloc_status_type +m32r_elf_lo16_reloc (bfd *input_bfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message) +{ + /* This part is from bfd_elf_generic_reloc. + If we're relocating, and this an external symbol, we don't want + to change anything. */ + if (output_bfd != NULL + && (symbol->flags & BSF_SECTION_SYM) == 0 + && reloc_entry->addend == 0) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (m32r_hi16_list != NULL) + { + struct m32r_hi16 *l; + + l = m32r_hi16_list; + while (l != NULL) + { + unsigned long insn; + unsigned long val; + unsigned long vallo; + struct m32r_hi16 *next; + + /* Do the HI16 relocation. Note that we actually don't need + to know anything about the LO16 itself, except where to + find the low 16 bits of the addend needed by the LO16. */ + insn = bfd_get_32 (input_bfd, l->addr); + vallo = ((bfd_get_32 (input_bfd, (bfd_byte *) data + reloc_entry->address) + & 0xffff) ^ 0x8000) - 0x8000; + val = ((insn & 0xffff) << 16) + vallo; + val += l->addend; + + /* Reaccount for sign extension of low part. */ + if ((val & 0x8000) != 0) + val += 0x10000; + + insn = (insn &~ (bfd_vma) 0xffff) | ((val >> 16) & 0xffff); + bfd_put_32 (input_bfd, (bfd_vma) insn, l->addr); + + next = l->next; + free (l); + l = next; + } + + m32r_hi16_list = NULL; + } + + /* Now do the LO16 reloc in the usual way. + ??? It would be nice to call bfd_elf_generic_reloc here, + but we have partial_inplace set. bfd_elf_generic_reloc will + pass the handling back to bfd_install_relocation which will install + a section relative addend which is wrong. */ + return m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); +} + + static reloc_howto_type m32r_elf_howto_table[] = { /* This reloc does nothing. */ @@ -338,7 +647,7 @@ static reloc_howto_type m32r_elf_howto_table[] = 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable hierarchy */ + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_M32R_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -353,7 +662,7 @@ static reloc_howto_type m32r_elf_howto_table[] = 0, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable member usage */ + /* GNU extension to record C++ vtable member usage. */ HOWTO (R_M32R_GNU_VTENTRY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -509,7 +818,7 @@ static reloc_howto_type m32r_elf_howto_table[] = FALSE), /* pcrel_offset */ /* Lower 16 bits of address. */ - HOWTO (R_M32R_LO16_RELA, /* type */ + HOWTO (R_M32R_LO16_RELA, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ @@ -538,7 +847,7 @@ static reloc_howto_type m32r_elf_howto_table[] = 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable hierarchy */ + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_M32R_RELA_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -553,7 +862,7 @@ static reloc_howto_type m32r_elf_howto_table[] = 0, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable member usage */ + /* GNU extension to record C++ vtable member usage. */ HOWTO (R_M32R_RELA_GNU_VTENTRY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -671,7 +980,7 @@ static reloc_howto_type m32r_elf_howto_table[] = 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ - HOWTO (R_M32R_GOTOFF, /* type */ + HOWTO (R_M32R_GOTOFF, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 24, /* bitsize */ @@ -687,7 +996,7 @@ static reloc_howto_type m32r_elf_howto_table[] = /* An PC Relative 24-bit relocation used when setting PIC offset table register. */ - HOWTO (R_M32R_GOTPC24, /* type */ + HOWTO (R_M32R_GOTPC24, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 24, /* bitsize */ @@ -842,410 +1151,7 @@ static reloc_howto_type m32r_elf_howto_table[] = 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ }; - -/* Handle the R_M32R_10_PCREL reloc. */ -static bfd_reloc_status_type -m32r_elf_10_pcrel_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd * abfd; - arelent * reloc_entry; - asymbol * symbol; - PTR data; - asection * input_section; - bfd * output_bfd; - char ** error_message ATTRIBUTE_UNUSED; -{ - /* This part is from bfd_elf_generic_reloc. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != NULL) - { - /* FIXME: See bfd_perform_relocation. Is this right? */ - return bfd_reloc_continue; - } - - return m32r_elf_do_10_pcrel_reloc (abfd, reloc_entry->howto, - input_section, - data, reloc_entry->address, - symbol->section, - (symbol->value - + symbol->section->output_section->vma - + symbol->section->output_offset), - reloc_entry->addend); -} - -/* Utility to actually perform an R_M32R_10_PCREL reloc. */ - -static bfd_reloc_status_type -m32r_elf_do_10_pcrel_reloc (abfd, howto, input_section, data, offset, - symbol_section, symbol_value, addend) - bfd *abfd; - reloc_howto_type *howto; - asection *input_section; - bfd_byte *data; - bfd_vma offset; - asection *symbol_section ATTRIBUTE_UNUSED; - bfd_vma symbol_value; - bfd_vma addend; -{ - bfd_signed_vma relocation; - unsigned long x; - bfd_reloc_status_type status; - - /* Sanity check the address (offset in section). */ - if (offset > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - - relocation = symbol_value + addend; - /* Make it pc relative. */ - relocation -= (input_section->output_section->vma - + input_section->output_offset); - /* These jumps mask off the lower two bits of the current address - before doing pcrel calculations. */ - relocation -= (offset & -(bfd_vma) 4); - - if (relocation < -0x200 || relocation > 0x1ff) - status = bfd_reloc_overflow; - else - status = bfd_reloc_ok; - - x = bfd_get_16 (abfd, data + offset); - relocation >>= howto->rightshift; - relocation <<= howto->bitpos; - x = (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask); - bfd_put_16 (abfd, (bfd_vma) x, data + offset); - - return status; -} - -/* Handle the R_M32R_HI16_[SU]LO relocs. - HI16_SLO is for the add3 and load/store with displacement instructions. - HI16_ULO is for the or3 instruction. - For R_M32R_HI16_SLO, the lower 16 bits are sign extended when added to - the high 16 bytes so if the lower 16 bits are negative (bit 15 == 1) then - we must add one to the high 16 bytes (which will get subtracted off when - the low 16 bits are added). - These relocs have to be done in combination with an R_M32R_LO16 reloc - because there is a carry from the LO16 to the HI16. Here we just save - the information we need; we do the actual relocation when we see the LO16. - This code is copied from the elf32-mips.c. We also support an arbitrary - number of HI16 relocs to be associated with a single LO16 reloc. The - assembler sorts the relocs to ensure each HI16 immediately precedes its - LO16. However if there are multiple copies, the assembler may not find - the real LO16 so it picks the first one it finds. */ - -struct m32r_hi16 -{ - struct m32r_hi16 *next; - bfd_byte *addr; - bfd_vma addend; -}; - -/* FIXME: This should not be a static variable. */ - -static struct m32r_hi16 *m32r_hi16_list; - -static bfd_reloc_status_type -m32r_elf_hi16_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - struct m32r_hi16 *n; - - /* This part is from bfd_elf_generic_reloc. - If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* Sanity check the address (offset in section). */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - - ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - /* Save the information, and let LO16 do the actual relocation. */ - n = (struct m32r_hi16 *) bfd_malloc ((bfd_size_type) sizeof *n); - if (n == NULL) - return bfd_reloc_outofrange; - n->addr = (bfd_byte *) data + reloc_entry->address; - n->addend = relocation; - n->next = m32r_hi16_list; - m32r_hi16_list = n; - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Handle an M32R ELF HI16 reloc. */ - -static void -m32r_elf_relocate_hi16 (input_bfd, type, relhi, rello, contents, addend) - bfd *input_bfd; - int type; - Elf_Internal_Rela *relhi; - Elf_Internal_Rela *rello; - bfd_byte *contents; - bfd_vma addend; -{ - unsigned long insn; - bfd_vma addlo; - - insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); - - addlo = bfd_get_32 (input_bfd, contents + rello->r_offset); - if (type == R_M32R_HI16_SLO) - addlo = ((addlo & 0xffff) ^ 0x8000) - 0x8000; - else - addlo &= 0xffff; - - addend += ((insn & 0xffff) << 16) + addlo; - - /* Reaccount for sign extension of low part. */ - if (type == R_M32R_HI16_SLO - && (addend & 0x8000) != 0) - addend += 0x10000; - - bfd_put_32 (input_bfd, - (insn & 0xffff0000) | ((addend >> 16) & 0xffff), - contents + relhi->r_offset); -} - -/* Do an R_M32R_LO16 relocation. This is a straightforward 16 bit - inplace relocation; this function exists in order to do the - R_M32R_HI16_[SU]LO relocation described above. */ - -bfd_reloc_status_type -m32r_elf_lo16_reloc (input_bfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *input_bfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* This part is from bfd_elf_generic_reloc. - If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (m32r_hi16_list != NULL) - { - struct m32r_hi16 *l; - - l = m32r_hi16_list; - while (l != NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - struct m32r_hi16 *next; - - /* Do the HI16 relocation. Note that we actually don't need - to know anything about the LO16 itself, except where to - find the low 16 bits of the addend needed by the LO16. */ - insn = bfd_get_32 (input_bfd, l->addr); - vallo = ((bfd_get_32 (input_bfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff) ^ 0x8000) - 0x8000; - val = ((insn & 0xffff) << 16) + vallo; - val += l->addend; - - /* Reaccount for sign extension of low part. */ - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ (bfd_vma) 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (input_bfd, (bfd_vma) insn, l->addr); - - next = l->next; - free (l); - l = next; - } - - m32r_hi16_list = NULL; - } - - /* Now do the LO16 reloc in the usual way. - ??? It would be nice to call bfd_elf_generic_reloc here, - but we have partial_inplace set. bfd_elf_generic_reloc will - pass the handling back to bfd_install_relocation which will install - a section relative addend which is wrong. */ - return m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* Do generic partial_inplace relocation. - This is a local replacement for bfd_elf_generic_reloc. */ - -bfd_reloc_status_type -m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *input_bfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - bfd_byte *inplace_address; - - /* This part is from bfd_elf_generic_reloc. - If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* Now do the reloc in the usual way. - ??? It would be nice to call bfd_elf_generic_reloc here, - but we have partial_inplace set. bfd_elf_generic_reloc will - pass the handling back to bfd_install_relocation which will install - a section relative addend which is wrong. */ - - /* Sanity check the address (offset in section). */ - if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section)) - return bfd_reloc_outofrange; - - ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section) - || output_bfd != (bfd *) NULL) - relocation = 0; - else - relocation = symbol->value; - - /* Only do this for a final link. */ - if (output_bfd == (bfd *) NULL) - { - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - } - - relocation += reloc_entry->addend; - inplace_address = (bfd_byte *) data + reloc_entry->address; - -#define DOIT(x) \ - x = ( (x & ~reloc_entry->howto->dst_mask) | \ - (((x & reloc_entry->howto->src_mask) + relocation) & \ - reloc_entry->howto->dst_mask)) - - switch (reloc_entry->howto->size) - { - case 1: - { - short x = bfd_get_16 (input_bfd, inplace_address); - DOIT (x); - bfd_put_16 (input_bfd, (bfd_vma) x, inplace_address); - } - break; - case 2: - { - unsigned long x = bfd_get_32 (input_bfd, inplace_address); - DOIT (x); - bfd_put_32 (input_bfd, (bfd_vma)x , inplace_address); - } - break; - default: - BFD_ASSERT (0); - } - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Handle the R_M32R_SDA16 reloc. - This reloc is used to compute the address of objects in the small data area - and to perform loads and stores from that area. - The lower 16 bits are sign extended and added to the register specified - in the instruction, which is assumed to point to _SDA_BASE_. */ - -static bfd_reloc_status_type -m32r_elf_sda16_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - /* This part is from bfd_elf_generic_reloc. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != NULL) - { - /* FIXME: See bfd_perform_relocation. Is this right? */ - return bfd_reloc_continue; - } - - /* FIXME: not sure what to do here yet. But then again, the linker - may never call us. */ - abort (); -} - /* Map BFD reloc types to M32R ELF reloc types. */ struct m32r_reloc_map @@ -1309,9 +1215,8 @@ static const struct m32r_reloc_map m32r_reloc_map[] = #endif static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -1319,19 +1224,16 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code) for (i = 0; i < sizeof (m32r_reloc_map_old) / sizeof (struct m32r_reloc_map); i++) - { - if (m32r_reloc_map_old[i].bfd_reloc_val == code) - return &m32r_elf_howto_table[m32r_reloc_map_old[i].elf_reloc_val]; - } + if (m32r_reloc_map_old[i].bfd_reloc_val == code) + return &m32r_elf_howto_table[m32r_reloc_map_old[i].elf_reloc_val]; + #else /* ! USE_M32R_OLD_RELOC */ for (i = 0; i < sizeof (m32r_reloc_map) / sizeof (struct m32r_reloc_map); i++) - { - if (m32r_reloc_map[i].bfd_reloc_val == code) - return &m32r_elf_howto_table[m32r_reloc_map[i].elf_reloc_val]; - } + if (m32r_reloc_map[i].bfd_reloc_val == code) + return &m32r_elf_howto_table[m32r_reloc_map[i].elf_reloc_val]; #endif return NULL; @@ -1340,10 +1242,9 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code) /* Set the howto pointer for an M32R ELF reloc. */ static void -m32r_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +m32r_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type; @@ -1353,10 +1254,9 @@ m32r_info_to_howto_rel (abfd, cache_ptr, dst) } static void -m32r_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +m32r_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { BFD_ASSERT ((ELF32_R_TYPE(dst->r_info) == (unsigned int) R_M32R_NONE) || ((ELF32_R_TYPE(dst->r_info) > (unsigned int) R_M32R_GNU_VTENTRY) @@ -1368,11 +1268,10 @@ m32r_info_to_howto (abfd, cache_ptr, dst) /* Given a BFD section, try to locate the corresponding ELF section index. */ -bfd_boolean -_bfd_m32r_elf_section_from_bfd_section (abfd, sec, retval) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - int *retval; +static bfd_boolean +_bfd_m32r_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + int *retval) { if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0) { @@ -1394,14 +1293,10 @@ static asymbol *m32r_elf_scom_symbol_ptr; /* Handle the special M32R section numbers that a symbol may use. */ -void -_bfd_m32r_elf_symbol_processing (abfd, asym) - bfd *abfd ATTRIBUTE_UNUSED; - asymbol *asym; +static void +_bfd_m32r_elf_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym) { - elf_symbol_type *elfsym; - - elfsym = (elf_symbol_type *) asym; + elf_symbol_type *elfsym = (elf_symbol_type *) asym; switch (elfsym->internal_elf_sym.st_shndx) { @@ -1431,14 +1326,13 @@ _bfd_m32r_elf_symbol_processing (abfd, asym) linker sections. */ static bfd_boolean -m32r_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp ATTRIBUTE_UNUSED; - asection **secp; - bfd_vma *valp; +m32r_elf_add_symbol_hook (bfd *abfd, + struct bfd_link_info *info, + Elf_Internal_Sym *sym, + const char **namep, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp, + bfd_vma *valp) { if (! info->relocatable && (*namep)[0] == '_' && (*namep)[1] == 'S' @@ -1455,7 +1349,6 @@ m32r_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) asection *s = bfd_get_section_by_name (abfd, ".sdata"); /* The following code was cobbled from elf32-ppc.c and elflink.c. */ - if (s == NULL) { flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS @@ -1478,7 +1371,7 @@ m32r_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) BSF_GLOBAL, s, (bfd_vma) 32768, - (const char *) NULL, + NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh))) @@ -1506,19 +1399,17 @@ m32r_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) external symbol if we are producing relocatable output. */ static bfd_reloc_status_type -m32r_elf_final_sda_base (output_bfd, info, error_message, psb) - bfd *output_bfd; - struct bfd_link_info *info; - const char **error_message; - bfd_vma *psb; +m32r_elf_final_sda_base (bfd *output_bfd, + struct bfd_link_info *info, + const char **error_message, + bfd_vma *psb) { if (elf_gp (output_bfd) == 0) { struct bfd_link_hash_entry *h; h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", FALSE, FALSE, TRUE); - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_defined) + if (h != NULL && h->type == bfd_link_hash_defined) elf_gp (output_bfd) = (h->u.def.value + h->u.def.section->output_section->vma + h->u.def.section->output_offset); @@ -1586,11 +1477,6 @@ struct elf_m32r_link_hash_entry /* Track dynamic relocs copied for this symbol. */ struct elf_m32r_dyn_relocs *dyn_relocs; - -// bfd_signed_vma gotplt_refcount; - - /* Number of PC relative relocs copied for this symbol. */ - /* struct elf_m32r_pcrel_relocs_copied *pcrel_relocs_copied; FIXME */ }; /* m32r ELF linker hash table. */ @@ -1617,7 +1503,7 @@ struct elf_m32r_link_hash_table #define m32r_elf_link_hash_traverse(table, func, info) \ (elf_link_hash_traverse \ (&(table)->root, \ - (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ + (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \ (info))) /* Get the m32r ELF linker hash table from a link_info structure. */ @@ -1627,57 +1513,48 @@ struct elf_m32r_link_hash_table ((struct elf_m32r_link_hash_table *) ((p)->hash)) /* Create an entry in an m32r ELF linker hash table. */ -static struct bfd_hash_entry * -m32r_elf_link_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *, - const char * ); static struct bfd_hash_entry * -m32r_elf_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; +m32r_elf_link_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) { struct elf_m32r_link_hash_entry *ret = (struct elf_m32r_link_hash_entry *) entry; /* Allocate the structure if it has not already been allocated by a subclass. */ - if (ret == (struct elf_m32r_link_hash_entry *) NULL) - ret = ((struct elf_m32r_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf_m32r_link_hash_entry))); - if (ret == (struct elf_m32r_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; + if (ret == NULL) + ret = bfd_hash_allocate (table, + sizeof (struct elf_m32r_link_hash_entry)); + if (ret == NULL) + return NULL; /* Call the allocation method of the superclass. */ ret = ((struct elf_m32r_link_hash_entry *) _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret != (struct elf_m32r_link_hash_entry *) NULL) + if (ret != NULL) { struct elf_m32r_link_hash_entry *eh; eh = (struct elf_m32r_link_hash_entry *) ret; eh->dyn_relocs = NULL; -// eh->gotplt_refcount = 0; - /* eh->pcrel_relocs_copied = NULL; FIXME */ } return (struct bfd_hash_entry *) ret; } /* Create an m32r ELF linker hash table. */ -static struct bfd_link_hash_table *m32r_elf_link_hash_table_create (bfd *); static struct bfd_link_hash_table * -m32r_elf_link_hash_table_create (abfd) - bfd *abfd; +m32r_elf_link_hash_table_create (bfd *abfd) { struct elf_m32r_link_hash_table *ret; bfd_size_type amt = sizeof (struct elf_m32r_link_hash_table); - ret = (struct elf_m32r_link_hash_table *) bfd_malloc (amt); - if (ret == (struct elf_m32r_link_hash_table *) NULL) + ret = bfd_malloc (amt); + if (ret == NULL) return NULL; if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, @@ -1701,12 +1578,9 @@ m32r_elf_link_hash_table_create (abfd) /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up shortcuts to them in our hash table. */ -static bfd_boolean create_got_section (bfd *, struct bfd_link_info *); static bfd_boolean -create_got_section (dynobj, info) - bfd *dynobj; - struct bfd_link_info *info; +create_got_section (bfd *dynobj, struct bfd_link_info *info) { struct elf_m32r_link_hash_table *htab; @@ -1736,13 +1610,11 @@ create_got_section (dynobj, info) /* Create dynamic sections when linking against a dynamic object. */ static bfd_boolean -m32r_elf_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; +m32r_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) { struct elf_m32r_link_hash_table *htab; flagword flags, pltflags; - register asection *s; + asection *s; const struct elf_backend_data *bed = get_elf_backend_data (abfd); int ptralign = 2; /* 32bit */ @@ -1750,7 +1622,6 @@ m32r_elf_create_dynamic_sections (abfd, info) /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and .rel[a].bss sections. */ - flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED); @@ -1773,9 +1644,10 @@ m32r_elf_create_dynamic_sections (abfd, info) .plt section. */ struct bfd_link_hash_entry *bh = NULL; struct elf_link_hash_entry *h; + if (! (_bfd_generic_link_add_one_symbol (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, FALSE, + (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh))) return FALSE; h = (struct elf_link_hash_entry *) bh; @@ -1812,7 +1684,7 @@ m32r_elf_create_dynamic_sections (abfd, info) || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS)) continue; secname = bfd_get_section_name (abfd, sec); - relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6); + relname = bfd_malloc ((bfd_size_type) strlen (secname) + 6); strcpy (relname, ".rela"); strcat (relname, secname); if (bfd_get_section_by_name (abfd, secname)) @@ -1866,16 +1738,14 @@ m32r_elf_create_dynamic_sections (abfd, info) } /* Copy the extra info we tack onto an elf_link_hash_entry. */ -static void m32r_elf_copy_indirect_symbol (const struct elf_backend_data *, - struct elf_link_hash_entry *, - struct elf_link_hash_entry *); static void m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed, struct elf_link_hash_entry *dir, struct elf_link_hash_entry *ind) { - struct elf_m32r_link_hash_entry *edir, *eind; + struct elf_m32r_link_hash_entry * edir; + struct elf_m32r_link_hash_entry * eind; edir = (struct elf_m32r_link_hash_entry *) dir; eind = (struct elf_m32r_link_hash_entry *) ind; @@ -1892,7 +1762,7 @@ m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed, /* Add reloc counts against the weak sym to the strong sym list. Merge any entries against the same section. */ - for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) + for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) { struct elf_m32r_dyn_relocs *q; @@ -1914,12 +1784,6 @@ m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed, eind->dyn_relocs = NULL; } -// if (ind->root.type == bfd_link_hash_indirect -// && dir->got.refcount <= 0) -// { -// edir->tls_type = eind->tls_type; -// eind->tls_type = GOT_UNKNOWN; -// } _bfd_elf_link_hash_copy_indirect (bed, dir, ind); } @@ -1931,9 +1795,8 @@ m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed, understand. */ static bfd_boolean -m32r_elf_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; +m32r_elf_adjust_dynamic_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) { struct elf_m32r_link_hash_table *htab; struct elf_m32r_link_hash_entry *eh; @@ -1943,7 +1806,7 @@ m32r_elf_adjust_dynamic_symbol (info, h) unsigned int power_of_two; #ifdef DEBUG_PIC -printf("m32r_elf_adjust_dynamic_symbol()\n"); + printf ("m32r_elf_adjust_dynamic_symbol()\n"); #endif dynobj = elf_hash_table (info)->dynobj; @@ -1956,7 +1819,6 @@ printf("m32r_elf_adjust_dynamic_symbol()\n"); && h->ref_regular && !h->def_regular))); - /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ @@ -2090,9 +1952,7 @@ printf("m32r_elf_adjust_dynamic_symbol()\n"); dynamic relocs. */ static bfd_boolean -allocate_dynrelocs (h, inf) - struct elf_link_hash_entry *h; - PTR inf; +allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) { struct bfd_link_info *info; struct elf_m32r_link_hash_table *htab; @@ -2112,16 +1972,6 @@ allocate_dynrelocs (h, inf) htab = m32r_elf_hash_table (info); eh = (struct elf_m32r_link_hash_entry *) h; -// if ((h->got.refcount > 0 -// || h->forced_local) -// && eh->gotplt_refcount > 0) -// { -// /* The symbol has been forced local, or we have some direct got refs, -// so treat all the gotplt refs as got refs. */ -// h->got.refcount += eh->gotplt_refcount; -// if (h->plt.refcount >= eh->gotplt_refcount) -// h->plt.refcount -= eh->gotplt_refcount; -// } if (htab->root.dynamic_sections_created && h->plt.refcount > 0) @@ -2221,7 +2071,8 @@ allocate_dynrelocs (h, inf) || info->symbolic)) { struct elf_m32r_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) { p->count -= p->pc_count; p->pc_count = 0; @@ -2274,12 +2125,11 @@ allocate_dynrelocs (h, inf) return TRUE; } + /* Find any dynamic relocs that apply to read-only sections. */ static bfd_boolean -readonly_dynrelocs (h, inf) - struct elf_link_hash_entry *h; - PTR inf; +readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) { struct elf_m32r_link_hash_entry *eh; struct elf_m32r_dyn_relocs *p; @@ -2308,9 +2158,8 @@ readonly_dynrelocs (h, inf) /* Set the sizes of the dynamic sections. */ static bfd_boolean -m32r_elf_size_dynamic_sections (output_bfd, info) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +m32r_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { struct elf_m32r_link_hash_table *htab; bfd *dynobj; @@ -2319,7 +2168,7 @@ m32r_elf_size_dynamic_sections (output_bfd, info) bfd *ibfd; #ifdef DEBUG_PIC -printf("m32r_elf_size_dynamic_sections()\n"); + printf ("m32r_elf_size_dynamic_sections()\n"); #endif htab = m32r_elf_hash_table (info); @@ -2403,7 +2252,7 @@ printf("m32r_elf_size_dynamic_sections()\n"); /* Allocate global sym .plt and .got entries, and space for global sym dynamic relocs. */ - elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info); + elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info); /* We now have determined the sizes of the various dynamic sections. Allocate memory for them. */ @@ -2430,10 +2279,8 @@ printf("m32r_elf_size_dynamic_sections()\n"); s->reloc_count = 0; } else - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } + /* It's not one of our sections, so don't allocate space. */ + continue; if (s->size == 0) { @@ -2455,7 +2302,7 @@ printf("m32r_elf_size_dynamic_sections()\n"); section's contents are written out. This should not happen, but this way if it does, we get a R_M32R_NONE reloc instead of garbage. */ - s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); + s->contents = bfd_zalloc (dynobj, s->size); if (s->contents == NULL) return FALSE; } @@ -2497,7 +2344,7 @@ printf("m32r_elf_size_dynamic_sections()\n"); then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) elf_link_hash_traverse (&htab->root, readonly_dynrelocs, - (PTR) info); + info); if ((info->flags & DF_TEXTREL) != 0) { @@ -2510,6 +2357,7 @@ printf("m32r_elf_size_dynamic_sections()\n"); return TRUE; } + /* Relocate an M32R/D ELF section. There is some attempt to make this function usable for many architectures, both for RELA and REL type relocs, if only to serve as a learning tool. @@ -2544,16 +2392,14 @@ printf("m32r_elf_size_dynamic_sections()\n"); accordingly. */ static bfd_boolean -m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); @@ -2607,7 +2453,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, continue; } - if (r_type == R_M32R_GNU_VTENTRY + if ( r_type == R_M32R_GNU_VTENTRY || r_type == R_M32R_GNU_VTINHERIT || r_type == R_M32R_NONE || r_type == R_M32R_RELA_GNU_VTENTRY @@ -2628,20 +2474,16 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, section symbol winds up in the output section. */ sec = NULL; if (r_symndx >= symtab_hdr->sh_info) - { - /* External symbol. */ - continue; - } + /* External symbol. */ + continue; /* Local symbol. */ sym = local_syms + r_symndx; sym_name = "<local symbol>"; /* STT_SECTION: symbol is associated with a section. */ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) - { - /* Symbol isn't associated with a section. Nothing to do. */ - continue; - } + /* Symbol isn't associated with a section. Nothing to do. */ + continue; sec = local_sections[r_symndx]; addend += sec->output_offset + sym->st_value; @@ -2960,7 +2802,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, outrel.r_info = ELF32_R_INFO (0, R_M32R_RELATIVE); outrel.r_addend = relocation; loc = srelgot->contents; - loc += srelgot->reloc_count * sizeof(Elf32_External_Rela); + loc += srelgot->reloc_count * sizeof (Elf32_External_Rela); bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc); ++srelgot->reloc_count; } @@ -2986,19 +2828,14 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (h == NULL) break; - //if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL - // || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) - // break; if (h->forced_local) break; if (h->plt.offset == (bfd_vma) -1) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } + /* We didn't make a PLT entry for this symbol. This + happens when statically linking PIC code, or when + using -Bsymbolic. */ + break; relocation = (splt->output_section->vma + splt->output_offset @@ -3006,13 +2843,10 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, break; case R_M32R_HI16_SLO_RELA: - { - if ((relocation + rel->r_addend) & 0x8000) - { - rel->r_addend += 0x10000; - } - } + if ((relocation + rel->r_addend) & 0x8000) + rel->r_addend += 0x10000; /* Fall through. */ + case R_M32R_16_RELA: case R_M32R_24_RELA: case R_M32R_32_RELA: @@ -3037,7 +2871,6 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* When generating a shared object, these relocations are copied into the output file to be resolved at run time. */ - if (sreloc == NULL) { const char *name; @@ -3068,7 +2901,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (outrel.r_offset == (bfd_vma) -1) skip = TRUE; else if (outrel.r_offset == (bfd_vma) -2) - skip = TRUE, relocate = TRUE; + skip = relocate = TRUE; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); @@ -3102,7 +2935,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, } loc = sreloc->contents; - loc += sreloc->reloc_count * sizeof(Elf32_External_Rela); + loc += sreloc->reloc_count * sizeof (Elf32_External_Rela); bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc); ++sreloc->reloc_count; @@ -3158,7 +2991,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sec != NULL); name = bfd_get_section_name (abfd, sec); - if (strcmp (name, ".sdata") == 0 + if ( strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0 || strcmp (name, ".scommon") == 0) { @@ -3192,7 +3025,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, continue; } } - /* fall through */ + /* Fall through. */ default : /* OLD_M32R_RELOC */ @@ -3275,19 +3108,19 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* Finish up dynamic symbol handling. We set the contents of various dynamic sections here. */ + static bfd_boolean -m32r_elf_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +m32r_elf_finish_dynamic_symbol (bfd *output_bfd, + struct bfd_link_info *info, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { struct elf_m32r_link_hash_table *htab; bfd *dynobj; bfd_byte *loc; #ifdef DEBUG_PIC -printf("m32r_elf_finish_dynamic_symbol()\n"); + printf ("m32r_elf_finish_dynamic_symbol()\n"); #endif htab = m32r_elf_hash_table (info); @@ -3384,7 +3217,7 @@ printf("m32r_elf_finish_dynamic_symbol()\n"); rela.r_info = ELF32_R_INFO (h->dynindx, R_M32R_JMP_SLOT); rela.r_addend = 0; loc = srela->contents; - loc += plt_index * sizeof(Elf32_External_Rela); + loc += plt_index * sizeof (Elf32_External_Rela); bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); if (!h->def_regular) @@ -3430,14 +3263,14 @@ printf("m32r_elf_finish_dynamic_symbol()\n"); } else { - BFD_ASSERT((h->got.offset & 1) == 0); + BFD_ASSERT ((h->got.offset & 1) == 0); bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset); rela.r_info = ELF32_R_INFO (h->dynindx, R_M32R_GLOB_DAT); rela.r_addend = 0; } loc = srela->contents; - loc += srela->reloc_count * sizeof(Elf32_External_Rela); + loc += srela->reloc_count * sizeof (Elf32_External_Rela); bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); ++srela->reloc_count; } @@ -3463,7 +3296,7 @@ printf("m32r_elf_finish_dynamic_symbol()\n"); rela.r_info = ELF32_R_INFO (h->dynindx, R_M32R_COPY); rela.r_addend = 0; loc = s->contents; - loc += s->reloc_count * sizeof(Elf32_External_Rela); + loc += s->reloc_count * sizeof (Elf32_External_Rela); bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); ++s->reloc_count; } @@ -3480,9 +3313,8 @@ printf("m32r_elf_finish_dynamic_symbol()\n"); /* Finish up the dynamic sections. */ static bfd_boolean -m32r_elf_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +m32r_elf_finish_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) { struct elf_m32r_link_hash_table *htab; bfd *dynobj; @@ -3490,7 +3322,7 @@ m32r_elf_finish_dynamic_sections (output_bfd, info) asection *sgot; #ifdef DEBUG_PIC -printf("m32r_elf_finish_dynamic_sections()\n"); + printf ("m32r_elf_finish_dynamic_sections()\n"); #endif htab = m32r_elf_hash_table (info); @@ -3615,9 +3447,9 @@ printf("m32r_elf_finish_dynamic_sections()\n"); /* Set the right machine number. */ + static bfd_boolean -m32r_elf_object_p (abfd) - bfd *abfd; +m32r_elf_object_p (bfd *abfd) { switch (elf_elfheader (abfd)->e_flags & EF_M32R_ARCH) { @@ -3630,10 +3462,10 @@ m32r_elf_object_p (abfd) } /* Store the machine number in the flags field. */ + static void -m32r_elf_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +m32r_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { unsigned long val; @@ -3650,10 +3482,9 @@ m32r_elf_final_write_processing (abfd, linker) } /* Function to keep M32R specific file flags. */ + static bfd_boolean -m32r_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; +m32r_elf_set_private_flags (bfd *abfd, flagword flags) { BFD_ASSERT (!elf_flags_init (abfd) || elf_elfheader (abfd)->e_flags == flags); @@ -3665,10 +3496,9 @@ m32r_elf_set_private_flags (abfd, flags) /* Merge backend specific data from an object file to the output object file when linking. */ + static bfd_boolean -m32r_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +m32r_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { flagword out_flags; flagword in_flags; @@ -3696,9 +3526,8 @@ m32r_elf_merge_private_bfd_data (ibfd, obfd) if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) && bfd_get_arch_info (obfd)->the_default) - { - return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); - } + return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), + bfd_get_mach (ibfd)); return TRUE; } @@ -3724,11 +3553,10 @@ m32r_elf_merge_private_bfd_data (ibfd, obfd) return TRUE; } -/* Display the flags field */ +/* Display the flags field. */ + static bfd_boolean -m32r_elf_print_private_bfd_data (abfd, ptr) - bfd *abfd; - PTR ptr; +m32r_elf_print_private_bfd_data (bfd *abfd, void * ptr) { FILE * file = (FILE *) ptr; @@ -3751,13 +3579,12 @@ m32r_elf_print_private_bfd_data (abfd, ptr) return TRUE; } -asection * -m32r_elf_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +static asection * +m32r_elf_gc_mark_hook (asection *sec, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { if (h != NULL) { @@ -3791,11 +3618,10 @@ m32r_elf_gc_mark_hook (sec, info, rel, h, sym) } static bfd_boolean -m32r_elf_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - asection *sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; +m32r_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) { /* Update the got entry reference counts for the section being removed. */ Elf_Internal_Shdr *symtab_hdr; @@ -3905,11 +3731,10 @@ m32r_elf_gc_sweep_hook (abfd, info, sec, relocs) virtual table relocs for gc. */ static bfd_boolean -m32r_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +m32r_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; @@ -4004,8 +3829,7 @@ m32r_elf_check_relocs (abfd, info, sec, relocs) size = symtab_hdr->sh_info; size *= sizeof (bfd_signed_vma); - local_got_refcounts = ((bfd_signed_vma *) - bfd_zalloc (abfd, size)); + local_got_refcounts = bfd_zalloc (abfd, size); if (local_got_refcounts == NULL) return FALSE; elf_local_got_refcounts (abfd) = local_got_refcounts; @@ -4147,7 +3971,8 @@ m32r_elf_check_relocs (abfd, info, sec, relocs) if (p == NULL || p->sec != sec) { bfd_size_type amt = sizeof (*p); - p = ((struct elf_m32r_dyn_relocs *) bfd_alloc (dynobj, amt)); + + p = bfd_alloc (dynobj, amt); if (p == NULL) return FALSE; p->next = *head; @@ -4229,12 +4054,11 @@ static struct bfd_elf_special_section const * }; static bfd_boolean -m32r_elf_fake_sections (abfd, hdr, sec) - bfd *abfd; - Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED; - asection *sec; +m32r_elf_fake_sections (bfd *abfd, + Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED, + asection *sec) { - register const char *name; + const char *name; name = bfd_get_section_name (abfd, sec); @@ -4256,7 +4080,7 @@ m32r_elf_fake_sections (abfd, hdr, sec) esd = elf_section_data (sec); BFD_ASSERT (esd->rel_hdr2 == NULL); - esd->rel_hdr2 = (Elf_Internal_Shdr *) bfd_zalloc (abfd, amt); + esd->rel_hdr2 = bfd_zalloc (abfd, amt); if (!esd->rel_hdr2) return FALSE; _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec, @@ -4267,19 +4091,14 @@ m32r_elf_fake_sections (abfd, hdr, sec) } static enum elf_reloc_type_class -m32r_elf_reloc_type_class (rela) - const Elf_Internal_Rela *rela; +m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela) { switch ((int) ELF32_R_TYPE (rela->r_info)) { - case R_M32R_RELATIVE: - return reloc_class_relative; - case R_M32R_JMP_SLOT: - return reloc_class_plt; - case R_M32R_COPY: - return reloc_class_copy; - default: - return reloc_class_normal; + case R_M32R_RELATIVE: return reloc_class_relative; + case R_M32R_JMP_SLOT: return reloc_class_plt; + case R_M32R_COPY: return reloc_class_copy; + default: return reloc_class_normal; } } @@ -4341,18 +4160,18 @@ m32r_elf_reloc_type_class (rela) #include "elf32-target.h" -#undef ELF_MAXPAGESIZE +#undef ELF_MAXPAGESIZE #define ELF_MAXPAGESIZE 0x1000 -#undef TARGET_BIG_SYM +#undef TARGET_BIG_SYM #define TARGET_BIG_SYM bfd_elf32_m32rlin_vec -#undef TARGET_BIG_NAME +#undef TARGET_BIG_NAME #define TARGET_BIG_NAME "elf32-m32r-linux" -#undef TARGET_LITTLE_SYM +#undef TARGET_LITTLE_SYM #define TARGET_LITTLE_SYM bfd_elf32_m32rlelin_vec -#undef TARGET_LITTLE_NAME +#undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-m32rle-linux" -#undef elf32_bed +#undef elf32_bed #define elf32_bed elf32_m32r_lin_bed #include "elf32-target.h" diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c index 29a4e8ac068..b554ec06cec 100644 --- a/bfd/elf32-mcore.c +++ b/bfd/elf32-mcore.c @@ -1,22 +1,23 @@ /* Motorola MCore specific support for 32-bit ELF - Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, + USA. */ /* This file is based on a preliminary RCE ELF ABI. The information may not match the final RCE ELF ABI. */ @@ -31,30 +32,76 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. /* RELA relocs are used here... */ -static void mcore_elf_howto_init - PARAMS ((void)); -static reloc_howto_type * mcore_elf_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void mcore_elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_boolean mcore_elf_set_private_flags - PARAMS ((bfd *, flagword)); -static bfd_boolean mcore_elf_merge_private_bfd_data - PARAMS ((bfd *, bfd *)); -static bfd_reloc_status_type mcore_elf_unsupported_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_boolean mcore_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static asection * mcore_elf_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static bfd_boolean mcore_elf_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean mcore_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); +/* Function to set whether a module needs the -mrelocatable bit set. */ + +static bfd_boolean +mcore_elf_set_private_flags (bfd * abfd, flagword flags) +{ + BFD_ASSERT (! elf_flags_init (abfd) + || elf_elfheader (abfd)->e_flags == flags); + + elf_elfheader (abfd)->e_flags = flags; + elf_flags_init (abfd) = TRUE; + return TRUE; +} + +/* Merge backend specific data from an object file to the output + object file when linking. */ + +static bfd_boolean +mcore_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) +{ + flagword old_flags; + flagword new_flags; + + /* Check if we have the same endianess. */ + if (! _bfd_generic_verify_endian_match (ibfd, obfd)) + return FALSE; + + if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour + || bfd_get_flavour (obfd) != bfd_target_elf_flavour) + return TRUE; + + new_flags = elf_elfheader (ibfd)->e_flags; + old_flags = elf_elfheader (obfd)->e_flags; + + if (! elf_flags_init (obfd)) + { + /* First call, no flags set. */ + elf_flags_init (obfd) = TRUE; + elf_elfheader (obfd)->e_flags = new_flags; + } + else if (new_flags == old_flags) + /* Compatible flags are OK. */ + ; + else + { + /* FIXME */ + } + + return TRUE; +} + +/* Don't pretend we can deal with unsupported relocs. */ + +static bfd_reloc_status_type +mcore_elf_unsupported_reloc (bfd * abfd, + arelent * reloc_entry, + asymbol * symbol ATTRIBUTE_UNUSED, + PTR data ATTRIBUTE_UNUSED, + asection * input_section ATTRIBUTE_UNUSED, + bfd * output_bfd ATTRIBUTE_UNUSED, + char ** error_message ATTRIBUTE_UNUSED) +{ + BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0); + + _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"), + abfd, + reloc_entry->howto->name, + reloc_entry->howto->type); + + return bfd_reloc_notsupported; +} static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max]; @@ -174,7 +221,7 @@ static reloc_howto_type mcore_elf_howto_raw[] = 0x7ff, /* dst_mask */ TRUE), /* pcrel_offset */ - /* GNU extension to record C++ vtable hierarchy */ + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_MCORE_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -189,7 +236,7 @@ static reloc_howto_type mcore_elf_howto_raw[] = 0, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable member usage */ + /* GNU extension to record C++ vtable member usage. */ HOWTO (R_MCORE_GNU_VTENTRY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -225,7 +272,7 @@ static reloc_howto_type mcore_elf_howto_raw[] = /* Initialize the mcore_elf_howto_table, so that linear accesses can be done. */ static void -mcore_elf_howto_init () +mcore_elf_howto_init (void) { unsigned int i; @@ -242,9 +289,8 @@ mcore_elf_howto_init () } static reloc_howto_type * -mcore_elf_reloc_type_lookup (abfd, code) - bfd * abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +mcore_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE; @@ -261,102 +307,31 @@ mcore_elf_reloc_type_lookup (abfd, code) case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break; case BFD_RELOC_RVA: mcore_reloc = R_MCORE_RELATIVE; break; default: - return (reloc_howto_type *)NULL; + return NULL; } - if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */ + if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) + /* Initialize howto table if needed. */ mcore_elf_howto_init (); return mcore_elf_howto_table [(int) mcore_reloc]; }; /* Set the howto pointer for a RCE ELF reloc. */ + static void -mcore_elf_info_to_howto (abfd, cache_ptr, dst) - bfd * abfd ATTRIBUTE_UNUSED; - arelent * cache_ptr; - Elf_Internal_Rela * dst; +mcore_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr, + Elf_Internal_Rela * dst) { - if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */ + if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) + /* Initialize howto table if needed. */ mcore_elf_howto_init (); BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max); cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)]; } - -/* Function to set whether a module needs the -mrelocatable bit set. */ -static bfd_boolean -mcore_elf_set_private_flags (abfd, flags) - bfd * abfd; - flagword flags; -{ - BFD_ASSERT (! elf_flags_init (abfd) - || elf_elfheader (abfd)->e_flags == flags); - - elf_elfheader (abfd)->e_flags = flags; - elf_flags_init (abfd) = TRUE; - return TRUE; -} - -/* Merge backend specific data from an object file to the output - object file when linking. */ -static bfd_boolean -mcore_elf_merge_private_bfd_data (ibfd, obfd) - bfd * ibfd; - bfd * obfd; -{ - flagword old_flags; - flagword new_flags; - - /* Check if we have the same endianess */ - if (! _bfd_generic_verify_endian_match (ibfd, obfd)) - return FALSE; - - if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour - || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return TRUE; - - new_flags = elf_elfheader (ibfd)->e_flags; - old_flags = elf_elfheader (obfd)->e_flags; - - if (! elf_flags_init (obfd)) /* First call, no flags set */ - { - elf_flags_init (obfd) = TRUE; - elf_elfheader (obfd)->e_flags = new_flags; - } - else if (new_flags == old_flags) /* Compatible flags are ok */ - ; - else - { - /* FIXME */ - } - - return TRUE; -} - -/* Don't pretend we can deal with unsupported relocs. */ - -static bfd_reloc_status_type -mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd * abfd; - arelent * reloc_entry; - asymbol * symbol ATTRIBUTE_UNUSED; - PTR data ATTRIBUTE_UNUSED; - asection * input_section ATTRIBUTE_UNUSED; - bfd * output_bfd ATTRIBUTE_UNUSED; - char ** error_message ATTRIBUTE_UNUSED; -{ - BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0); - - _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"), - abfd, - reloc_entry->howto->name, - reloc_entry->howto->type); - - return bfd_reloc_notsupported; -} /* The RELOCATE_SECTION function is called by the ELF backend linker to handle the relocations for a section. @@ -388,16 +363,14 @@ mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section, accordingly. */ static bfd_boolean -mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd * output_bfd; - struct bfd_link_info * info; - bfd * input_bfd; - asection * input_section; - bfd_byte * contents; - Elf_Internal_Rela * relocs; - Elf_Internal_Sym * local_syms; - asection ** local_sections; +mcore_elf_relocate_section (bfd * output_bfd, + struct bfd_link_info * info, + bfd * input_bfd, + asection * input_section, + bfd_byte * contents, + Elf_Internal_Rela * relocs, + Elf_Internal_Sym * local_syms, + asection ** local_sections) { Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd); @@ -426,15 +399,15 @@ mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, bfd_vma offset = rel->r_offset; bfd_vma addend = rel->r_addend; bfd_reloc_status_type r = bfd_reloc_other; - asection * sec = (asection *) 0; + asection * sec = NULL; reloc_howto_type * howto; bfd_vma relocation; - Elf_Internal_Sym * sym = (Elf_Internal_Sym *) 0; + Elf_Internal_Sym * sym = NULL; unsigned long r_symndx; - struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0; + struct elf_link_hash_entry * h = NULL; unsigned short oldinst = 0; - /* Unknown relocation handling */ + /* Unknown relocation handling. */ if ((unsigned) r_type >= (unsigned) R_MCORE_max || ! mcore_elf_howto_table [(int)r_type]) { @@ -553,38 +526,35 @@ mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation. */ static asection * -mcore_elf_gc_mark_hook (sec, info, rel, h, sym) - asection * sec; - struct bfd_link_info * info ATTRIBUTE_UNUSED; - Elf_Internal_Rela * rel; - struct elf_link_hash_entry * h; - Elf_Internal_Sym * sym; +mcore_elf_gc_mark_hook (asection * sec, + struct bfd_link_info * info ATTRIBUTE_UNUSED, + Elf_Internal_Rela * rel, + struct elf_link_hash_entry * h, + Elf_Internal_Sym * sym) { - if (h != NULL) + if (h == NULL) + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); + + switch (ELF32_R_TYPE (rel->r_info)) { - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_MCORE_GNU_VTINHERIT: - case R_MCORE_GNU_VTENTRY: - break; + case R_MCORE_GNU_VTINHERIT: + case R_MCORE_GNU_VTENTRY: + break; - default: - switch (h->root.type) - { - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - return h->root.u.def.section; + default: + switch (h->root.type) + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + return h->root.u.def.section; - case bfd_link_hash_common: - return h->root.u.c.p->section; + case bfd_link_hash_common: + return h->root.u.c.p->section; - default: - break; - } + default: + break; } } - else - return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } @@ -592,11 +562,10 @@ mcore_elf_gc_mark_hook (sec, info, rel, h, sym) /* Update the got entry reference counts for the section being removed. */ static bfd_boolean -mcore_elf_gc_sweep_hook (abfd, info, sec, relocs) - bfd * abfd ATTRIBUTE_UNUSED; - struct bfd_link_info * info ATTRIBUTE_UNUSED; - asection * sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED; +mcore_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, + struct bfd_link_info * info ATTRIBUTE_UNUSED, + asection * sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED) { return TRUE; } @@ -606,11 +575,10 @@ mcore_elf_gc_sweep_hook (abfd, info, sec, relocs) virtual table relocs for gc. */ static bfd_boolean -mcore_elf_check_relocs (abfd, info, sec, relocs) - bfd * abfd; - struct bfd_link_info * info; - asection * sec; - const Elf_Internal_Rela * relocs; +mcore_elf_check_relocs (bfd * abfd, + struct bfd_link_info * info, + asection * sec, + const Elf_Internal_Rela * relocs) { Elf_Internal_Shdr * symtab_hdr; struct elf_link_hash_entry ** sym_hashes; diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c index 6220df3c073..b3d67bb82cf 100644 --- a/bfd/elf32-openrisc.c +++ b/bfd/elf32-openrisc.c @@ -1,22 +1,23 @@ /* OpenRISC-specific support for 32-bit ELF. - Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Johan Rydberg, jrydberg@opencores.org -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, + USA. */ #include "bfd.h" #include "sysdep.h" @@ -25,35 +26,8 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "elf/openrisc.h" #include "libiberty.h" -/* Forward declarations. */ - -static reloc_howto_type *openrisc_reloc_type_lookup - PARAMS ((bfd * , bfd_reloc_code_real_type)); -static void openrisc_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_boolean openrisc_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_reloc_status_type openrisc_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, bfd_vma)); -static bfd_boolean openrisc_elf_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static asection * openrisc_elf_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static bfd_boolean openrisc_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean openrisc_elf_object_p - PARAMS ((bfd *)); -static void openrisc_elf_final_write_processing - PARAMS ((bfd *, bfd_boolean)); - - static reloc_howto_type openrisc_elf_howto_table[] = - { +{ /* This reloc does nothing. */ HOWTO (R_OPENRISC_NONE, /* type */ 0, /* rightshift */ @@ -172,7 +146,7 @@ static reloc_howto_type openrisc_elf_howto_table[] = 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable hierarchy */ + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_OPENRISC_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -187,7 +161,7 @@ static reloc_howto_type openrisc_elf_howto_table[] = 0, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable member usage */ + /* GNU extension to record C++ vtable member usage. */ HOWTO (R_OPENRISC_GNU_VTENTRY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -206,29 +180,28 @@ static reloc_howto_type openrisc_elf_howto_table[] = /* Map BFD reloc types to OpenRISC ELF reloc types. */ struct openrisc_reloc_map - { - bfd_reloc_code_real_type bfd_reloc_val; - unsigned int openrisc_reloc_val; - }; +{ + bfd_reloc_code_real_type bfd_reloc_val; + unsigned int openrisc_reloc_val; +}; static const struct openrisc_reloc_map openrisc_reloc_map[] = - { - { BFD_RELOC_NONE, R_OPENRISC_NONE }, - { BFD_RELOC_32, R_OPENRISC_32 }, - { BFD_RELOC_16, R_OPENRISC_16 }, - { BFD_RELOC_8, R_OPENRISC_8 }, - { BFD_RELOC_OPENRISC_REL_26,R_OPENRISC_INSN_REL_26 }, - { BFD_RELOC_OPENRISC_ABS_26,R_OPENRISC_INSN_ABS_26 }, +{ + { BFD_RELOC_NONE, R_OPENRISC_NONE }, + { BFD_RELOC_32, R_OPENRISC_32 }, + { BFD_RELOC_16, R_OPENRISC_16 }, + { BFD_RELOC_8, R_OPENRISC_8 }, + { BFD_RELOC_OPENRISC_REL_26,R_OPENRISC_INSN_REL_26 }, + { BFD_RELOC_OPENRISC_ABS_26,R_OPENRISC_INSN_ABS_26 }, { BFD_RELOC_HI16, R_OPENRISC_HI_16_IN_INSN }, - { BFD_RELOC_LO16, R_OPENRISC_LO_16_IN_INSN }, - { BFD_RELOC_VTABLE_INHERIT, R_OPENRISC_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_OPENRISC_GNU_VTENTRY } - }; + { BFD_RELOC_LO16, R_OPENRISC_LO_16_IN_INSN }, + { BFD_RELOC_VTABLE_INHERIT, R_OPENRISC_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_OPENRISC_GNU_VTENTRY } +}; static reloc_howto_type * -openrisc_reloc_type_lookup (abfd, code) - bfd * abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +openrisc_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -243,10 +216,9 @@ openrisc_reloc_type_lookup (abfd, code) /* Set the howto pointer for an OpenRISC ELF reloc. */ static void -openrisc_info_to_howto_rela (abfd, cache_ptr, dst) - bfd * abfd ATTRIBUTE_UNUSED; - arelent * cache_ptr; - Elf_Internal_Rela * dst; +openrisc_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr, + Elf_Internal_Rela * dst) { unsigned int r_type; @@ -259,14 +231,12 @@ openrisc_info_to_howto_rela (abfd, cache_ptr, dst) routines, but a few relocs, we have to do them ourselves. */ static bfd_reloc_status_type -openrisc_final_link_relocate (howto, input_bfd, input_section, contents, rel, - relocation) - reloc_howto_type *howto; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *rel; - bfd_vma relocation; +openrisc_final_link_relocate (reloc_howto_type *howto, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *rel, + bfd_vma relocation) { bfd_reloc_status_type r = bfd_reloc_ok; @@ -319,16 +289,14 @@ openrisc_final_link_relocate (howto, input_bfd, input_section, contents, rel, accordingly. */ static bfd_boolean -openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +openrisc_elf_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -396,7 +364,7 @@ openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (r != bfd_reloc_ok) { - const char *msg = (const char *) NULL; + const char *msg = NULL; switch (r) { @@ -444,38 +412,35 @@ openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation. */ static asection * -openrisc_elf_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +openrisc_elf_gc_mark_hook (asection *sec, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { - if (h != NULL) + if (h == NULL) + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); + + switch (ELF32_R_TYPE (rel->r_info)) { - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_OPENRISC_GNU_VTINHERIT: - case R_OPENRISC_GNU_VTENTRY: - break; + case R_OPENRISC_GNU_VTINHERIT: + case R_OPENRISC_GNU_VTENTRY: + break; - default: - switch (h->root.type) - { - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - return h->root.u.def.section; + default: + switch (h->root.type) + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + return h->root.u.def.section; - case bfd_link_hash_common: - return h->root.u.c.p->section; + case bfd_link_hash_common: + return h->root.u.c.p->section; - default: - break; - } + default: + break; } } - else - return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } @@ -483,11 +448,10 @@ openrisc_elf_gc_mark_hook (sec, info, rel, h, sym) /* Update the got entry reference counts for the section being removed. */ static bfd_boolean -openrisc_elf_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - asection *sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; +openrisc_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) { return TRUE; } @@ -497,11 +461,10 @@ openrisc_elf_gc_sweep_hook (abfd, info, sec, relocs) virtual table relocs for gc. */ static bfd_boolean -openrisc_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +openrisc_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; @@ -559,24 +522,17 @@ openrisc_elf_check_relocs (abfd, info, sec, relocs) /* Set the right machine number. */ static bfd_boolean -openrisc_elf_object_p (abfd) - bfd *abfd; +openrisc_elf_object_p (bfd *abfd) { - switch (elf_elfheader (abfd)->e_flags & 0xf) - { - default: - (void) bfd_default_set_arch_mach (abfd, bfd_arch_openrisc, 0); - break; - } + bfd_default_set_arch_mach (abfd, bfd_arch_openrisc, 0); return TRUE; } /* Store the machine number in the flags field. */ static void -openrisc_elf_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +openrisc_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { unsigned long val; diff --git a/bfd/elf32-or32.c b/bfd/elf32-or32.c index f7f9e77669a..546aa151f5c 100644 --- a/bfd/elf32-or32.c +++ b/bfd/elf32-or32.c @@ -1,5 +1,5 @@ /* OR32-specific support for 32-bit ELF - Copyright 2002, 2004 Free Software Foundation, Inc. + Copyright 2002, 2004, 2005 Free Software Foundation, Inc. Contributed by Ivan Guzvinec <ivang@opencores.org> This file is part of BFD, the Binary File Descriptor library. @@ -25,226 +25,14 @@ #include "elf/or32.h" #include "libiberty.h" -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void or32_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_boolean or32_elf_object_p - PARAMS ((bfd *)); -static void or32_elf_final_write_processing - PARAMS ((bfd *, bfd_boolean)); -static bfd_reloc_status_type or32_elf_32_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type or32_elf_16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type or32_elf_8_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type or32_elf_const_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type or32_elf_consth_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type or32_elf_jumptarg_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - /* Try to minimize the amount of space occupied by relocation tables on the ROM (not that the ROM won't be swamped by other ELF overhead). */ #define USE_REL 1 -static reloc_howto_type elf_or32_howto_table[] = -{ - /* This reloc does nothing. */ - HOWTO (R_OR32_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_OR32_NONE", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard 32 bit relocation. */ - HOWTO (R_OR32_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - or32_elf_32_reloc, /* special_function */ - "R_OR32_32", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard 16 bit relocation. */ - HOWTO (R_OR32_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - or32_elf_16_reloc, /* special_function */ - "R_OR32_16", /* name */ - FALSE, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard 8 bit relocation. */ - HOWTO (R_OR32_8, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - or32_elf_8_reloc, /* special_function */ - "R_OR32_8", /* name */ - FALSE, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard low 16 bit relocation. */ - HOWTO (R_OR32_CONST, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - or32_elf_const_reloc, /* special_function */ - "R_OR32_CONST", /* name */ - FALSE, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard high 16 bit relocation. */ - HOWTO (R_OR32_CONSTH, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - or32_elf_consth_reloc, /* special_function */ - "R_OR32_CONSTH", /* name */ - FALSE, /* partial_inplace */ - 0xffff0000, /* src_mask */ - 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A standard branch relocation. */ - HOWTO (R_OR32_JUMPTARG, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 28, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - or32_elf_jumptarg_reloc,/* special_function */ - "R_OR32_JUMPTARG", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0x03ffffff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable hierarchy. */ - HOWTO (R_OR32_GNU_VTINHERIT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "R_OR32_GNU_VTINHERIT", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable member usage. */ - HOWTO (R_OR32_GNU_VTENTRY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - _bfd_elf_rel_vtable_reloc_fn, /* special_function */ - "R_OR32_GNU_VTENTRY", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ -}; - -/* Map BFD reloc types to OR32 ELF reloc types. */ - -struct or32_reloc_map -{ - bfd_reloc_code_real_type bfd_reloc_val; - unsigned char elf_reloc_val; -}; - -static const struct or32_reloc_map or32_reloc_map[] = -{ - { BFD_RELOC_NONE, R_OR32_NONE }, - { BFD_RELOC_32, R_OR32_32 }, - { BFD_RELOC_16, R_OR32_16 }, - { BFD_RELOC_8, R_OR32_8 }, - { BFD_RELOC_LO16, R_OR32_CONST }, - { BFD_RELOC_HI16, R_OR32_CONSTH }, - { BFD_RELOC_32_GOT_PCREL, R_OR32_JUMPTARG }, - { BFD_RELOC_VTABLE_INHERIT, R_OR32_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_OR32_GNU_VTENTRY }, -}; - -static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; -{ - unsigned int i; - - for (i = ARRAY_SIZE (or32_reloc_map); i--;) - { - if (or32_reloc_map[i].bfd_reloc_val == code) - return &elf_or32_howto_table[or32_reloc_map[i].elf_reloc_val]; - } - - return NULL; -} - -/* Set the howto pointer for an OR32 ELF reloc. */ - -static void -or32_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - unsigned int r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_OR32_max); - cache_ptr->howto = &elf_or32_howto_table[r_type]; -} - /* Set the right machine number for an OR32 ELF file. */ static bfd_boolean -or32_elf_object_p (abfd) - bfd *abfd; +or32_elf_object_p (bfd *abfd) { (void) bfd_default_set_arch_mach (abfd, bfd_arch_or32, 0); return TRUE; @@ -254,41 +42,22 @@ or32_elf_object_p (abfd) This gets the OR32 architecture right based on the machine number. */ static void -or32_elf_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +or32_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { - int mach; - unsigned long val; - - switch (mach = bfd_get_mach (abfd)) - { - /* - case bfd_mach_arc_base: - val = E_OR32_MACH_BASE; - break; - */ - default: - val = 0; - return; - } - elf_elfheader (abfd)->e_flags &=~ EF_OR32_MACH; - elf_elfheader (abfd)->e_flags |= val; } -bfd_reloc_status_type -or32_elf_32_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +static bfd_reloc_status_type +or32_elf_32_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { unsigned long insn; bfd_size_type addr = reloc_entry->address; @@ -307,18 +76,16 @@ or32_elf_32_reloc (abfd, reloc_entry, symbol, data, input_section, return bfd_reloc_continue; } -bfd_reloc_status_type -or32_elf_16_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +static bfd_reloc_status_type +or32_elf_16_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { unsigned short insn; bfd_size_type addr = reloc_entry->address; @@ -337,18 +104,16 @@ or32_elf_16_reloc (abfd, reloc_entry, symbol, data, input_section, return bfd_reloc_continue; } -bfd_reloc_status_type -or32_elf_8_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +static bfd_reloc_status_type +or32_elf_8_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { unsigned char insn; bfd_size_type addr = reloc_entry->address; @@ -387,16 +152,14 @@ struct or32_consth static struct or32_consth *or32_consth_list; -bfd_reloc_status_type -or32_elf_consth_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +static bfd_reloc_status_type +or32_elf_consth_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { bfd_reloc_status_type ret; bfd_vma relocation; @@ -405,7 +168,7 @@ or32_elf_consth_reloc (abfd, reloc_entry, symbol, data, input_section, ret = bfd_reloc_ok; if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) + && output_bfd == NULL) ret = bfd_reloc_undefined; if (bfd_is_com_section (symbol->section)) @@ -421,7 +184,7 @@ or32_elf_consth_reloc (abfd, reloc_entry, symbol, data, input_section, return bfd_reloc_outofrange; /* Save the information, and let LO16 do the actual relocation. */ - n = (struct or32_consth *) bfd_malloc (sizeof *n); + n = bfd_malloc (sizeof *n); if (n == NULL) return bfd_reloc_outofrange; n->addr = (bfd_byte *) data + reloc_entry->address; @@ -429,7 +192,7 @@ or32_elf_consth_reloc (abfd, reloc_entry, symbol, data, input_section, n->next = or32_consth_list; or32_consth_list = n; - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) reloc_entry->address += input_section->output_offset; return ret; @@ -439,16 +202,14 @@ or32_elf_consth_reloc (abfd, reloc_entry, symbol, data, input_section, inplace relocation; this function exists in order to do the R_OR32_CONSTH relocation described above. */ -bfd_reloc_status_type -or32_elf_const_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +static bfd_reloc_status_type +or32_elf_const_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message) { if (or32_consth_list != NULL) { @@ -482,7 +243,7 @@ or32_elf_const_reloc (abfd, reloc_entry, symbol, data, input_section, or32_consth_list = NULL; } - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { unsigned long insn, tmp; bfd_size_type addr = reloc_entry->address; @@ -505,18 +266,16 @@ or32_elf_const_reloc (abfd, reloc_entry, symbol, data, input_section, input_section, output_bfd, error_message); } -bfd_reloc_status_type -or32_elf_jumptarg_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol ATTRIBUTE_UNUSED; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +static bfd_reloc_status_type +or32_elf_jumptarg_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { unsigned long insn, tmp; bfd_size_type addr = reloc_entry->address; @@ -535,6 +294,192 @@ or32_elf_jumptarg_reloc (abfd, reloc_entry, symbol, data, input_section, return bfd_reloc_continue; } +static reloc_howto_type elf_or32_howto_table[] = +{ + /* This reloc does nothing. */ + HOWTO (R_OR32_NONE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_OR32_NONE", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A standard 32 bit relocation. */ + HOWTO (R_OR32_32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + or32_elf_32_reloc, /* special_function */ + "R_OR32_32", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A standard 16 bit relocation. */ + HOWTO (R_OR32_16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + or32_elf_16_reloc, /* special_function */ + "R_OR32_16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A standard 8 bit relocation. */ + HOWTO (R_OR32_8, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + or32_elf_8_reloc, /* special_function */ + "R_OR32_8", /* name */ + FALSE, /* partial_inplace */ + 0x000000ff, /* src_mask */ + 0x000000ff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A standard low 16 bit relocation. */ + HOWTO (R_OR32_CONST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + or32_elf_const_reloc, /* special_function */ + "R_OR32_CONST", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A standard high 16 bit relocation. */ + HOWTO (R_OR32_CONSTH, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + or32_elf_consth_reloc, /* special_function */ + "R_OR32_CONSTH", /* name */ + FALSE, /* partial_inplace */ + 0xffff0000, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A standard branch relocation. */ + HOWTO (R_OR32_JUMPTARG, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 28, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + or32_elf_jumptarg_reloc,/* special_function */ + "R_OR32_JUMPTARG", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x03ffffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* GNU extension to record C++ vtable hierarchy. */ + HOWTO (R_OR32_GNU_VTINHERIT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + NULL, /* special_function */ + "R_OR32_GNU_VTINHERIT", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* GNU extension to record C++ vtable member usage. */ + HOWTO (R_OR32_GNU_VTENTRY, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_elf_rel_vtable_reloc_fn, /* special_function */ + "R_OR32_GNU_VTENTRY", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; + +/* Map BFD reloc types to OR32 ELF reloc types. */ + +struct or32_reloc_map +{ + bfd_reloc_code_real_type bfd_reloc_val; + unsigned char elf_reloc_val; +}; + +static const struct or32_reloc_map or32_reloc_map[] = +{ + { BFD_RELOC_NONE, R_OR32_NONE }, + { BFD_RELOC_32, R_OR32_32 }, + { BFD_RELOC_16, R_OR32_16 }, + { BFD_RELOC_8, R_OR32_8 }, + { BFD_RELOC_LO16, R_OR32_CONST }, + { BFD_RELOC_HI16, R_OR32_CONSTH }, + { BFD_RELOC_32_GOT_PCREL, R_OR32_JUMPTARG }, + { BFD_RELOC_VTABLE_INHERIT, R_OR32_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_OR32_GNU_VTENTRY }, +}; + +static reloc_howto_type * +bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = ARRAY_SIZE (or32_reloc_map); i--;) + if (or32_reloc_map[i].bfd_reloc_val == code) + return &elf_or32_howto_table[or32_reloc_map[i].elf_reloc_val]; + + return NULL; +} + +/* Set the howto pointer for an OR32 ELF reloc. */ + +static void +or32_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) +{ + unsigned int r_type; + + r_type = ELF32_R_TYPE (dst->r_info); + BFD_ASSERT (r_type < (unsigned int) R_OR32_max); + cache_ptr->howto = &elf_or32_howto_table[r_type]; +} + #define TARGET_LITTLE_SYM bfd_elf32_or32_little_vec #define TARGET_LITTLE_NAME "elf32-littleor32" #define TARGET_BIG_SYM bfd_elf32_or32_big_vec diff --git a/bfd/elf32-pj.c b/bfd/elf32-pj.c index 3ad0b6c352d..bd0a5b49ffa 100644 --- a/bfd/elf32-pj.c +++ b/bfd/elf32-pj.c @@ -1,22 +1,22 @@ /* picoJava specific support for 32-bit ELF - Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc. Contributed by Steve Chamberlan of Transmeta (sac@pobox.com). -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bfd.h" #include "sysdep.h" @@ -25,14 +25,87 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "elf-bfd.h" #include "elf/pj.h" -static bfd_reloc_status_type pj_elf_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *pj_elf_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void pj_elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static void pj_elf_final_write_processing - PARAMS ((bfd *, bfd_boolean)); +/* This function is used for normal relocs. This is like the COFF + function, and is almost certainly incorrect for other ELF targets. */ + +static bfd_reloc_status_type +pj_elf_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol_in, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + unsigned long insn; + bfd_vma sym_value; + enum elf_pj_reloc_type r_type; + bfd_vma addr = reloc_entry->address; + bfd_byte *hit_data = addr + (bfd_byte *) data; + + r_type = (enum elf_pj_reloc_type) reloc_entry->howto->type; + + if (output_bfd != NULL) + { + /* Partial linking--do nothing. */ + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (symbol_in != NULL + && bfd_is_und_section (symbol_in->section)) + return bfd_reloc_undefined; + + if (bfd_is_com_section (symbol_in->section)) + sym_value = 0; + else + sym_value = (symbol_in->value + + symbol_in->section->output_section->vma + + symbol_in->section->output_offset); + + switch (r_type) + { + case R_PJ_DATA_DIR32: + insn = bfd_get_32 (abfd, hit_data); + insn += sym_value + reloc_entry->addend; + bfd_put_32 (abfd, (bfd_vma) insn, hit_data); + break; + + /* Relocations in code are always bigendian, no matter what the + data endianness is. */ + + case R_PJ_CODE_DIR32: + insn = bfd_getb32 (hit_data); + insn += sym_value + reloc_entry->addend; + bfd_putb32 ((bfd_vma) insn, hit_data); + break; + + case R_PJ_CODE_REL16: + insn = bfd_getb16 (hit_data); + insn += sym_value + reloc_entry->addend + - (input_section->output_section->vma + + input_section->output_offset); + bfd_putb16 ((bfd_vma) insn, hit_data); + break; + case R_PJ_CODE_LO16: + insn = bfd_getb16 (hit_data); + insn += sym_value + reloc_entry->addend; + bfd_putb16 ((bfd_vma) insn, hit_data); + break; + + case R_PJ_CODE_HI16: + insn = bfd_getb16 (hit_data); + insn += (sym_value + reloc_entry->addend) >> 16; + bfd_putb16 ((bfd_vma) insn, hit_data); + break; + + default: + abort (); + break; + } + + return bfd_reloc_ok; +} static reloc_howto_type pj_elf_howto_table[] = { @@ -53,7 +126,7 @@ static reloc_howto_type pj_elf_howto_table[] = /* 32 bit absolute relocation. Setting partial_inplace to TRUE and src_mask to a non-zero value is similar to the COFF toolchain. */ - HOWTO (R_PJ_DATA_DIR32, /* type */ + HOWTO (R_PJ_DATA_DIR32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ @@ -68,7 +141,7 @@ static reloc_howto_type pj_elf_howto_table[] = FALSE), /* pcrel_offset */ /* 32 bit PC relative relocation. */ - HOWTO (R_PJ_CODE_REL32, /* type */ + HOWTO (R_PJ_CODE_REL32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ @@ -83,7 +156,7 @@ static reloc_howto_type pj_elf_howto_table[] = TRUE), /* pcrel_offset */ /* 16 bit PC relative relocation. */ - HOWTO (R_PJ_CODE_REL16, /* type */ + HOWTO (R_PJ_CODE_REL16, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ @@ -147,7 +220,7 @@ static reloc_howto_type pj_elf_howto_table[] = 0xffff, /* dst_mask */ TRUE), /* pcrel_offset */ - /* GNU extension to record C++ vtable hierarchy */ + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_PJ_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -162,7 +235,7 @@ static reloc_howto_type pj_elf_howto_table[] = 0, /* dst_mask */ FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable member usage */ + /* GNU extension to record C++ vtable member usage. */ HOWTO (R_PJ_GNU_VTENTRY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -178,90 +251,6 @@ static reloc_howto_type pj_elf_howto_table[] = FALSE), /* pcrel_offset */ }; -/* This function is used for normal relocs. This is like the COFF - function, and is almost certainly incorrect for other ELF targets. */ - -static bfd_reloc_status_type -pj_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - unsigned long insn; - bfd_vma sym_value; - enum elf_pj_reloc_type r_type; - bfd_vma addr = reloc_entry->address; - bfd_byte *hit_data = addr + (bfd_byte *) data; - - r_type = (enum elf_pj_reloc_type) reloc_entry->howto->type; - - if (output_bfd != NULL) - { - /* Partial linking--do nothing. */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - return bfd_reloc_undefined; - - if (bfd_is_com_section (symbol_in->section)) - sym_value = 0; - else - sym_value = (symbol_in->value + - symbol_in->section->output_section->vma + - symbol_in->section->output_offset); - - switch (r_type) - { - case R_PJ_DATA_DIR32: - insn = bfd_get_32 (abfd, hit_data); - insn += sym_value + reloc_entry->addend; - bfd_put_32 (abfd, (bfd_vma) insn, hit_data); - break; - - /* Relocations in code are always bigendian, no matter what the - data endianness is. */ - - case R_PJ_CODE_DIR32: - insn = bfd_getb32 (hit_data); - insn += sym_value + reloc_entry->addend; - bfd_putb32 ((bfd_vma) insn, hit_data); - break; - - case R_PJ_CODE_REL16: - insn = bfd_getb16 (hit_data); - insn += sym_value + reloc_entry->addend - - (input_section->output_section->vma - + input_section->output_offset); - bfd_putb16 ((bfd_vma) insn, hit_data); - break; - case R_PJ_CODE_LO16: - insn = bfd_getb16 (hit_data); - insn += sym_value + reloc_entry->addend; - bfd_putb16 ((bfd_vma) insn, hit_data); - break; - - case R_PJ_CODE_HI16: - insn = bfd_getb16 (hit_data); - insn += (sym_value + reloc_entry->addend) >> 16; - bfd_putb16 ((bfd_vma) insn, hit_data); - break; - - default: - abort (); - break; - } - - return bfd_reloc_ok; -} - /* This structure is used to map BFD reloc codes to PJ ELF relocs. */ struct elf_reloc_map @@ -290,17 +279,14 @@ static const struct elf_reloc_map pj_reloc_map[] = corresponding PJ ELf reloc. */ static reloc_howto_type * -pj_elf_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +pj_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; for (i = 0; i < sizeof (pj_reloc_map) / sizeof (struct elf_reloc_map); i++) - { - if (pj_reloc_map[i].bfd_reloc_val == code) - return &pj_elf_howto_table[(int) pj_reloc_map[i].elf_reloc_val]; - } + if (pj_reloc_map[i].bfd_reloc_val == code) + return & pj_elf_howto_table[(int) pj_reloc_map[i].elf_reloc_val]; return NULL; } @@ -308,10 +294,9 @@ pj_elf_reloc_type_lookup (abfd, code) /* Given an ELF reloc, fill in the howto field of a relent. */ static void -pj_elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +pj_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r; @@ -326,12 +311,11 @@ pj_elf_info_to_howto (abfd, cache_ptr, dst) e_flags field. */ static void -pj_elf_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +pj_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { - elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_ARCH; - elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_GNUCALLS; + elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_ARCH; + elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_GNUCALLS; } #define TARGET_BIG_SYM bfd_elf32_pj_vec diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index 47d87d21b4e..ba98a180717 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -16,7 +16,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char dependencies. As is the gas & simulator code for the v850. */ @@ -32,628 +33,15 @@ /* Sign-extend a 24-bit number. */ #define SEXT24(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) -static reloc_howto_type *v850_elf_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void v850_elf_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static void v850_elf_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_reloc_status_type v850_elf_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_boolean v850_elf_is_local_label_name - PARAMS ((bfd *, const char *)); -static bfd_boolean v850_elf_relocate_section - PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_reloc_status_type v850_elf_perform_relocation - PARAMS ((bfd *, unsigned int, bfd_vma, bfd_byte *)); -static bfd_boolean v850_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); -static void remember_hi16s_reloc - PARAMS ((bfd *, bfd_vma, bfd_byte *)); -static bfd_byte * find_remembered_hi16s_reloc - PARAMS ((bfd_vma, bfd_boolean *)); -static bfd_reloc_status_type v850_elf_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, bfd_vma, - bfd_vma, bfd_vma, struct bfd_link_info *, asection *, int)); -static bfd_boolean v850_elf_object_p - PARAMS ((bfd *)); -static bfd_boolean v850_elf_fake_sections - PARAMS ((bfd *, Elf_Internal_Shdr *, asection *)); -static void v850_elf_final_write_processing - PARAMS ((bfd *, bfd_boolean)); -static bfd_boolean v850_elf_set_private_flags - PARAMS ((bfd *, flagword)); -static bfd_boolean v850_elf_merge_private_bfd_data - PARAMS ((bfd *, bfd *)); -static bfd_boolean v850_elf_print_private_bfd_data - PARAMS ((bfd *, PTR)); -static bfd_boolean v850_elf_section_from_bfd_section - PARAMS ((bfd *, asection *, int *)); -static void v850_elf_symbol_processing - PARAMS ((bfd *, asymbol *)); -static bfd_boolean v850_elf_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); -static bfd_boolean v850_elf_link_output_symbol_hook - PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *, - asection *, struct elf_link_hash_entry *)); -static bfd_boolean v850_elf_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static asection * v850_elf_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, - Elf_Internal_Rela *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static bfd_reloc_status_type v850_elf_ignore_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_boolean v850_elf_relax_delete_bytes - PARAMS ((bfd *, asection *, bfd_vma, bfd_vma, int)); -static bfd_boolean v850_elf_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *)); - -/* Note: It is REQUIRED that the 'type' value of each entry - in this array match the index of the entry in the array. */ -static reloc_howto_type v850_elf_howto_table[] = -{ - /* This reloc does nothing. */ - HOWTO (R_V850_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_V850_NONE", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* A PC relative 9 bit branch. */ - HOWTO (R_V850_9_PCREL, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_9_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0x00ffffff, /* src_mask */ - 0x00ffffff, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* A PC relative 22 bit branch. */ - HOWTO (R_V850_22_PCREL, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 22, /* bitsize */ - TRUE, /* pc_relative */ - 7, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_22_PCREL", /* name */ - FALSE, /* partial_inplace */ - 0x07ffff80, /* src_mask */ - 0x07ffff80, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* High 16 bits of symbol value. */ - HOWTO (R_V850_HI16_S, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_HI16_S", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* High 16 bits of symbol value. */ - HOWTO (R_V850_HI16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_HI16", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* Low 16 bits of symbol value. */ - HOWTO (R_V850_LO16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_LO16", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* Simple 32bit reloc. */ - HOWTO (R_V850_ABS32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_ABS32", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* Simple 16bit reloc. */ - HOWTO (R_V850_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_V850_16", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* Simple 8bit reloc. */ - HOWTO (R_V850_8, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_V850_8", /* name */ - FALSE, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 16 bit offset from the short data area pointer. */ - HOWTO (R_V850_SDA_16_16_OFFSET, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_SDA_16_16_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 15 bit offset from the short data area pointer. */ - HOWTO (R_V850_SDA_15_16_OFFSET, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 1, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_SDA_15_16_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0xfffe, /* src_mask */ - 0xfffe, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 16 bit offset from the zero data area pointer. */ - HOWTO (R_V850_ZDA_16_16_OFFSET, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_ZDA_16_16_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 15 bit offset from the zero data area pointer. */ - HOWTO (R_V850_ZDA_15_16_OFFSET, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 1, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_ZDA_15_16_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0xfffe, /* src_mask */ - 0xfffe, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 6 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_6_8_OFFSET, /* type */ - 2, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - FALSE, /* pc_relative */ - 1, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_TDA_6_8_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0x7e, /* src_mask */ - 0x7e, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 8 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_7_8_OFFSET, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_TDA_7_8_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0x7f, /* src_mask */ - 0x7f, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 7 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_7_7_OFFSET, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 7, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_TDA_7_7_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0x7f, /* src_mask */ - 0x7f, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 16 bit offset from the tiny data area pointer! */ - HOWTO (R_V850_TDA_16_16_OFFSET, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_TDA_16_16_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xfff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 5 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_4_5_OFFSET, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 5, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_TDA_4_5_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0x0f, /* src_mask */ - 0x0f, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 4 bit offset from the tiny data area pointer. */ - HOWTO (R_V850_TDA_4_4_OFFSET, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 4, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_TDA_4_4_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0x0f, /* src_mask */ - 0x0f, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 16 bit offset from the short data area pointer. */ - HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_SDA_16_16_SPLIT_OFFSET",/* name */ - FALSE, /* partial_inplace */ - 0xfffe0020, /* src_mask */ - 0xfffe0020, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 16 bit offset from the zero data area pointer. */ - HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_ZDA_16_16_SPLIT_OFFSET",/* name */ - FALSE, /* partial_inplace */ - 0xfffe0020, /* src_mask */ - 0xfffe0020, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 6 bit offset from the call table base pointer. */ - HOWTO (R_V850_CALLT_6_7_OFFSET, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 7, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_CALLT_6_7_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0x3f, /* src_mask */ - 0x3f, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* 16 bit offset from the call table base pointer. */ - HOWTO (R_V850_CALLT_16_16_OFFSET, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_CALLT_16_16_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable hierarchy */ - HOWTO (R_V850_GNU_VTINHERIT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - NULL, /* special_function */ - "R_V850_GNU_VTINHERIT", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* GNU extension to record C++ vtable member usage */ - HOWTO (R_V850_GNU_VTENTRY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - _bfd_elf_rel_vtable_reloc_fn, /* special_function */ - "R_V850_GNU_VTENTRY", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* Indicates a .longcall pseudo-op. The compiler will generate a .longcall - pseudo-op when it finds a function call which can be relaxed. */ - HOWTO (R_V850_LONGCALL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - v850_elf_ignore_reloc, /* special_function */ - "R_V850_LONGCALL", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* Indicates a .longjump pseudo-op. The compiler will generate a - .longjump pseudo-op when it finds a branch which can be relaxed. */ - HOWTO (R_V850_LONGJUMP, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - v850_elf_ignore_reloc, /* special_function */ - "R_V850_LONGJUMP", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - TRUE), /* pcrel_offset */ - - HOWTO (R_V850_ALIGN, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_unsigned, /* complain_on_overflow */ - v850_elf_ignore_reloc, /* special_function */ - "R_V850_ALIGN", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - TRUE), /* pcrel_offset */ - - /* Simple pc-relative 32bit reloc. */ - HOWTO (R_V850_REL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - TRUE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_REL32", /* name */ - FALSE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ - - /* An ld.bu version of R_V850_LO16. */ - HOWTO (R_V850_LO16_SPLIT_OFFSET, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - v850_elf_reloc, /* special_function */ - "R_V850_LO16_SPLIT_OFFSET", /* name */ - FALSE, /* partial_inplace */ - 0xfffe0020, /* src_mask */ - 0xfffe0020, /* dst_mask */ - FALSE), /* pcrel_offset */ -}; - -/* Map BFD reloc types to V850 ELF reloc types. */ - -struct v850_elf_reloc_map -{ - /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an - unsigned char. */ - bfd_reloc_code_real_type bfd_reloc_val; - unsigned int elf_reloc_val; -}; - -static const struct v850_elf_reloc_map v850_elf_reloc_map[] = -{ - { BFD_RELOC_NONE, R_V850_NONE }, - { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL }, - { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL }, - { BFD_RELOC_HI16_S, R_V850_HI16_S }, - { BFD_RELOC_HI16, R_V850_HI16 }, - { BFD_RELOC_LO16, R_V850_LO16 }, - { BFD_RELOC_32, R_V850_ABS32 }, - { BFD_RELOC_32_PCREL, R_V850_REL32 }, - { BFD_RELOC_16, R_V850_16 }, - { BFD_RELOC_8, R_V850_8 }, - { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET }, - { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET }, - { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET }, - { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET }, - { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET }, - { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET }, - { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET }, - { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET }, - { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET }, - { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET }, - { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_OFFSET }, - { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET }, - { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET }, - { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET }, - { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET }, - { BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT }, - { BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY }, - { BFD_RELOC_V850_LONGCALL, R_V850_LONGCALL }, - { BFD_RELOC_V850_LONGJUMP, R_V850_LONGJUMP }, - { BFD_RELOC_V850_ALIGN, R_V850_ALIGN }, - -}; - -/* Map a bfd relocation into the appropriate howto structure. */ - -static reloc_howto_type * -v850_elf_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; -{ - unsigned int i; - - for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;) - if (v850_elf_reloc_map[i].bfd_reloc_val == code) - { - unsigned int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val; - - BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val); - - return v850_elf_howto_table + elf_reloc_val; - } - - return NULL; -} - -/* Set the howto pointer for an V850 ELF reloc. */ - -static void -v850_elf_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - unsigned int r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_V850_max); - cache_ptr->howto = &v850_elf_howto_table[r_type]; -} - -/* Set the howto pointer for a V850 ELF reloc (type RELA). */ -static void -v850_elf_info_to_howto_rela (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent * cache_ptr; - Elf_Internal_Rela *dst; -{ - unsigned int r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_V850_max); - cache_ptr->howto = &v850_elf_howto_table[r_type]; -} - /* Look through the relocs for a section during the first phase, and allocate space in the global offset table or procedure linkage table. */ static bfd_boolean -v850_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +v850_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { bfd_boolean ret = TRUE; bfd *dynobj; @@ -664,7 +52,7 @@ v850_elf_check_relocs (abfd, info, sec, relocs) asection *sreloc; enum v850_reloc_type r_type; int other = 0; - const char *common = (const char *)0; + const char *common = NULL; if (info->relocatable) return TRUE; @@ -834,30 +222,27 @@ v850_elf_check_relocs (abfd, info, sec, relocs) typedef struct hi16s_location { - bfd_vma addend; - bfd_byte *address; - unsigned long counter; - bfd_boolean found; - struct hi16s_location *next; + bfd_vma addend; + bfd_byte * address; + unsigned long counter; + bfd_boolean found; + struct hi16s_location * next; } hi16s_location; -static hi16s_location *previous_hi16s; -static hi16s_location *free_hi16s; -static unsigned long hi16s_counter; +static hi16s_location * previous_hi16s; +static hi16s_location * free_hi16s; +static unsigned long hi16s_counter; static void -remember_hi16s_reloc (abfd, addend, address) - bfd *abfd; - bfd_vma addend; - bfd_byte *address; +remember_hi16s_reloc (bfd *abfd, bfd_vma addend, bfd_byte *address) { hi16s_location * entry = NULL; bfd_size_type amt = sizeof (* free_hi16s); /* Find a free structure. */ if (free_hi16s == NULL) - free_hi16s = (hi16s_location *) bfd_zalloc (abfd, amt); + free_hi16s = bfd_zalloc (abfd, amt); entry = free_hi16s; free_hi16s = free_hi16s->next; @@ -872,20 +257,16 @@ remember_hi16s_reloc (abfd, addend, address) /* Cope with wrap around of our counter. */ if (hi16s_counter == 0) { - /* XXX - Assume that all counter entries differ only in their low 16 bits. */ + /* XXX: Assume that all counter entries differ only in their low 16 bits. */ for (entry = previous_hi16s; entry != NULL; entry = entry->next) entry->counter &= 0xffff; hi16s_counter = 0x10000; } - - return; } static bfd_byte * -find_remembered_hi16s_reloc (addend, already_found) - bfd_vma addend; - bfd_boolean *already_found; +find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found) { hi16s_location *match = NULL; hi16s_location *entry; @@ -1070,6 +451,7 @@ v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn, { #define BIT15_SET(x) ((x) & 0x8000) #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff) + if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend)) || (OVERFLOWS (addend, *insn) && ((! BIT15_SET (*insn)) || (BIT15_SET (addend))))) @@ -1107,11 +489,10 @@ v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn, allowed to do its stuff instead. At least for most of the relocs, anyway. */ static bfd_reloc_status_type -v850_elf_perform_relocation (abfd, r_type, addend, address) - bfd *abfd; - unsigned int r_type; - bfd_vma addend; - bfd_byte *address; +v850_elf_perform_relocation (bfd *abfd, + unsigned int r_type, + bfd_vma addend, + bfd_byte *address) { unsigned long insn; unsigned long result; @@ -1120,7 +501,6 @@ v850_elf_perform_relocation (abfd, r_type, addend, address) switch (r_type) { default: - /* fprintf (stderr, "reloc type %d not SUPPORTED\n", r_type ); */ return bfd_reloc_notsupported; case R_V850_REL32: @@ -1202,8 +582,6 @@ v850_elf_perform_relocation (abfd, r_type, addend, address) break; case R_V850_16: - - /* drop through */ case R_V850_SDA_16_16_OFFSET: case R_V850_ZDA_16_16_OFFSET: case R_V850_TDA_16_16_OFFSET: @@ -1364,14 +742,13 @@ v850_elf_perform_relocation (abfd, r_type, addend, address) /* Insert the addend into the instruction. */ static bfd_reloc_status_type -v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc; - asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; - asection *isection; - bfd *obfd; - char **err ATTRIBUTE_UNUSED; +v850_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc, + asymbol *symbol, + void * data ATTRIBUTE_UNUSED, + asection *isection, + bfd *obfd, + char **err ATTRIBUTE_UNUSED) { long relocation; @@ -1380,7 +757,7 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) and either we are not putting the addend into the instruction or the addend is zero, so there is nothing to add into the instruction then just fixup the address and return. */ - if (obfd != (bfd *) NULL + if (obfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && (! reloc->howto->partial_inplace || reloc->addend == 0)) @@ -1426,26 +803,571 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) for relaxing, which the linker should otherwise ignore. */ static bfd_reloc_status_type -v850_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *reloc_entry; - asymbol *symbol ATTRIBUTE_UNUSED; - PTR data ATTRIBUTE_UNUSED; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; +v850_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, + arelent *reloc_entry, + asymbol *symbol ATTRIBUTE_UNUSED, + void * data ATTRIBUTE_UNUSED, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) { if (output_bfd != NULL) reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; } +/* Note: It is REQUIRED that the 'type' value of each entry + in this array match the index of the entry in the array. */ +static reloc_howto_type v850_elf_howto_table[] = +{ + /* This reloc does nothing. */ + HOWTO (R_V850_NONE, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_V850_NONE", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* A PC relative 9 bit branch. */ + HOWTO (R_V850_9_PCREL, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 26, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_bitfield, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_9_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x00ffffff, /* Src_mask. */ + 0x00ffffff, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* A PC relative 22 bit branch. */ + HOWTO (R_V850_22_PCREL, /* Type. */ + 2, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 22, /* Bitsize. */ + TRUE, /* PC_relative. */ + 7, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_22_PCREL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x07ffff80, /* Src_mask. */ + 0x07ffff80, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* High 16 bits of symbol value. */ + HOWTO (R_V850_HI16_S, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_HI16_S", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* High 16 bits of symbol value. */ + HOWTO (R_V850_HI16, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_HI16", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* Low 16 bits of symbol value. */ + HOWTO (R_V850_LO16, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_LO16", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* Simple 32bit reloc. */ + HOWTO (R_V850_ABS32, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_ABS32", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* Simple 16bit reloc. */ + HOWTO (R_V850_16, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_V850_16", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* Simple 8bit reloc. */ + HOWTO (R_V850_8, /* Type. */ + 0, /* Rightshift. */ + 0, /* Size (0 = byte, 1 = short, 2 = long). */ + 8, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + bfd_elf_generic_reloc, /* Special_function. */ + "R_V850_8", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xff, /* Src_mask. */ + 0xff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 16 bit offset from the short data area pointer. */ + HOWTO (R_V850_SDA_16_16_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_SDA_16_16_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 15 bit offset from the short data area pointer. */ + HOWTO (R_V850_SDA_15_16_OFFSET, /* Type. */ + 1, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 1, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_SDA_15_16_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xfffe, /* Src_mask. */ + 0xfffe, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 16 bit offset from the zero data area pointer. */ + HOWTO (R_V850_ZDA_16_16_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_ZDA_16_16_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 15 bit offset from the zero data area pointer. */ + HOWTO (R_V850_ZDA_15_16_OFFSET, /* Type. */ + 1, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 1, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_ZDA_15_16_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xfffe, /* Src_mask. */ + 0xfffe, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 6 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_6_8_OFFSET, /* Type. */ + 2, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 8, /* Bitsize. */ + FALSE, /* PC_relative. */ + 1, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_TDA_6_8_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x7e, /* Src_mask. */ + 0x7e, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 8 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_7_8_OFFSET, /* Type. */ + 1, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 8, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_TDA_7_8_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x7f, /* Src_mask. */ + 0x7f, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 7 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_7_7_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 7, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_TDA_7_7_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x7f, /* Src_mask. */ + 0x7f, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 16 bit offset from the tiny data area pointer! */ + HOWTO (R_V850_TDA_16_16_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_TDA_16_16_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xfff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 5 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_4_5_OFFSET, /* Type. */ + 1, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 5, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_TDA_4_5_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x0f, /* Src_mask. */ + 0x0f, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 4 bit offset from the tiny data area pointer. */ + HOWTO (R_V850_TDA_4_4_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 4, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_TDA_4_4_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x0f, /* Src_mask. */ + 0x0f, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 16 bit offset from the short data area pointer. */ + HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_SDA_16_16_SPLIT_OFFSET",/* Name. */ + FALSE, /* Partial_inplace. */ + 0xfffe0020, /* Src_mask. */ + 0xfffe0020, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 16 bit offset from the zero data area pointer. */ + HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_ZDA_16_16_SPLIT_OFFSET",/* Name. */ + FALSE, /* Partial_inplace. */ + 0xfffe0020, /* Src_mask. */ + 0xfffe0020, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 6 bit offset from the call table base pointer. */ + HOWTO (R_V850_CALLT_6_7_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 7, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_CALLT_6_7_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0x3f, /* Src_mask. */ + 0x3f, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* 16 bit offset from the call table base pointer. */ + HOWTO (R_V850_CALLT_16_16_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_CALLT_16_16_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffff, /* Src_mask. */ + 0xffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* GNU extension to record C++ vtable hierarchy */ + HOWTO (R_V850_GNU_VTINHERIT, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + NULL, /* Special_function. */ + "R_V850_GNU_VTINHERIT", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* GNU extension to record C++ vtable member usage */ + HOWTO (R_V850_GNU_VTENTRY, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + _bfd_elf_rel_vtable_reloc_fn, /* Special_function. */ + "R_V850_GNU_VTENTRY", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* Indicates a .longcall pseudo-op. The compiler will generate a .longcall + pseudo-op when it finds a function call which can be relaxed. */ + HOWTO (R_V850_LONGCALL, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + v850_elf_ignore_reloc, /* Special_function. */ + "R_V850_LONGCALL", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* Indicates a .longjump pseudo-op. The compiler will generate a + .longjump pseudo-op when it finds a branch which can be relaxed. */ + HOWTO (R_V850_LONGJUMP, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_signed, /* Complain_on_overflow. */ + v850_elf_ignore_reloc, /* Special_function. */ + "R_V850_LONGJUMP", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + HOWTO (R_V850_ALIGN, /* Type. */ + 0, /* Rightshift. */ + 1, /* Size (0 = byte, 1 = short, 2 = long). */ + 0, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_unsigned, /* Complain_on_overflow. */ + v850_elf_ignore_reloc, /* Special_function. */ + "R_V850_ALIGN", /* Name. */ + FALSE, /* Partial_inplace. */ + 0, /* Src_mask. */ + 0, /* Dst_mask. */ + TRUE), /* PCrel_offset. */ + + /* Simple pc-relative 32bit reloc. */ + HOWTO (R_V850_REL32, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 32, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_REL32", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xffffffff, /* Src_mask. */ + 0xffffffff, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ + + /* An ld.bu version of R_V850_LO16. */ + HOWTO (R_V850_LO16_SPLIT_OFFSET, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + FALSE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain_on_overflow. */ + v850_elf_reloc, /* Special_function. */ + "R_V850_LO16_SPLIT_OFFSET", /* Name. */ + FALSE, /* Partial_inplace. */ + 0xfffe0020, /* Src_mask. */ + 0xfffe0020, /* Dst_mask. */ + FALSE), /* PCrel_offset. */ +}; + +/* Map BFD reloc types to V850 ELF reloc types. */ + +struct v850_elf_reloc_map +{ + /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an + unsigned char. */ + bfd_reloc_code_real_type bfd_reloc_val; + unsigned int elf_reloc_val; +}; + +static const struct v850_elf_reloc_map v850_elf_reloc_map[] = +{ + { BFD_RELOC_NONE, R_V850_NONE }, + { BFD_RELOC_V850_9_PCREL, R_V850_9_PCREL }, + { BFD_RELOC_V850_22_PCREL, R_V850_22_PCREL }, + { BFD_RELOC_HI16_S, R_V850_HI16_S }, + { BFD_RELOC_HI16, R_V850_HI16 }, + { BFD_RELOC_LO16, R_V850_LO16 }, + { BFD_RELOC_32, R_V850_ABS32 }, + { BFD_RELOC_32_PCREL, R_V850_REL32 }, + { BFD_RELOC_16, R_V850_16 }, + { BFD_RELOC_8, R_V850_8 }, + { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V850_SDA_16_16_OFFSET }, + { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V850_SDA_15_16_OFFSET }, + { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V850_ZDA_16_16_OFFSET }, + { BFD_RELOC_V850_ZDA_15_16_OFFSET, R_V850_ZDA_15_16_OFFSET }, + { BFD_RELOC_V850_TDA_6_8_OFFSET, R_V850_TDA_6_8_OFFSET }, + { BFD_RELOC_V850_TDA_7_8_OFFSET, R_V850_TDA_7_8_OFFSET }, + { BFD_RELOC_V850_TDA_7_7_OFFSET, R_V850_TDA_7_7_OFFSET }, + { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET }, + { BFD_RELOC_V850_TDA_4_5_OFFSET, R_V850_TDA_4_5_OFFSET }, + { BFD_RELOC_V850_TDA_4_4_OFFSET, R_V850_TDA_4_4_OFFSET }, + { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_OFFSET }, + { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET }, + { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET }, + { BFD_RELOC_V850_CALLT_6_7_OFFSET, R_V850_CALLT_6_7_OFFSET }, + { BFD_RELOC_V850_CALLT_16_16_OFFSET, R_V850_CALLT_16_16_OFFSET }, + { BFD_RELOC_VTABLE_INHERIT, R_V850_GNU_VTINHERIT }, + { BFD_RELOC_VTABLE_ENTRY, R_V850_GNU_VTENTRY }, + { BFD_RELOC_V850_LONGCALL, R_V850_LONGCALL }, + { BFD_RELOC_V850_LONGJUMP, R_V850_LONGJUMP }, + { BFD_RELOC_V850_ALIGN, R_V850_ALIGN }, + +}; + +/* Map a bfd relocation into the appropriate howto structure. */ + +static reloc_howto_type * +v850_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;) + if (v850_elf_reloc_map[i].bfd_reloc_val == code) + { + unsigned int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val; + + BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val); + + return v850_elf_howto_table + elf_reloc_val; + } + + return NULL; +} + +/* Set the howto pointer for an V850 ELF reloc. */ + +static void +v850_elf_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) +{ + unsigned int r_type; + + r_type = ELF32_R_TYPE (dst->r_info); + BFD_ASSERT (r_type < (unsigned int) R_V850_max); + cache_ptr->howto = &v850_elf_howto_table[r_type]; +} + +/* Set the howto pointer for a V850 ELF reloc (type RELA). */ + +static void +v850_elf_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr, + Elf_Internal_Rela *dst) +{ + unsigned int r_type; + + r_type = ELF32_R_TYPE (dst->r_info); + BFD_ASSERT (r_type < (unsigned int) R_V850_max); + cache_ptr->howto = &v850_elf_howto_table[r_type]; +} static bfd_boolean -v850_elf_is_local_label_name (abfd, name) - bfd *abfd ATTRIBUTE_UNUSED; - const char *name; +v850_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name) { return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.')) || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')); @@ -1459,20 +1381,17 @@ v850_elf_is_local_label_name (abfd, name) /* Perform a relocation as part of a final link. */ static bfd_reloc_status_type -v850_elf_final_link_relocate (howto, input_bfd, output_bfd, - input_section, contents, offset, value, - addend, info, sym_sec, is_local) - reloc_howto_type *howto; - bfd *input_bfd; - bfd *output_bfd ATTRIBUTE_UNUSED; - asection *input_section; - bfd_byte *contents; - bfd_vma offset; - bfd_vma value; - bfd_vma addend; - struct bfd_link_info *info; - asection *sym_sec; - int is_local ATTRIBUTE_UNUSED; +v850_elf_final_link_relocate (reloc_howto_type *howto, + bfd *input_bfd, + bfd *output_bfd ATTRIBUTE_UNUSED, + asection *input_section, + bfd_byte *contents, + bfd_vma offset, + bfd_vma value, + bfd_vma addend, + struct bfd_link_info *info, + asection *sym_sec, + int is_local ATTRIBUTE_UNUSED) { unsigned int r_type = howto->type; bfd_byte *hit_data = contents + offset; @@ -1495,7 +1414,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, if (((value & 0xff000000) != 0x0) && ((value & 0xff000000) != 0xff000000)) return bfd_reloc_overflow; - /* Only the bottom 24 bits of the PC are valid */ + /* Only the bottom 24 bits of the PC are valid. */ value = SEXT24 (value); break; @@ -1535,7 +1454,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, /* Get the value of __gp. */ h = bfd_link_hash_lookup (info->hash, "__gp", FALSE, FALSE, TRUE); - if (h == (struct bfd_link_hash_entry *) NULL + if (h == NULL || h->type != bfd_link_hash_defined) return bfd_reloc_gp_not_found; @@ -1560,7 +1479,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, /* Get the value of __ep. */ h = bfd_link_hash_lookup (info->hash, "__ep", FALSE, FALSE, TRUE); - if (h == (struct bfd_link_hash_entry *) NULL + if (h == NULL || h->type != bfd_link_hash_defined) return bfd_reloc_ep_not_found; @@ -1579,7 +1498,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, /* Get the value of __ctbp. */ h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE); - if (h == (struct bfd_link_hash_entry *) NULL + if (h == NULL || h->type != bfd_link_hash_defined) return bfd_reloc_ctbp_not_found; @@ -1600,7 +1519,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, /* Get the value of __ctbp. */ h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE); - if (h == (struct bfd_link_hash_entry *) NULL + if (h == NULL || h->type != bfd_link_hash_defined) return bfd_reloc_ctbp_not_found; @@ -1632,16 +1551,14 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, /* Relocate an V850 ELF section. */ static bfd_boolean -v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +v850_elf_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1694,9 +1611,9 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, { bfd_boolean unresolved_reloc, warned; - /* Note - this check is delayed until now as it is possible and valid - to have a file without any symbols but with relocs that can be - processed. */ + /* Note - this check is delayed until now as it is possible and + valid to have a file without any symbols but with relocs that + can be processed. */ if (sym_hashes == NULL) { info->callbacks->warning @@ -1722,7 +1639,7 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (r != bfd_reloc_ok) { const char * name; - const char * msg = (const char *)0; + const char * msg = NULL; if (h != NULL) name = h->root.root.string; @@ -1793,23 +1710,21 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, } static bfd_boolean -v850_elf_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - asection *sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; +v850_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) { /* No got and plt entries for v850-elf. */ return TRUE; } static asection * -v850_elf_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +v850_elf_gc_mark_hook (asection *sec, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { if (h != NULL) { @@ -1843,8 +1758,7 @@ v850_elf_gc_mark_hook (sec, info, rel, h, sym) /* Set the right machine number. */ static bfd_boolean -v850_elf_object_p (abfd) - bfd *abfd; +v850_elf_object_p (bfd *abfd) { switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH) { @@ -1865,18 +1779,17 @@ v850_elf_object_p (abfd) /* Store the machine number in the flags field. */ static void -v850_elf_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +v850_elf_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { unsigned long val; switch (bfd_get_mach (abfd)) { default: - case bfd_mach_v850: val = E_V850_ARCH; break; - case bfd_mach_v850e: val = E_V850E_ARCH; break; - case bfd_mach_v850e1: val = E_V850E1_ARCH; break; + case bfd_mach_v850: val = E_V850_ARCH; break; + case bfd_mach_v850e: val = E_V850E_ARCH; break; + case bfd_mach_v850e1: val = E_V850E1_ARCH; break; } elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH; @@ -1886,9 +1799,7 @@ v850_elf_final_write_processing (abfd, linker) /* Function to keep V850 specific file flags. */ static bfd_boolean -v850_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; +v850_elf_set_private_flags (bfd *abfd, flagword flags) { BFD_ASSERT (!elf_flags_init (abfd) || elf_elfheader (abfd)->e_flags == flags); @@ -1900,10 +1811,9 @@ v850_elf_set_private_flags (abfd, flags) /* Merge backend specific data from an object file to the output object file when linking. */ + static bfd_boolean -v850_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +v850_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { flagword out_flags; flagword in_flags; @@ -1967,9 +1877,7 @@ v850_elf_merge_private_bfd_data (ibfd, obfd) /* Display the flags field. */ static bfd_boolean -v850_elf_print_private_bfd_data (abfd, ptr) - bfd *abfd; - PTR ptr; +v850_elf_print_private_bfd_data (bfd *abfd, void * ptr) { FILE * file = (FILE *) ptr; @@ -1984,7 +1892,7 @@ v850_elf_print_private_bfd_data (abfd, ptr) { default: case E_V850_ARCH: fprintf (file, _("v850 architecture")); break; - case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break; + case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break; case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break; } @@ -2014,10 +1922,9 @@ static asymbol * v850_elf_zcom_symbol_ptr; corresponding ELF section index. */ static bfd_boolean -v850_elf_section_from_bfd_section (abfd, sec, retval) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - int *retval; +v850_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + int *retval) { if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0) *retval = SHN_V850_SCOMMON; @@ -2034,9 +1941,7 @@ v850_elf_section_from_bfd_section (abfd, sec, retval) /* Handle the special V850 section numbers that a symbol may use. */ static void -v850_elf_symbol_processing (abfd, asym) - bfd *abfd; - asymbol *asym; +v850_elf_symbol_processing (bfd *abfd, asymbol *asym) { elf_symbol_type * elfsym = (elf_symbol_type *) asym; unsigned int indx; @@ -2130,14 +2035,13 @@ v850_elf_symbol_processing (abfd, asym) file. We must handle the special v850 section numbers here. */ static bfd_boolean -v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Sym *sym; - const char **namep ATTRIBUTE_UNUSED; - flagword *flagsp ATTRIBUTE_UNUSED; - asection **secp; - bfd_vma *valp; +v850_elf_add_symbol_hook (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Sym *sym, + const char **namep ATTRIBUTE_UNUSED, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp, + bfd_vma *valp) { unsigned int indx = sym->st_shndx; @@ -2191,12 +2095,11 @@ v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) } static bfd_boolean -v850_elf_link_output_symbol_hook (info, name, sym, input_sec, h) - struct bfd_link_info *info ATTRIBUTE_UNUSED; - const char *name ATTRIBUTE_UNUSED; - Elf_Internal_Sym *sym; - asection *input_sec; - struct elf_link_hash_entry *h ATTRIBUTE_UNUSED; +v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED, + Elf_Internal_Sym *sym, + asection *input_sec, + struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) { /* If we see a common symbol, which implies a relocatable link, then if a symbol was in a special common section in an input file, mark @@ -2247,23 +2150,18 @@ v850_elf_section_from_shdr (bfd *abfd, by the section name, which is a hack, but ought to work. */ static bfd_boolean -v850_elf_fake_sections (abfd, hdr, sec) - bfd *abfd ATTRIBUTE_UNUSED; - Elf_Internal_Shdr *hdr; - asection *sec; +v850_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *hdr, + asection *sec) { - register const char * name; + const char * name; name = bfd_get_section_name (abfd, sec); if (strcmp (name, ".scommon") == 0) - { - hdr->sh_type = SHT_V850_SCOMMON; - } + hdr->sh_type = SHT_V850_SCOMMON; else if (strcmp (name, ".tcommon") == 0) - { - hdr->sh_type = SHT_V850_TCOMMON; - } + hdr->sh_type = SHT_V850_TCOMMON; else if (strcmp (name, ".zcommon") == 0) hdr->sh_type = SHT_V850_ZCOMMON; @@ -2273,12 +2171,11 @@ v850_elf_fake_sections (abfd, hdr, sec) /* Delete some bytes from a section while relaxing. */ static bfd_boolean -v850_elf_relax_delete_bytes (abfd, sec, addr, toaddr, count) - bfd *abfd; - asection *sec; - bfd_vma addr; - bfd_vma toaddr; - int count; +v850_elf_relax_delete_bytes (bfd *abfd, + asection *sec, + bfd_vma addr, + bfd_vma toaddr, + int count) { Elf_Internal_Shdr *symtab_hdr; Elf32_External_Sym *extsyms; @@ -2499,11 +2396,10 @@ v850_elf_relax_delete_bytes (abfd, sec, addr, toaddr, count) #define JMP_R1(insn) ((insn) & 0x1f) static bfd_boolean -v850_elf_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - bfd_boolean *again; +v850_elf_relax_section (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + bfd_boolean *again) { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *internal_relocs; @@ -2527,8 +2423,7 @@ v850_elf_relax_section (abfd, sec, link_info, again) symtab_hdr = & elf_tdata (abfd)->symtab_hdr; internal_relocs = (_bfd_elf_link_read_relocs - (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL, - link_info->keep_memory)); + (abfd, sec, NULL, NULL, link_info->keep_memory)); if (internal_relocs == NULL) goto error_return; @@ -2610,7 +2505,7 @@ v850_elf_relax_section (abfd, sec, link_info, again) contents = elf_section_data (sec)->this_hdr.contents; else { - if (!bfd_malloc_and_get_section (abfd, sec, &contents)) + if (! bfd_malloc_and_get_section (abfd, sec, &contents)) goto error_return; } } diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c index d8c4e116e75..1341a4405ec 100644 --- a/bfd/elf32-xstormy16.c +++ b/bfd/elf32-xstormy16.c @@ -1,21 +1,22 @@ -/* XSTORMY16-specific support for 32-bit ELF. - Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Xstormy16-specific support for 32-bit ELF. + Copyright 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, + USA. */ #include "bfd.h" #include "sysdep.h" @@ -24,38 +25,48 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. #include "elf/xstormy16.h" #include "libiberty.h" -/* Forward declarations. */ -static reloc_howto_type * xstormy16_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void xstormy16_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static bfd_reloc_status_type xstormy16_elf_24_reloc - PARAMS ((bfd *abfd, arelent *reloc_entry, asymbol *symbol, - PTR data, asection *input_section, bfd *output_bfd, - char **error_message)); -static bfd_boolean xstormy16_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean xstormy16_relax_plt_check - PARAMS ((struct elf_link_hash_entry *, PTR)); -static bfd_boolean xstormy16_relax_plt_realloc - PARAMS ((struct elf_link_hash_entry *, PTR)); -static bfd_boolean xstormy16_elf_relax_section - PARAMS ((bfd *abfd, asection *sec, struct bfd_link_info *link_info, - bfd_boolean *again)); -static bfd_boolean xstormy16_elf_always_size_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean xstormy16_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_boolean xstormy16_elf_finish_dynamic_sections - PARAMS((bfd *, struct bfd_link_info *)); -static bfd_boolean xstormy16_elf_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static asection * xstormy16_elf_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); +/* Handle the R_XSTORMY16_24 reloc, which has an odd bit arrangement. */ + +static bfd_reloc_status_type +xstormy16_elf_24_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void * data, + asection *input_section, + bfd *output_bfd, + char **error_message ATTRIBUTE_UNUSED) +{ + bfd_vma relocation, x; + + if (output_bfd != NULL) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + return bfd_reloc_outofrange; + + if (bfd_is_com_section (symbol->section)) + relocation = 0; + else + relocation = symbol->value; + + relocation += symbol->section->output_section->vma; + relocation += symbol->section->output_offset; + relocation += reloc_entry->addend; + + x = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); + x &= 0x0000ff00; + x |= relocation & 0xff; + x |= (relocation << 8) & 0xffff0000; + bfd_put_32 (abfd, x, (bfd_byte *) data + reloc_entry->address); + + if (relocation & ~ (bfd_vma) 0xffffff) + return bfd_reloc_overflow; + + return bfd_reloc_ok; +} static reloc_howto_type xstormy16_elf_howto_table [] = { @@ -238,7 +249,7 @@ static reloc_howto_type xstormy16_elf_howto_table [] = 0, /* src_mask */ 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ - + /* A 12 bit absolute relocation. */ HOWTO (R_XSTORMY16_12, /* type */ 0, /* rightshift */ @@ -318,9 +329,8 @@ static const reloc_map xstormy16_reloc_map [] = }; static reloc_howto_type * -xstormy16_reloc_type_lookup (abfd, code) - bfd * abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +xstormy16_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; @@ -341,10 +351,9 @@ xstormy16_reloc_type_lookup (abfd, code) /* Set the howto pointer for an XSTORMY16 ELF reloc. */ static void -xstormy16_info_to_howto_rela (abfd, cache_ptr, dst) - bfd * abfd ATTRIBUTE_UNUSED; - arelent * cache_ptr; - Elf_Internal_Rela * dst; +xstormy16_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED, + arelent * cache_ptr, + Elf_Internal_Rela * dst) { unsigned int r_type = ELF32_R_TYPE (dst->r_info); @@ -357,51 +366,6 @@ xstormy16_info_to_howto_rela (abfd, cache_ptr, dst) else abort (); } - -/* Handle the R_XSTORMY16_24 reloc, which has an odd bit arrangement. */ - -static bfd_reloc_status_type -xstormy16_elf_24_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; -{ - bfd_vma relocation, x; - - if (output_bfd != NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - x = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - x &= 0x0000ff00; - x |= relocation & 0xff; - x |= (relocation << 8) & 0xffff0000; - bfd_put_32 (abfd, x, (bfd_byte *) data + reloc_entry->address); - - if (relocation & ~ (bfd_vma) 0xffffff) - return bfd_reloc_overflow; - - return bfd_reloc_ok; -} /* We support 16-bit pointers to code above 64k by generating a thunk below 64k containing a JMPF instruction to the final address. We @@ -410,11 +374,10 @@ xstormy16_elf_24_reloc (abfd, reloc_entry, symbol, data, input_section, sections will fall in the address space. */ static bfd_boolean -xstormy16_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +xstormy16_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { const Elf_Internal_Rela *rel, *relend; struct elf_link_hash_entry **sym_hashes; @@ -495,7 +458,7 @@ xstormy16_elf_check_relocs (abfd, info, sec, relocs) unsigned int i; size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size); + local_plt_offsets = bfd_alloc (abfd, size); if (local_plt_offsets == NULL) return FALSE; elf_local_got_offsets (abfd) = local_plt_offsets; @@ -542,9 +505,7 @@ struct relax_plt_data }; static bfd_boolean -xstormy16_relax_plt_check (h, xdata) - struct elf_link_hash_entry *h; - PTR xdata; +xstormy16_relax_plt_check (struct elf_link_hash_entry *h, void * xdata) { struct relax_plt_data *data = (struct relax_plt_data *) xdata; @@ -578,9 +539,7 @@ xstormy16_relax_plt_check (h, xdata) previously had a plt entry, give it a new entry offset. */ static bfd_boolean -xstormy16_relax_plt_realloc (h, xdata) - struct elf_link_hash_entry *h; - PTR xdata; +xstormy16_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata) { bfd_vma *entry = (bfd_vma *) xdata; @@ -597,11 +556,10 @@ xstormy16_relax_plt_realloc (h, xdata) } static bfd_boolean -xstormy16_elf_relax_section (dynobj, splt, info, again) - bfd *dynobj; - asection *splt; - struct bfd_link_info *info; - bfd_boolean *again; +xstormy16_elf_relax_section (bfd *dynobj, + asection *splt, + struct bfd_link_info *info, + bfd_boolean *again) { struct relax_plt_data relax_plt_data; bfd *ibfd; @@ -726,9 +684,8 @@ xstormy16_elf_relax_section (dynobj, splt, info, again) } static bfd_boolean -xstormy16_elf_always_size_sections (output_bfd, info) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +xstormy16_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { bfd *dynobj; asection *splt; @@ -743,7 +700,7 @@ xstormy16_elf_always_size_sections (output_bfd, info) splt = bfd_get_section_by_name (dynobj, ".plt"); BFD_ASSERT (splt != NULL); - splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size); + splt->contents = bfd_zalloc (dynobj, splt->size); if (splt->contents == NULL) return FALSE; @@ -781,16 +738,14 @@ xstormy16_elf_always_size_sections (output_bfd, info) accordingly. */ static bfd_boolean -xstormy16_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd * output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info * info; - bfd * input_bfd; - asection * input_section; - bfd_byte * contents; - Elf_Internal_Rela * relocs; - Elf_Internal_Sym * local_syms; - asection ** local_sections; +xstormy16_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info * info, + bfd * input_bfd, + asection * input_section, + bfd_byte * contents, + Elf_Internal_Rela * relocs, + Elf_Internal_Sym * local_syms, + asection ** local_sections) { Elf_Internal_Shdr * symtab_hdr; struct elf_link_hash_entry ** sym_hashes; @@ -934,7 +889,7 @@ xstormy16_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (r != bfd_reloc_ok) { - const char * msg = (const char *) NULL; + const char * msg = NULL; switch (r) { @@ -982,9 +937,8 @@ xstormy16_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* This must exist if dynobj is ever set. */ static bfd_boolean -xstormy16_elf_finish_dynamic_sections (abfd, info) - bfd *abfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +xstormy16_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { bfd *dynobj; asection *splt; @@ -997,9 +951,11 @@ xstormy16_elf_finish_dynamic_sections (abfd, info) { bfd_byte *contents = splt->contents; unsigned int i, size = splt->size; + for (i = 0; i < size; i += 4) { unsigned int x = bfd_get_32 (dynobj, contents + i); + BFD_ASSERT (x != 0); } } @@ -1011,12 +967,11 @@ xstormy16_elf_finish_dynamic_sections (abfd, info) relocation. */ static asection * -xstormy16_elf_gc_mark_hook (sec, info, rel, h, sym) - asection * sec; - struct bfd_link_info * info ATTRIBUTE_UNUSED; - Elf_Internal_Rela * rel; - struct elf_link_hash_entry * h; - Elf_Internal_Sym * sym; +xstormy16_elf_gc_mark_hook (asection * sec, + struct bfd_link_info * info ATTRIBUTE_UNUSED, + Elf_Internal_Rela * rel, + struct elf_link_hash_entry * h, + Elf_Internal_Sym * sym) { if (h != NULL) { @@ -1050,11 +1005,10 @@ xstormy16_elf_gc_mark_hook (sec, info, rel, h, sym) /* Update the got entry reference counts for the section being removed. */ static bfd_boolean -xstormy16_elf_gc_sweep_hook (abfd, info, sec, relocs) - bfd * abfd ATTRIBUTE_UNUSED; - struct bfd_link_info * info ATTRIBUTE_UNUSED; - asection * sec ATTRIBUTE_UNUSED; - const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED; +xstormy16_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED, + struct bfd_link_info * info ATTRIBUTE_UNUSED, + asection * sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED) { return TRUE; } |