Home | History | Annotate | Line # | Download | only in bfd
elf32-cr16.c revision 1.6
      1  1.1  christos /* BFD back-end for National Semiconductor's CR16 ELF
      2  1.6  christos    Copyright (C) 2007-2018 Free Software Foundation, Inc.
      3  1.1  christos    Written by M R Swami Reddy.
      4  1.1  christos 
      5  1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program; if not, write to the Free Software Foundation,
     19  1.1  christos    Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
     20  1.1  christos 
     21  1.1  christos #include "sysdep.h"
     22  1.1  christos #include "bfd.h"
     23  1.1  christos #include "bfdlink.h"
     24  1.1  christos #include "libbfd.h"
     25  1.1  christos #include "libiberty.h"
     26  1.1  christos #include "elf-bfd.h"
     27  1.1  christos #include "elf/cr16.h"
     28  1.1  christos 
     29  1.1  christos /* The cr16 linker needs to keep track of the number of relocs that
     30  1.1  christos    it decides to copy in check_relocs for each symbol.  This is so
     31  1.1  christos    that it can discard PC relative relocs if it doesn't need them when
     32  1.1  christos    linking with -Bsymbolic.  We store the information in a field
     33  1.1  christos    extending the regular ELF linker hash table.  */
     34  1.1  christos 
     35  1.1  christos struct elf32_cr16_link_hash_entry
     36  1.1  christos {
     37  1.1  christos   /* The basic elf link hash table entry.  */
     38  1.1  christos   struct elf_link_hash_entry root;
     39  1.1  christos 
     40  1.1  christos   /* For function symbols, the number of times this function is
     41  1.1  christos      called directly (ie by name).  */
     42  1.1  christos   unsigned int direct_calls;
     43  1.1  christos 
     44  1.1  christos   /* For function symbols, the size of this function's stack
     45  1.1  christos      (if <= 255 bytes).  We stuff this into "call" instructions
     46  1.1  christos      to this target when it's valid and profitable to do so.
     47  1.1  christos 
     48  1.1  christos      This does not include stack allocated by movm!  */
     49  1.1  christos   unsigned char stack_size;
     50  1.1  christos 
     51  1.1  christos   /* For function symbols, arguments (if any) for movm instruction
     52  1.1  christos      in the prologue.  We stuff this value into "call" instructions
     53  1.1  christos      to the target when it's valid and profitable to do so.  */
     54  1.1  christos   unsigned char movm_args;
     55  1.1  christos 
     56  1.1  christos   /* For function symbols, the amount of stack space that would be allocated
     57  1.1  christos      by the movm instruction.  This is redundant with movm_args, but we
     58  1.1  christos      add it to the hash table to avoid computing it over and over.  */
     59  1.1  christos   unsigned char movm_stack_size;
     60  1.1  christos 
     61  1.1  christos /* Used to mark functions which have had redundant parts of their
     62  1.1  christos    prologue deleted.  */
     63  1.1  christos #define CR16_DELETED_PROLOGUE_BYTES 0x1
     64  1.1  christos   unsigned char flags;
     65  1.1  christos 
     66  1.1  christos   /* Calculated value.  */
     67  1.1  christos   bfd_vma value;
     68  1.1  christos };
     69  1.1  christos 
     70  1.1  christos /* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type.  */
     71  1.1  christos 
     72  1.1  christos struct cr16_reloc_map
     73  1.1  christos {
     74  1.1  christos   bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum.  */
     75  1.6  christos   unsigned short cr16_reloc_type;	   /* CR16 relocation type.  */
     76  1.1  christos };
     77  1.1  christos 
     78  1.1  christos static const struct cr16_reloc_map cr16_reloc_map[R_CR16_MAX] =
     79  1.1  christos {
     80  1.6  christos   {BFD_RELOC_NONE,	     R_CR16_NONE},
     81  1.6  christos   {BFD_RELOC_CR16_NUM8,	     R_CR16_NUM8},
     82  1.1  christos   {BFD_RELOC_CR16_NUM16,     R_CR16_NUM16},
     83  1.1  christos   {BFD_RELOC_CR16_NUM32,     R_CR16_NUM32},
     84  1.1  christos   {BFD_RELOC_CR16_NUM32a,    R_CR16_NUM32a},
     85  1.1  christos   {BFD_RELOC_CR16_REGREL4,   R_CR16_REGREL4},
     86  1.1  christos   {BFD_RELOC_CR16_REGREL4a,  R_CR16_REGREL4a},
     87  1.1  christos   {BFD_RELOC_CR16_REGREL14,  R_CR16_REGREL14},
     88  1.1  christos   {BFD_RELOC_CR16_REGREL14a, R_CR16_REGREL14a},
     89  1.1  christos   {BFD_RELOC_CR16_REGREL16,  R_CR16_REGREL16},
     90  1.1  christos   {BFD_RELOC_CR16_REGREL20,  R_CR16_REGREL20},
     91  1.1  christos   {BFD_RELOC_CR16_REGREL20a, R_CR16_REGREL20a},
     92  1.1  christos   {BFD_RELOC_CR16_ABS20,     R_CR16_ABS20},
     93  1.1  christos   {BFD_RELOC_CR16_ABS24,     R_CR16_ABS24},
     94  1.6  christos   {BFD_RELOC_CR16_IMM4,	     R_CR16_IMM4},
     95  1.6  christos   {BFD_RELOC_CR16_IMM8,	     R_CR16_IMM8},
     96  1.1  christos   {BFD_RELOC_CR16_IMM16,     R_CR16_IMM16},
     97  1.1  christos   {BFD_RELOC_CR16_IMM20,     R_CR16_IMM20},
     98  1.1  christos   {BFD_RELOC_CR16_IMM24,     R_CR16_IMM24},
     99  1.1  christos   {BFD_RELOC_CR16_IMM32,     R_CR16_IMM32},
    100  1.1  christos   {BFD_RELOC_CR16_IMM32a,    R_CR16_IMM32a},
    101  1.1  christos   {BFD_RELOC_CR16_DISP4,     R_CR16_DISP4},
    102  1.1  christos   {BFD_RELOC_CR16_DISP8,     R_CR16_DISP8},
    103  1.1  christos   {BFD_RELOC_CR16_DISP16,    R_CR16_DISP16},
    104  1.1  christos   {BFD_RELOC_CR16_DISP24,    R_CR16_DISP24},
    105  1.1  christos   {BFD_RELOC_CR16_DISP24a,   R_CR16_DISP24a},
    106  1.1  christos   {BFD_RELOC_CR16_SWITCH8,   R_CR16_SWITCH8},
    107  1.1  christos   {BFD_RELOC_CR16_SWITCH16,  R_CR16_SWITCH16},
    108  1.1  christos   {BFD_RELOC_CR16_SWITCH32,  R_CR16_SWITCH32},
    109  1.1  christos   {BFD_RELOC_CR16_GOT_REGREL20, R_CR16_GOT_REGREL20},
    110  1.1  christos   {BFD_RELOC_CR16_GOTC_REGREL20, R_CR16_GOTC_REGREL20},
    111  1.1  christos   {BFD_RELOC_CR16_GLOB_DAT,  R_CR16_GLOB_DAT}
    112  1.1  christos };
    113  1.1  christos 
    114  1.1  christos static reloc_howto_type cr16_elf_howto_table[] =
    115  1.1  christos {
    116  1.6  christos   HOWTO (R_CR16_NONE,		   /* type */
    117  1.6  christos 	 0,			   /* rightshift */
    118  1.6  christos 	 3,			   /* size */
    119  1.6  christos 	 0,			   /* bitsize */
    120  1.6  christos 	 FALSE,			   /* pc_relative */
    121  1.6  christos 	 0,			   /* bitpos */
    122  1.6  christos 	 complain_overflow_dont,   /* complain_on_overflow */
    123  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    124  1.6  christos 	 "R_CR16_NONE",		   /* name */
    125  1.6  christos 	 FALSE,			   /* partial_inplace */
    126  1.6  christos 	 0,			   /* src_mask */
    127  1.6  christos 	 0,			   /* dst_mask */
    128  1.6  christos 	 FALSE),		   /* pcrel_offset */
    129  1.6  christos 
    130  1.6  christos   HOWTO (R_CR16_NUM8,		   /* type */
    131  1.6  christos 	 0,			   /* rightshift */
    132  1.6  christos 	 0,			   /* size */
    133  1.6  christos 	 8,			   /* bitsize */
    134  1.6  christos 	 FALSE,			   /* pc_relative */
    135  1.6  christos 	 0,			   /* bitpos */
    136  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    137  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    138  1.6  christos 	 "R_CR16_NUM8",		   /* name */
    139  1.6  christos 	 FALSE,			   /* partial_inplace */
    140  1.6  christos 	 0x0,			   /* src_mask */
    141  1.6  christos 	 0xff,			   /* dst_mask */
    142  1.6  christos 	 FALSE),		   /* pcrel_offset */
    143  1.6  christos 
    144  1.6  christos   HOWTO (R_CR16_NUM16,		   /* type */
    145  1.6  christos 	 0,			   /* rightshift */
    146  1.6  christos 	 1,			   /* size */
    147  1.6  christos 	 16,			   /* bitsize */
    148  1.6  christos 	 FALSE,			   /* pc_relative */
    149  1.6  christos 	 0,			   /* bitpos */
    150  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    151  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    152  1.6  christos 	 "R_CR16_NUM16",	   /* name */
    153  1.6  christos 	 FALSE,			   /* partial_inplace */
    154  1.6  christos 	 0x0,			   /* src_mask */
    155  1.6  christos 	 0xffff,		   /* dst_mask */
    156  1.6  christos 	 FALSE),		   /* pcrel_offset */
    157  1.6  christos 
    158  1.6  christos   HOWTO (R_CR16_NUM32,		   /* type */
    159  1.6  christos 	 0,			   /* rightshift */
    160  1.6  christos 	 2,			   /* size */
    161  1.6  christos 	 32,			   /* bitsize */
    162  1.6  christos 	 FALSE,			   /* pc_relative */
    163  1.6  christos 	 0,			   /* bitpos */
    164  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    165  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    166  1.6  christos 	 "R_CR16_NUM32",	   /* name */
    167  1.6  christos 	 FALSE,			   /* partial_inplace */
    168  1.6  christos 	 0x0,			   /* src_mask */
    169  1.6  christos 	 0xffffffff,		   /* dst_mask */
    170  1.6  christos 	 FALSE),		   /* pcrel_offset */
    171  1.6  christos 
    172  1.6  christos   HOWTO (R_CR16_NUM32a,		   /* type */
    173  1.6  christos 	 1,			   /* rightshift */
    174  1.6  christos 	 2,			   /* size */
    175  1.6  christos 	 32,			   /* bitsize */
    176  1.6  christos 	 FALSE,			   /* pc_relative */
    177  1.6  christos 	 0,			   /* bitpos */
    178  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    179  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    180  1.6  christos 	 "R_CR16_NUM32a",	   /* name */
    181  1.6  christos 	 FALSE,			   /* partial_inplace */
    182  1.6  christos 	 0x0,			   /* src_mask */
    183  1.6  christos 	 0xffffffff,		   /* dst_mask */
    184  1.6  christos 	 FALSE),		   /* pcrel_offset */
    185  1.6  christos 
    186  1.6  christos   HOWTO (R_CR16_REGREL4,	   /* type */
    187  1.6  christos 	 0,			   /* rightshift */
    188  1.6  christos 	 0,			   /* size */
    189  1.6  christos 	 4,			   /* bitsize */
    190  1.6  christos 	 FALSE,			   /* pc_relative */
    191  1.6  christos 	 0,			   /* bitpos */
    192  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    193  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    194  1.6  christos 	 "R_CR16_REGREL4",	   /* name */
    195  1.6  christos 	 FALSE,			   /* partial_inplace */
    196  1.6  christos 	 0x0,			   /* src_mask */
    197  1.6  christos 	 0xf,			   /* dst_mask */
    198  1.6  christos 	 FALSE),		   /* pcrel_offset */
    199  1.6  christos 
    200  1.6  christos   HOWTO (R_CR16_REGREL4a,	   /* type */
    201  1.6  christos 	 0,			   /* rightshift */
    202  1.6  christos 	 0,			   /* size */
    203  1.6  christos 	 4,			   /* bitsize */
    204  1.6  christos 	 FALSE,			   /* pc_relative */
    205  1.6  christos 	 0,			   /* bitpos */
    206  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    207  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    208  1.6  christos 	 "R_CR16_REGREL4a",	   /* name */
    209  1.6  christos 	 FALSE,			   /* partial_inplace */
    210  1.6  christos 	 0x0,			   /* src_mask */
    211  1.6  christos 	 0xf,			   /* dst_mask */
    212  1.6  christos 	 FALSE),		   /* pcrel_offset */
    213  1.6  christos 
    214  1.6  christos   HOWTO (R_CR16_REGREL14,	   /* type */
    215  1.6  christos 	 0,			   /* rightshift */
    216  1.6  christos 	 1,			   /* size */
    217  1.6  christos 	 14,			   /* bitsize */
    218  1.6  christos 	 FALSE,			   /* pc_relative */
    219  1.6  christos 	 0,			   /* bitpos */
    220  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    221  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    222  1.6  christos 	 "R_CR16_REGREL14",	   /* name */
    223  1.6  christos 	 FALSE,			   /* partial_inplace */
    224  1.6  christos 	 0x0,			   /* src_mask */
    225  1.6  christos 	 0x3fff,		   /* dst_mask */
    226  1.6  christos 	 FALSE),		   /* pcrel_offset */
    227  1.6  christos 
    228  1.6  christos   HOWTO (R_CR16_REGREL14a,	   /* type */
    229  1.6  christos 	 0,			   /* rightshift */
    230  1.6  christos 	 1,			   /* size */
    231  1.6  christos 	 14,			   /* bitsize */
    232  1.6  christos 	 FALSE,			   /* pc_relative */
    233  1.6  christos 	 0,			   /* bitpos */
    234  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    235  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    236  1.6  christos 	 "R_CR16_REGREL14a",	   /* name */
    237  1.6  christos 	 FALSE,			   /* partial_inplace */
    238  1.6  christos 	 0x0,			   /* src_mask */
    239  1.6  christos 	 0x3fff,		   /* dst_mask */
    240  1.6  christos 	 FALSE),		   /* pcrel_offset */
    241  1.6  christos 
    242  1.6  christos   HOWTO (R_CR16_REGREL16,	   /* type */
    243  1.6  christos 	 0,			   /* rightshift */
    244  1.6  christos 	 1,			   /* size */
    245  1.6  christos 	 16,			   /* bitsize */
    246  1.6  christos 	 FALSE,			   /* pc_relative */
    247  1.6  christos 	 0,			   /* bitpos */
    248  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    249  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    250  1.6  christos 	 "R_CR16_REGREL16",	   /* name */
    251  1.6  christos 	 FALSE,			   /* partial_inplace */
    252  1.6  christos 	 0x0,			   /* src_mask */
    253  1.6  christos 	 0xffff,		   /* dst_mask */
    254  1.6  christos 	 FALSE),		   /* pcrel_offset */
    255  1.6  christos 
    256  1.6  christos   HOWTO (R_CR16_REGREL20,	   /* type */
    257  1.6  christos 	 0,			   /* rightshift */
    258  1.6  christos 	 2,			   /* size */
    259  1.6  christos 	 20,			   /* bitsize */
    260  1.6  christos 	 FALSE,			   /* pc_relative */
    261  1.6  christos 	 0,			   /* bitpos */
    262  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    263  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    264  1.6  christos 	 "R_CR16_REGREL20",	   /* name */
    265  1.6  christos 	 FALSE,			   /* partial_inplace */
    266  1.6  christos 	 0x0,			   /* src_mask */
    267  1.6  christos 	 0xfffff,		   /* dst_mask */
    268  1.6  christos 	 FALSE),		   /* pcrel_offset */
    269  1.6  christos 
    270  1.6  christos   HOWTO (R_CR16_REGREL20a,	   /* type */
    271  1.6  christos 	 0,			   /* rightshift */
    272  1.6  christos 	 2,			   /* size */
    273  1.6  christos 	 20,			   /* bitsize */
    274  1.6  christos 	 FALSE,			   /* pc_relative */
    275  1.6  christos 	 0,			   /* bitpos */
    276  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    277  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    278  1.6  christos 	 "R_CR16_REGREL20a",	   /* name */
    279  1.6  christos 	 FALSE,			   /* partial_inplace */
    280  1.6  christos 	 0x0,			   /* src_mask */
    281  1.6  christos 	 0xfffff,		   /* dst_mask */
    282  1.6  christos 	 FALSE),		   /* pcrel_offset */
    283  1.6  christos 
    284  1.6  christos   HOWTO (R_CR16_ABS20,		   /* type */
    285  1.6  christos 	 0,			   /* rightshift */
    286  1.6  christos 	 2,			   /* size */
    287  1.6  christos 	 20,			   /* bitsize */
    288  1.6  christos 	 FALSE,			   /* pc_relative */
    289  1.6  christos 	 0,			   /* bitpos */
    290  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    291  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    292  1.6  christos 	 "R_CR16_ABS20",	   /* name */
    293  1.6  christos 	 FALSE,			   /* partial_inplace */
    294  1.6  christos 	 0x0,			   /* src_mask */
    295  1.6  christos 	 0xfffff,		   /* dst_mask */
    296  1.6  christos 	 FALSE),		   /* pcrel_offset */
    297  1.6  christos 
    298  1.6  christos   HOWTO (R_CR16_ABS24,		   /* type */
    299  1.6  christos 	 0,			   /* rightshift */
    300  1.6  christos 	 2,			   /* size */
    301  1.6  christos 	 24,			   /* bitsize */
    302  1.6  christos 	 FALSE,			   /* pc_relative */
    303  1.6  christos 	 0,			   /* bitpos */
    304  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    305  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    306  1.6  christos 	 "R_CR16_ABS24",	   /* name */
    307  1.6  christos 	 FALSE,			   /* partial_inplace */
    308  1.6  christos 	 0x0,			   /* src_mask */
    309  1.6  christos 	 0xffffff,		   /* dst_mask */
    310  1.6  christos 	 FALSE),		   /* pcrel_offset */
    311  1.6  christos 
    312  1.6  christos   HOWTO (R_CR16_IMM4,		   /* type */
    313  1.6  christos 	 0,			   /* rightshift */
    314  1.6  christos 	 0,			   /* size */
    315  1.6  christos 	 4,			   /* bitsize */
    316  1.6  christos 	 FALSE,			   /* pc_relative */
    317  1.6  christos 	 0,			   /* bitpos */
    318  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    319  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    320  1.6  christos 	 "R_CR16_IMM4",		   /* name */
    321  1.6  christos 	 FALSE,			   /* partial_inplace */
    322  1.6  christos 	 0x0,			   /* src_mask */
    323  1.6  christos 	 0xf,			   /* dst_mask */
    324  1.6  christos 	 FALSE),		   /* pcrel_offset */
    325  1.6  christos 
    326  1.6  christos   HOWTO (R_CR16_IMM8,		   /* type */
    327  1.6  christos 	 0,			   /* rightshift */
    328  1.6  christos 	 0,			   /* size */
    329  1.6  christos 	 8,			   /* bitsize */
    330  1.6  christos 	 FALSE,			   /* pc_relative */
    331  1.6  christos 	 0,			   /* bitpos */
    332  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    333  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    334  1.6  christos 	 "R_CR16_IMM8",		   /* name */
    335  1.6  christos 	 FALSE,			   /* partial_inplace */
    336  1.6  christos 	 0x0,			   /* src_mask */
    337  1.6  christos 	 0xff,			   /* dst_mask */
    338  1.6  christos 	 FALSE),		   /* pcrel_offset */
    339  1.6  christos 
    340  1.6  christos   HOWTO (R_CR16_IMM16,		   /* type */
    341  1.6  christos 	 0,			   /* rightshift */
    342  1.6  christos 	 1,			   /* size */
    343  1.6  christos 	 16,			   /* bitsize */
    344  1.6  christos 	 FALSE,			   /* pc_relative */
    345  1.6  christos 	 0,			   /* bitpos */
    346  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    347  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    348  1.6  christos 	 "R_CR16_IMM16",	   /* name */
    349  1.6  christos 	 FALSE,			   /* partial_inplace */
    350  1.6  christos 	 0x0,			   /* src_mask */
    351  1.6  christos 	 0xffff,		   /* dst_mask */
    352  1.6  christos 	 FALSE),		   /* pcrel_offset */
    353  1.6  christos 
    354  1.6  christos   HOWTO (R_CR16_IMM20,		   /* type */
    355  1.6  christos 	 0,			   /* rightshift */
    356  1.6  christos 	 2,			   /* size */
    357  1.6  christos 	 20,			   /* bitsize */
    358  1.6  christos 	 FALSE,			   /* pc_relative */
    359  1.6  christos 	 0,			   /* bitpos */
    360  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    361  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    362  1.6  christos 	 "R_CR16_IMM20",	   /* name */
    363  1.6  christos 	 FALSE,			   /* partial_inplace */
    364  1.6  christos 	 0x0,			   /* src_mask */
    365  1.6  christos 	 0xfffff,		   /* dst_mask */
    366  1.6  christos 	 FALSE),		   /* pcrel_offset */
    367  1.6  christos 
    368  1.6  christos   HOWTO (R_CR16_IMM24,		   /* type */
    369  1.6  christos 	 0,			   /* rightshift */
    370  1.6  christos 	 2,			   /* size */
    371  1.6  christos 	 24,			   /* bitsize */
    372  1.6  christos 	 FALSE,			   /* pc_relative */
    373  1.6  christos 	 0,			   /* bitpos */
    374  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    375  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    376  1.6  christos 	 "R_CR16_IMM24",	   /* name */
    377  1.6  christos 	 FALSE,			   /* partial_inplace */
    378  1.6  christos 	 0x0,			   /* src_mask */
    379  1.6  christos 	 0xffffff,		   /* dst_mask */
    380  1.6  christos 	 FALSE),		   /* pcrel_offset */
    381  1.6  christos 
    382  1.6  christos   HOWTO (R_CR16_IMM32,		   /* type */
    383  1.6  christos 	 0,			   /* rightshift */
    384  1.6  christos 	 2,			   /* size */
    385  1.6  christos 	 32,			   /* bitsize */
    386  1.6  christos 	 FALSE,			   /* pc_relative */
    387  1.6  christos 	 0,			   /* bitpos */
    388  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    389  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    390  1.6  christos 	 "R_CR16_IMM32",	   /* name */
    391  1.6  christos 	 FALSE,			   /* partial_inplace */
    392  1.6  christos 	 0x0,			   /* src_mask */
    393  1.6  christos 	 0xffffffff,		   /* dst_mask */
    394  1.6  christos 	 FALSE),		   /* pcrel_offset */
    395  1.6  christos 
    396  1.6  christos   HOWTO (R_CR16_IMM32a,		   /* type */
    397  1.6  christos 	 1,			   /* rightshift */
    398  1.6  christos 	 2,			   /* size */
    399  1.6  christos 	 32,			   /* bitsize */
    400  1.6  christos 	 FALSE,			   /* pc_relative */
    401  1.6  christos 	 0,			   /* bitpos */
    402  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    403  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    404  1.6  christos 	 "R_CR16_IMM32a",	   /* name */
    405  1.6  christos 	 FALSE,			   /* partial_inplace */
    406  1.6  christos 	 0x0,			   /* src_mask */
    407  1.6  christos 	 0xffffffff,		   /* dst_mask */
    408  1.6  christos 	 FALSE),		   /* pcrel_offset */
    409  1.6  christos 
    410  1.6  christos   HOWTO (R_CR16_DISP4,		   /* type */
    411  1.6  christos 	 1,			   /* rightshift */
    412  1.6  christos 	 0,			   /* size (0 = byte, 1 = short, 2 = long) */
    413  1.6  christos 	 4,			   /* bitsize */
    414  1.6  christos 	 TRUE,			   /* pc_relative */
    415  1.6  christos 	 0,			   /* bitpos */
    416  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    417  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    418  1.6  christos 	 "R_CR16_DISP4",	   /* name */
    419  1.6  christos 	 FALSE,			   /* partial_inplace */
    420  1.6  christos 	 0x0,			   /* src_mask */
    421  1.6  christos 	 0xf,			   /* dst_mask */
    422  1.6  christos 	 FALSE),		   /* pcrel_offset */
    423  1.6  christos 
    424  1.6  christos   HOWTO (R_CR16_DISP8,		   /* type */
    425  1.6  christos 	 1,			   /* rightshift */
    426  1.6  christos 	 0,			   /* size (0 = byte, 1 = short, 2 = long) */
    427  1.6  christos 	 8,			   /* bitsize */
    428  1.6  christos 	 TRUE,			   /* pc_relative */
    429  1.6  christos 	 0,			   /* bitpos */
    430  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    431  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    432  1.6  christos 	 "R_CR16_DISP8",	   /* name */
    433  1.6  christos 	 FALSE,			   /* partial_inplace */
    434  1.6  christos 	 0x0,			   /* src_mask */
    435  1.6  christos 	 0x1ff,			   /* dst_mask */
    436  1.6  christos 	 FALSE),		   /* pcrel_offset */
    437  1.6  christos 
    438  1.6  christos   HOWTO (R_CR16_DISP16,		   /* type */
    439  1.6  christos 	 0,			   /* rightshift REVIITS: To sync with WinIDEA*/
    440  1.6  christos 	 1,			   /* size (0 = byte, 1 = short, 2 = long) */
    441  1.6  christos 	 16,			   /* bitsize */
    442  1.6  christos 	 TRUE,			   /* pc_relative */
    443  1.6  christos 	 0,			   /* bitpos */
    444  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    445  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    446  1.6  christos 	 "R_CR16_DISP16",	   /* name */
    447  1.6  christos 	 FALSE,			   /* partial_inplace */
    448  1.6  christos 	 0x0,			   /* src_mask */
    449  1.6  christos 	 0x1ffff,		   /* dst_mask */
    450  1.6  christos 	 FALSE),		   /* pcrel_offset */
    451  1.1  christos   /* REVISIT: DISP24 should be left-shift by 2 as per ISA doc
    452  1.1  christos      but its not done, to sync with WinIDEA and CR16 4.1 tools */
    453  1.6  christos   HOWTO (R_CR16_DISP24,		   /* type */
    454  1.6  christos 	 0,			   /* rightshift */
    455  1.6  christos 	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
    456  1.6  christos 	 24,			   /* bitsize */
    457  1.6  christos 	 TRUE,			   /* pc_relative */
    458  1.6  christos 	 0,			   /* bitpos */
    459  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    460  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    461  1.6  christos 	 "R_CR16_DISP24",	   /* name */
    462  1.6  christos 	 FALSE,			   /* partial_inplace */
    463  1.6  christos 	 0x0,			   /* src_mask */
    464  1.6  christos 	 0x1ffffff,		   /* dst_mask */
    465  1.6  christos 	 FALSE),		   /* pcrel_offset */
    466  1.6  christos 
    467  1.6  christos   HOWTO (R_CR16_DISP24a,	   /* type */
    468  1.6  christos 	 0,			   /* rightshift */
    469  1.6  christos 	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
    470  1.6  christos 	 24,			   /* bitsize */
    471  1.6  christos 	 TRUE,			   /* pc_relative */
    472  1.6  christos 	 0,			   /* bitpos */
    473  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    474  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    475  1.6  christos 	 "R_CR16_DISP24a",	   /* name */
    476  1.6  christos 	 FALSE,			   /* partial_inplace */
    477  1.6  christos 	 0x0,			   /* src_mask */
    478  1.6  christos 	 0xffffff,		   /* dst_mask */
    479  1.6  christos 	 FALSE),		   /* pcrel_offset */
    480  1.1  christos 
    481  1.1  christos   /* An 8 bit switch table entry.  This is generated for an expression
    482  1.1  christos      such as ``.byte L1 - L2''.  The offset holds the difference
    483  1.1  christos      between the reloc address and L2.  */
    484  1.6  christos   HOWTO (R_CR16_SWITCH8,	   /* type */
    485  1.6  christos 	 0,			   /* rightshift */
    486  1.6  christos 	 0,			   /* size (0 = byte, 1 = short, 2 = long) */
    487  1.6  christos 	 8,			   /* bitsize */
    488  1.6  christos 	 FALSE,			   /* pc_relative */
    489  1.6  christos 	 0,			   /* bitpos */
    490  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    491  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    492  1.6  christos 	 "R_CR16_SWITCH8",	   /* name */
    493  1.6  christos 	 FALSE,			   /* partial_inplace */
    494  1.6  christos 	 0x0,			   /* src_mask */
    495  1.6  christos 	 0xff,			   /* dst_mask */
    496  1.6  christos 	 TRUE),			   /* pcrel_offset */
    497  1.1  christos 
    498  1.1  christos   /* A 16 bit switch table entry.  This is generated for an expression
    499  1.1  christos      such as ``.word L1 - L2''.  The offset holds the difference
    500  1.1  christos      between the reloc address and L2.  */
    501  1.6  christos   HOWTO (R_CR16_SWITCH16,	   /* type */
    502  1.6  christos 	 0,			   /* rightshift */
    503  1.6  christos 	 1,			   /* size (0 = byte, 1 = short, 2 = long) */
    504  1.6  christos 	 16,			   /* bitsize */
    505  1.6  christos 	 FALSE,			   /* pc_relative */
    506  1.6  christos 	 0,			   /* bitpos */
    507  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    508  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    509  1.6  christos 	 "R_CR16_SWITCH16",	   /* name */
    510  1.6  christos 	 FALSE,			   /* partial_inplace */
    511  1.6  christos 	 0x0,			   /* src_mask */
    512  1.6  christos 	 0xffff,		   /* dst_mask */
    513  1.6  christos 	 TRUE),			   /* pcrel_offset */
    514  1.1  christos 
    515  1.1  christos   /* A 32 bit switch table entry.  This is generated for an expression
    516  1.1  christos      such as ``.long L1 - L2''.  The offset holds the difference
    517  1.1  christos      between the reloc address and L2.  */
    518  1.6  christos   HOWTO (R_CR16_SWITCH32,	   /* type */
    519  1.6  christos 	 0,			   /* rightshift */
    520  1.6  christos 	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
    521  1.6  christos 	 32,			   /* bitsize */
    522  1.6  christos 	 FALSE,			   /* pc_relative */
    523  1.6  christos 	 0,			   /* bitpos */
    524  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    525  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    526  1.6  christos 	 "R_CR16_SWITCH32",	   /* name */
    527  1.6  christos 	 FALSE,			   /* partial_inplace */
    528  1.6  christos 	 0x0,			   /* src_mask */
    529  1.6  christos 	 0xffffffff,		   /* dst_mask */
    530  1.6  christos 	 TRUE),			   /* pcrel_offset */
    531  1.6  christos 
    532  1.6  christos   HOWTO (R_CR16_GOT_REGREL20,	   /* type */
    533  1.6  christos 	 0,			   /* rightshift */
    534  1.6  christos 	 2,			   /* size */
    535  1.6  christos 	 20,			   /* bitsize */
    536  1.6  christos 	 FALSE,			   /* pc_relative */
    537  1.6  christos 	 0,			   /* bitpos */
    538  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    539  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    540  1.6  christos 	 "R_CR16_GOT_REGREL20",	   /* name */
    541  1.6  christos 	 TRUE,			   /* partial_inplace */
    542  1.6  christos 	 0x0,			   /* src_mask */
    543  1.6  christos 	 0xfffff,		   /* dst_mask */
    544  1.6  christos 	 FALSE),		   /* pcrel_offset */
    545  1.6  christos 
    546  1.6  christos   HOWTO (R_CR16_GOTC_REGREL20,	   /* type */
    547  1.6  christos 	 0,			   /* rightshift */
    548  1.6  christos 	 2,			   /* size */
    549  1.6  christos 	 20,			   /* bitsize */
    550  1.6  christos 	 FALSE,			   /* pc_relative */
    551  1.6  christos 	 0,			   /* bitpos */
    552  1.6  christos 	 complain_overflow_bitfield,/* complain_on_overflow */
    553  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    554  1.6  christos 	 "R_CR16_GOTC_REGREL20",   /* name */
    555  1.6  christos 	 TRUE,			   /* partial_inplace */
    556  1.6  christos 	 0x0,			   /* src_mask */
    557  1.6  christos 	 0xfffff,		   /* dst_mask */
    558  1.6  christos 	 FALSE),		   /* pcrel_offset */
    559  1.6  christos 
    560  1.6  christos   HOWTO (R_CR16_GLOB_DAT,	   /* type */
    561  1.6  christos 	 0,			   /* rightshift */
    562  1.6  christos 	 2,			   /* size (0 = byte, 1 = short, 2 = long) */
    563  1.6  christos 	 32,			   /* bitsize */
    564  1.6  christos 	 FALSE,			   /* pc_relative */
    565  1.6  christos 	 0,			   /* bitpos */
    566  1.6  christos 	 complain_overflow_unsigned, /* complain_on_overflow */
    567  1.6  christos 	 bfd_elf_generic_reloc,	   /* special_function */
    568  1.6  christos 	 "R_CR16_GLOB_DAT",	   /* name */
    569  1.6  christos 	 FALSE,			   /* partial_inplace */
    570  1.6  christos 	 0x0,			   /* src_mask */
    571  1.6  christos 	 0xffffffff,		   /* dst_mask */
    572  1.6  christos 	 TRUE)			   /* pcrel_offset */
    573  1.1  christos };
    574  1.1  christos 
    575  1.1  christos 
    576  1.1  christos /* Create the GOT section.  */
    577  1.1  christos 
    578  1.1  christos static bfd_boolean
    579  1.1  christos _bfd_cr16_elf_create_got_section (bfd * abfd, struct bfd_link_info * info)
    580  1.1  christos {
    581  1.1  christos   flagword   flags;
    582  1.1  christos   asection * s;
    583  1.1  christos   struct elf_link_hash_entry * h;
    584  1.1  christos   const struct elf_backend_data * bed = get_elf_backend_data (abfd);
    585  1.6  christos   struct elf_link_hash_table *htab = elf_hash_table (info);
    586  1.1  christos   int ptralign;
    587  1.1  christos 
    588  1.1  christos   /* This function may be called more than once.  */
    589  1.6  christos   if (htab->sgot != NULL)
    590  1.1  christos     return TRUE;
    591  1.1  christos 
    592  1.1  christos   switch (bed->s->arch_size)
    593  1.1  christos     {
    594  1.1  christos     case 16:
    595  1.1  christos       ptralign = 1;
    596  1.1  christos       break;
    597  1.1  christos 
    598  1.1  christos     case 32:
    599  1.1  christos       ptralign = 2;
    600  1.1  christos       break;
    601  1.1  christos 
    602  1.1  christos     default:
    603  1.1  christos       bfd_set_error (bfd_error_bad_value);
    604  1.1  christos       return FALSE;
    605  1.1  christos     }
    606  1.1  christos 
    607  1.1  christos   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
    608  1.6  christos 	   | SEC_LINKER_CREATED);
    609  1.1  christos 
    610  1.1  christos   s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
    611  1.6  christos   htab->sgot= s;
    612  1.1  christos   if (s == NULL
    613  1.1  christos       || ! bfd_set_section_alignment (abfd, s, ptralign))
    614  1.1  christos     return FALSE;
    615  1.1  christos 
    616  1.1  christos   if (bed->want_got_plt)
    617  1.1  christos     {
    618  1.1  christos       s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
    619  1.6  christos       htab->sgotplt = s;
    620  1.1  christos       if (s == NULL
    621  1.6  christos 	  || ! bfd_set_section_alignment (abfd, s, ptralign))
    622  1.6  christos 	return FALSE;
    623  1.1  christos     }
    624  1.1  christos 
    625  1.1  christos   /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
    626  1.1  christos      (or .got.plt) section.  We don't do this in the linker script
    627  1.1  christos      because we don't want to define the symbol if we are not creating
    628  1.1  christos      a global offset table.  */
    629  1.1  christos   h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
    630  1.6  christos   htab->hgot = h;
    631  1.1  christos   if (h == NULL)
    632  1.1  christos     return FALSE;
    633  1.1  christos 
    634  1.1  christos   /* The first bit of the global offset table is the header.  */
    635  1.1  christos   s->size += bed->got_header_size;
    636  1.1  christos 
    637  1.1  christos   return TRUE;
    638  1.1  christos }
    639  1.1  christos 
    640  1.1  christos 
    641  1.1  christos /* Retrieve a howto ptr using a BFD reloc_code.  */
    642  1.1  christos 
    643  1.1  christos static reloc_howto_type *
    644  1.6  christos elf_cr16_reloc_type_lookup (bfd *abfd,
    645  1.6  christos 			    bfd_reloc_code_real_type code)
    646  1.1  christos {
    647  1.1  christos   unsigned int i;
    648  1.1  christos 
    649  1.1  christos   for (i = 0; i < R_CR16_MAX; i++)
    650  1.1  christos     if (code == cr16_reloc_map[i].bfd_reloc_enum)
    651  1.1  christos       return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type];
    652  1.1  christos 
    653  1.6  christos   _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    654  1.6  christos 		      abfd, code);
    655  1.1  christos   return NULL;
    656  1.1  christos }
    657  1.1  christos 
    658  1.1  christos static reloc_howto_type *
    659  1.1  christos elf_cr16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    660  1.6  christos 			    const char *r_name)
    661  1.1  christos {
    662  1.1  christos   unsigned int i;
    663  1.1  christos 
    664  1.1  christos   for (i = 0; ARRAY_SIZE (cr16_elf_howto_table); i++)
    665  1.1  christos     if (cr16_elf_howto_table[i].name != NULL
    666  1.6  christos 	&& strcasecmp (cr16_elf_howto_table[i].name, r_name) == 0)
    667  1.1  christos       return cr16_elf_howto_table + i;
    668  1.1  christos 
    669  1.1  christos   return NULL;
    670  1.1  christos }
    671  1.1  christos 
    672  1.1  christos /* Retrieve a howto ptr using an internal relocation entry.  */
    673  1.1  christos 
    674  1.6  christos static bfd_boolean
    675  1.6  christos elf_cr16_info_to_howto (bfd *abfd, arelent *cache_ptr,
    676  1.6  christos 			Elf_Internal_Rela *dst)
    677  1.1  christos {
    678  1.1  christos   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
    679  1.1  christos 
    680  1.3  christos   if (r_type >= R_CR16_MAX)
    681  1.3  christos     {
    682  1.6  christos       /* xgettext:c-format */
    683  1.6  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    684  1.6  christos 			  abfd, r_type);
    685  1.3  christos       bfd_set_error (bfd_error_bad_value);
    686  1.6  christos       return FALSE;
    687  1.3  christos     }
    688  1.1  christos   cache_ptr->howto = cr16_elf_howto_table + r_type;
    689  1.6  christos   return TRUE;
    690  1.1  christos }
    691  1.1  christos 
    692  1.1  christos /* Look through the relocs for a section during the first phase.
    693  1.1  christos    Since we don't do .gots or .plts, we just need to consider the
    694  1.1  christos    virtual table relocs for gc.  */
    695  1.1  christos 
    696  1.1  christos static bfd_boolean
    697  1.1  christos cr16_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
    698  1.6  christos 		       const Elf_Internal_Rela *relocs)
    699  1.1  christos {
    700  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
    701  1.1  christos   Elf_Internal_Sym * isymbuf = NULL;
    702  1.1  christos   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
    703  1.1  christos   const Elf_Internal_Rela *rel;
    704  1.1  christos   const Elf_Internal_Rela *rel_end;
    705  1.1  christos   bfd *      dynobj;
    706  1.1  christos   bfd_vma *  local_got_offsets;
    707  1.1  christos   asection * sgot;
    708  1.1  christos   asection * srelgot;
    709  1.1  christos 
    710  1.1  christos   sgot    = NULL;
    711  1.1  christos   srelgot = NULL;
    712  1.1  christos   bfd_boolean result = FALSE;
    713  1.1  christos 
    714  1.3  christos   if (bfd_link_relocatable (info))
    715  1.1  christos     return TRUE;
    716  1.1  christos 
    717  1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    718  1.1  christos   sym_hashes = elf_sym_hashes (abfd);
    719  1.1  christos   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
    720  1.1  christos   if (!elf_bad_symtab (abfd))
    721  1.1  christos     sym_hashes_end -= symtab_hdr->sh_info;
    722  1.1  christos 
    723  1.1  christos   dynobj = elf_hash_table (info)->dynobj;
    724  1.1  christos   local_got_offsets = elf_local_got_offsets (abfd);
    725  1.1  christos   rel_end = relocs + sec->reloc_count;
    726  1.1  christos   for (rel = relocs; rel < rel_end; rel++)
    727  1.1  christos     {
    728  1.1  christos       struct elf_link_hash_entry *h;
    729  1.1  christos       unsigned long r_symndx;
    730  1.1  christos 
    731  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
    732  1.1  christos       if (r_symndx < symtab_hdr->sh_info)
    733  1.6  christos 	h = NULL;
    734  1.1  christos       else
    735  1.6  christos 	{
    736  1.6  christos 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
    737  1.6  christos 	  while (h->root.type == bfd_link_hash_indirect
    738  1.6  christos 		 || h->root.type == bfd_link_hash_warning)
    739  1.6  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    740  1.6  christos 	}
    741  1.1  christos 
    742  1.1  christos       /* Some relocs require a global offset table.  */
    743  1.1  christos       if (dynobj == NULL)
    744  1.6  christos 	{
    745  1.6  christos 	  switch (ELF32_R_TYPE (rel->r_info))
    746  1.6  christos 	    {
    747  1.6  christos 	    case R_CR16_GOT_REGREL20:
    748  1.6  christos 	    case R_CR16_GOTC_REGREL20:
    749  1.6  christos 	      elf_hash_table (info)->dynobj = dynobj = abfd;
    750  1.6  christos 	      if (! _bfd_cr16_elf_create_got_section (dynobj, info))
    751  1.6  christos 		goto fail;
    752  1.6  christos 	      break;
    753  1.6  christos 
    754  1.6  christos 	    default:
    755  1.6  christos 	      break;
    756  1.6  christos 	    }
    757  1.6  christos 	}
    758  1.1  christos 
    759  1.1  christos       switch (ELF32_R_TYPE (rel->r_info))
    760  1.6  christos 	{
    761  1.6  christos 	case R_CR16_GOT_REGREL20:
    762  1.6  christos 	case R_CR16_GOTC_REGREL20:
    763  1.6  christos 	  /* This symbol requires a global offset table entry.  */
    764  1.6  christos 
    765  1.6  christos 	  sgot = elf_hash_table (info)->sgot;
    766  1.6  christos 	  srelgot = elf_hash_table (info)->srelgot;
    767  1.6  christos 	  BFD_ASSERT (sgot != NULL && srelgot != NULL);
    768  1.6  christos 
    769  1.6  christos 	  if (h != NULL)
    770  1.6  christos 	    {
    771  1.6  christos 	      if (h->got.offset != (bfd_vma) -1)
    772  1.6  christos 		/* We have already allocated space in the .got.  */
    773  1.6  christos 		break;
    774  1.6  christos 
    775  1.6  christos 	      h->got.offset = sgot->size;
    776  1.6  christos 
    777  1.6  christos 	      /* Make sure this symbol is output as a dynamic symbol.  */
    778  1.6  christos 	      if (h->dynindx == -1)
    779  1.6  christos 		{
    780  1.6  christos 		  if (! bfd_elf_link_record_dynamic_symbol (info, h))
    781  1.6  christos 		    goto fail;
    782  1.6  christos 		}
    783  1.6  christos 
    784  1.6  christos 	      srelgot->size += sizeof (Elf32_External_Rela);
    785  1.6  christos 	    }
    786  1.6  christos 	  else
    787  1.6  christos 	    {
    788  1.6  christos 	      /* This is a global offset table entry for a local
    789  1.6  christos 		 symbol.  */
    790  1.6  christos 	      if (local_got_offsets == NULL)
    791  1.6  christos 		{
    792  1.6  christos 		  size_t       size;
    793  1.6  christos 		  unsigned int i;
    794  1.6  christos 
    795  1.6  christos 		  size = symtab_hdr->sh_info * sizeof (bfd_vma);
    796  1.6  christos 		  local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
    797  1.6  christos 
    798  1.6  christos 		  if (local_got_offsets == NULL)
    799  1.6  christos 		    goto fail;
    800  1.6  christos 
    801  1.6  christos 		  elf_local_got_offsets (abfd) = local_got_offsets;
    802  1.6  christos 
    803  1.6  christos 		  for (i = 0; i < symtab_hdr->sh_info; i++)
    804  1.6  christos 		    local_got_offsets[i] = (bfd_vma) -1;
    805  1.6  christos 		}
    806  1.6  christos 
    807  1.6  christos 	      if (local_got_offsets[r_symndx] != (bfd_vma) -1)
    808  1.6  christos 		/* We have already allocated space in the .got.  */
    809  1.6  christos 		break;
    810  1.6  christos 
    811  1.6  christos 	      local_got_offsets[r_symndx] = sgot->size;
    812  1.6  christos 
    813  1.6  christos 	      if (bfd_link_executable (info))
    814  1.6  christos 		/* If we are generating a shared object, we need to
    815  1.6  christos 		   output a R_CR16_RELATIVE reloc so that the dynamic
    816  1.6  christos 		   linker can adjust this GOT entry.  */
    817  1.6  christos 		srelgot->size += sizeof (Elf32_External_Rela);
    818  1.6  christos 	    }
    819  1.1  christos 
    820  1.6  christos 	  sgot->size += 4;
    821  1.6  christos 	  break;
    822  1.1  christos 
    823  1.6  christos 	}
    824  1.1  christos     }
    825  1.1  christos 
    826  1.1  christos    result = TRUE;
    827  1.1  christos   fail:
    828  1.1  christos     if (isymbuf != NULL)
    829  1.1  christos       free (isymbuf);
    830  1.1  christos 
    831  1.1  christos   return result;
    832  1.1  christos }
    833  1.1  christos 
    834  1.1  christos /* Perform a relocation as part of a final link.  */
    835  1.1  christos 
    836  1.1  christos static bfd_reloc_status_type
    837  1.1  christos cr16_elf_final_link_relocate (reloc_howto_type *howto,
    838  1.6  christos 			      bfd *input_bfd,
    839  1.6  christos 			      bfd *output_bfd ATTRIBUTE_UNUSED,
    840  1.6  christos 			      asection *input_section,
    841  1.6  christos 			      bfd_byte *contents,
    842  1.6  christos 			      bfd_vma offset,
    843  1.6  christos 			      bfd_vma Rvalue,
    844  1.6  christos 			      bfd_vma addend,
    845  1.6  christos 			      struct elf_link_hash_entry * h,
    846  1.6  christos 			      unsigned long symndx  ATTRIBUTE_UNUSED,
    847  1.6  christos 			      struct bfd_link_info *info ATTRIBUTE_UNUSED,
    848  1.6  christos 			      asection *sec ATTRIBUTE_UNUSED,
    849  1.6  christos 			      int is_local ATTRIBUTE_UNUSED)
    850  1.1  christos {
    851  1.1  christos   unsigned short r_type = howto->type;
    852  1.1  christos   bfd_byte *hit_data = contents + offset;
    853  1.1  christos   bfd_vma reloc_bits, check, Rvalue1;
    854  1.1  christos 
    855  1.1  christos   switch (r_type)
    856  1.1  christos     {
    857  1.1  christos      case R_CR16_IMM4:
    858  1.1  christos      case R_CR16_IMM20:
    859  1.1  christos      case R_CR16_ABS20:
    860  1.1  christos        break;
    861  1.1  christos 
    862  1.1  christos      case R_CR16_IMM8:
    863  1.1  christos      case R_CR16_IMM16:
    864  1.1  christos      case R_CR16_IMM32:
    865  1.1  christos      case R_CR16_IMM32a:
    866  1.1  christos      case R_CR16_REGREL4:
    867  1.1  christos      case R_CR16_REGREL4a:
    868  1.1  christos      case R_CR16_REGREL14:
    869  1.1  christos      case R_CR16_REGREL14a:
    870  1.1  christos      case R_CR16_REGREL16:
    871  1.1  christos      case R_CR16_REGREL20:
    872  1.1  christos      case R_CR16_REGREL20a:
    873  1.1  christos      case R_CR16_GOT_REGREL20:
    874  1.1  christos      case R_CR16_GOTC_REGREL20:
    875  1.1  christos      case R_CR16_ABS24:
    876  1.1  christos      case R_CR16_DISP16:
    877  1.1  christos      case R_CR16_DISP24:
    878  1.1  christos        /* 'hit_data' is relative to the start of the instruction, not the
    879  1.6  christos 	   relocation offset. Advance it to account for the exact offset.  */
    880  1.1  christos        hit_data += 2;
    881  1.1  christos        break;
    882  1.1  christos 
    883  1.1  christos      case R_CR16_NONE:
    884  1.1  christos        return bfd_reloc_ok;
    885  1.1  christos        break;
    886  1.1  christos 
    887  1.1  christos      case R_CR16_DISP4:
    888  1.1  christos        if (is_local)
    889  1.6  christos 	Rvalue += -1;
    890  1.1  christos        break;
    891  1.1  christos 
    892  1.1  christos      case R_CR16_DISP8:
    893  1.1  christos      case R_CR16_DISP24a:
    894  1.1  christos        if (is_local)
    895  1.6  christos 	Rvalue -= -1;
    896  1.1  christos        break;
    897  1.1  christos 
    898  1.1  christos      case R_CR16_SWITCH8:
    899  1.1  christos      case R_CR16_SWITCH16:
    900  1.1  christos      case R_CR16_SWITCH32:
    901  1.1  christos        /* We only care about the addend, where the difference between
    902  1.6  christos 	  expressions is kept.  */
    903  1.1  christos        Rvalue = 0;
    904  1.3  christos 
    905  1.1  christos      default:
    906  1.1  christos        break;
    907  1.1  christos     }
    908  1.1  christos 
    909  1.1  christos   if (howto->pc_relative)
    910  1.1  christos     {
    911  1.1  christos       /* Subtract the address of the section containing the location.  */
    912  1.1  christos       Rvalue -= (input_section->output_section->vma
    913  1.6  christos 		 + input_section->output_offset);
    914  1.1  christos       /* Subtract the position of the location within the section.  */
    915  1.1  christos       Rvalue -= offset;
    916  1.1  christos     }
    917  1.1  christos 
    918  1.1  christos   /* Add in supplied addend.  */
    919  1.1  christos   Rvalue += addend;
    920  1.1  christos 
    921  1.1  christos   /* Complain if the bitfield overflows, whether it is considered
    922  1.1  christos      as signed or unsigned.  */
    923  1.1  christos   check = Rvalue >> howto->rightshift;
    924  1.1  christos 
    925  1.1  christos   /* Assumes two's complement.  This expression avoids
    926  1.1  christos      overflow if howto->bitsize is the number of bits in
    927  1.1  christos      bfd_vma.  */
    928  1.1  christos   reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
    929  1.1  christos 
    930  1.1  christos   /* For GOT and GOTC relocs no boundary checks applied.  */
    931  1.1  christos   if (!((r_type == R_CR16_GOT_REGREL20)
    932  1.1  christos       || (r_type == R_CR16_GOTC_REGREL20)))
    933  1.1  christos     {
    934  1.1  christos       if (((bfd_vma) check & ~reloc_bits) != 0
    935  1.6  christos 	  && (((bfd_vma) check & ~reloc_bits)
    936  1.6  christos 	  != (-(bfd_vma) 1 & ~reloc_bits)))
    937  1.6  christos 	{
    938  1.6  christos 	  /* The above right shift is incorrect for a signed
    939  1.6  christos 	     value.  See if turning on the upper bits fixes the
    940  1.6  christos 	     overflow.  */
    941  1.6  christos 	  if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
    942  1.6  christos 	    {
    943  1.6  christos 	      check |= ((bfd_vma) - 1
    944  1.6  christos 			& ~((bfd_vma) - 1
    945  1.6  christos 			 >> howto->rightshift));
    946  1.6  christos 
    947  1.6  christos 	      if (((bfd_vma) check & ~reloc_bits)
    948  1.6  christos 		  != (-(bfd_vma) 1 & ~reloc_bits))
    949  1.6  christos 		 return bfd_reloc_overflow;
    950  1.6  christos 	    }
    951  1.6  christos 	  else
    952  1.6  christos 	    return bfd_reloc_overflow;
    953  1.6  christos 	}
    954  1.1  christos 
    955  1.1  christos       /* Drop unwanted bits from the value we are relocating to.  */
    956  1.1  christos       Rvalue >>= (bfd_vma) howto->rightshift;
    957  1.1  christos 
    958  1.1  christos       /* Apply dst_mask to select only relocatable part of the insn.  */
    959  1.1  christos       Rvalue &= howto->dst_mask;
    960  1.1  christos     }
    961  1.1  christos 
    962  1.1  christos   switch (howto->size)
    963  1.1  christos     {
    964  1.1  christos       case 0:
    965  1.6  christos 	if (r_type == R_CR16_DISP8)
    966  1.6  christos 	  {
    967  1.6  christos 	     Rvalue1 = bfd_get_16 (input_bfd, hit_data);
    968  1.6  christos 	     Rvalue = ((Rvalue1 & 0xf000) | ((Rvalue << 4) & 0xf00)
    969  1.6  christos 		       | (Rvalue1 & 0x00f0) | (Rvalue & 0xf));
    970  1.6  christos 	     bfd_put_16 (input_bfd, Rvalue, hit_data);
    971  1.6  christos 	  }
    972  1.6  christos 	else if (r_type == R_CR16_IMM4)
    973  1.6  christos 	  {
    974  1.6  christos 	     Rvalue1 = bfd_get_16 (input_bfd, hit_data);
    975  1.6  christos 	     Rvalue = (((Rvalue1 & 0xff) << 8) | ((Rvalue << 4) & 0xf0)
    976  1.6  christos 		       | ((Rvalue1 & 0x0f00) >> 8));
    977  1.6  christos 	     bfd_put_16 (input_bfd, Rvalue, hit_data);
    978  1.6  christos 	  }
    979  1.6  christos 	else if (r_type == R_CR16_DISP4)
    980  1.6  christos 	  {
    981  1.6  christos 	     Rvalue1 = bfd_get_16 (input_bfd, hit_data);
    982  1.6  christos 	     Rvalue = (Rvalue1 | ((Rvalue & 0xf) << 4));
    983  1.6  christos 	     bfd_put_16 (input_bfd, Rvalue, hit_data);
    984  1.6  christos 	  }
    985  1.6  christos 	else
    986  1.6  christos 	  {
    987  1.6  christos 	     bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
    988  1.6  christos 	  }
    989  1.6  christos 	break;
    990  1.1  christos 
    991  1.1  christos       case 1:
    992  1.6  christos 	if (r_type == R_CR16_DISP16)
    993  1.6  christos 	  {
    994  1.6  christos 	    Rvalue |= (bfd_get_16 (input_bfd, hit_data));
    995  1.6  christos 	    Rvalue = ((Rvalue & 0xfffe) | ((Rvalue >> 16) & 0x1));
    996  1.6  christos 	  }
    997  1.6  christos 	if (r_type == R_CR16_IMM16)
    998  1.6  christos 	  {
    999  1.6  christos 	    Rvalue1 = bfd_get_16 (input_bfd, hit_data);
   1000  1.6  christos 
   1001  1.6  christos 	    /* Add or subtract the offset value.  */
   1002  1.6  christos 	    if (Rvalue1 & 0x8000)
   1003  1.6  christos 	      Rvalue -= (~Rvalue1 + 1) & 0xffff;
   1004  1.6  christos 	    else
   1005  1.6  christos 	      Rvalue += Rvalue1;
   1006  1.6  christos 
   1007  1.6  christos 	     /* Check for range.  */
   1008  1.6  christos 	     if ((long) Rvalue > 0xffff || (long) Rvalue < 0x0)
   1009  1.6  christos 	      return bfd_reloc_overflow;
   1010  1.6  christos 	  }
   1011  1.1  christos 
   1012  1.6  christos 	bfd_put_16 (input_bfd, Rvalue, hit_data);
   1013  1.6  christos 	break;
   1014  1.1  christos 
   1015  1.1  christos       case 2:
   1016  1.6  christos 	if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20))
   1017  1.6  christos 	  {
   1018  1.6  christos 	     Rvalue1 = (bfd_get_16 (input_bfd, hit_data + 2)
   1019  1.6  christos 			| (((bfd_get_16 (input_bfd, hit_data) & 0xf) <<16)));
   1020  1.6  christos 
   1021  1.6  christos 	     /* Add or subtract the offset value.  */
   1022  1.6  christos 	     if (Rvalue1 & 0x80000)
   1023  1.6  christos 		Rvalue -= (~Rvalue1 + 1) & 0xfffff;
   1024  1.6  christos 	      else
   1025  1.6  christos 		Rvalue += Rvalue1;
   1026  1.6  christos 
   1027  1.6  christos 	      /* Check for range.  */
   1028  1.6  christos 	      if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
   1029  1.6  christos 	       return bfd_reloc_overflow;
   1030  1.6  christos 
   1031  1.6  christos 	    bfd_put_16 (input_bfd, ((bfd_get_16 (input_bfd, hit_data) & 0xfff0)
   1032  1.6  christos 			| ((Rvalue >> 16) & 0xf)), hit_data);
   1033  1.6  christos 	    bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
   1034  1.6  christos 	  }
   1035  1.6  christos 	else if (r_type == R_CR16_GOT_REGREL20)
   1036  1.6  christos 	  {
   1037  1.6  christos 	    asection *sgot = elf_hash_table (info)->sgot;
   1038  1.6  christos 
   1039  1.6  christos 	    if (h != NULL)
   1040  1.6  christos 	      {
   1041  1.6  christos 		bfd_vma off;
   1042  1.6  christos 
   1043  1.6  christos 		off = h->got.offset;
   1044  1.6  christos 		BFD_ASSERT (off != (bfd_vma) -1);
   1045  1.6  christos 
   1046  1.6  christos 		if (! elf_hash_table (info)->dynamic_sections_created
   1047  1.6  christos 		     || SYMBOL_REFERENCES_LOCAL (info, h))
   1048  1.6  christos 		    /* This is actually a static link, or it is a
   1049  1.6  christos 		       -Bsymbolic link and the symbol is defined
   1050  1.6  christos 		       locally, or the symbol was forced to be local
   1051  1.6  christos 		       because of a version file.  We must initialize
   1052  1.6  christos 		       this entry in the global offset table.
   1053  1.6  christos 		       When doing a dynamic link, we create a .rela.got
   1054  1.6  christos 		       relocation entry to initialize the value.  This
   1055  1.6  christos 		       is done in the finish_dynamic_symbol routine.  */
   1056  1.6  christos 		  bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
   1057  1.6  christos 
   1058  1.6  christos 		  Rvalue = sgot->output_offset + off;
   1059  1.6  christos 		}
   1060  1.6  christos 	      else
   1061  1.6  christos 		{
   1062  1.6  christos 		   bfd_vma off;
   1063  1.6  christos 
   1064  1.6  christos 		   off = elf_local_got_offsets (input_bfd)[symndx];
   1065  1.6  christos 		   bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
   1066  1.6  christos 
   1067  1.6  christos 		   Rvalue = sgot->output_offset + off;
   1068  1.6  christos 		}
   1069  1.6  christos 
   1070  1.6  christos 	     Rvalue += addend;
   1071  1.6  christos 
   1072  1.6  christos 	     /* REVISIT: if ((long) Rvalue > 0xffffff ||
   1073  1.6  christos 				    (long) Rvalue < -0x800000).  */
   1074  1.6  christos 	     if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
   1075  1.6  christos 	       return bfd_reloc_overflow;
   1076  1.6  christos 
   1077  1.6  christos 
   1078  1.6  christos 	     bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
   1079  1.6  christos 			 | (((Rvalue >> 16) & 0xf) << 8), hit_data);
   1080  1.6  christos 	     bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
   1081  1.6  christos 
   1082  1.6  christos 	  }
   1083  1.6  christos 	else if (r_type == R_CR16_GOTC_REGREL20)
   1084  1.6  christos 	  {
   1085  1.6  christos 	     asection *sgot = elf_hash_table (info)->sgot;
   1086  1.6  christos 
   1087  1.6  christos 	     if (h != NULL)
   1088  1.6  christos 	       {
   1089  1.6  christos 		 bfd_vma off;
   1090  1.6  christos 
   1091  1.6  christos 		 off = h->got.offset;
   1092  1.6  christos 		 BFD_ASSERT (off != (bfd_vma) -1);
   1093  1.6  christos 
   1094  1.6  christos 		  Rvalue >>=1; /* For code symbols.  */
   1095  1.6  christos 
   1096  1.6  christos 		 if (! elf_hash_table (info)->dynamic_sections_created
   1097  1.6  christos 		      || SYMBOL_REFERENCES_LOCAL (info, h))
   1098  1.6  christos 		 /* This is actually a static link, or it is a
   1099  1.6  christos 		    -Bsymbolic link and the symbol is defined
   1100  1.6  christos 		     locally, or the symbol was forced to be local
   1101  1.6  christos 		     because of a version file.  We must initialize
   1102  1.6  christos 		     this entry in the global offset table.
   1103  1.6  christos 		     When doing a dynamic link, we create a .rela.got
   1104  1.6  christos 		     relocation entry to initialize the value.  This
   1105  1.6  christos 		     is done in the finish_dynamic_symbol routine.  */
   1106  1.6  christos 		  bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
   1107  1.6  christos 
   1108  1.6  christos 		  Rvalue = sgot->output_offset + off;
   1109  1.6  christos 	       }
   1110  1.6  christos 	     else
   1111  1.6  christos 	       {
   1112  1.6  christos 		  bfd_vma off;
   1113  1.6  christos 
   1114  1.6  christos 		  off = elf_local_got_offsets (input_bfd)[symndx];
   1115  1.6  christos 		  Rvalue >>= 1;
   1116  1.6  christos 		  bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
   1117  1.6  christos 		  Rvalue = sgot->output_offset + off;
   1118  1.6  christos 	       }
   1119  1.6  christos 
   1120  1.6  christos 	     Rvalue += addend;
   1121  1.6  christos 
   1122  1.6  christos 	     /* Check if any value in DISP.  */
   1123  1.6  christos 	     Rvalue1 =((bfd_get_32 (input_bfd, hit_data) >>16)
   1124  1.6  christos 		       | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
   1125  1.6  christos 
   1126  1.6  christos 	     /* Add or subtract the offset value.  */
   1127  1.6  christos 	     if (Rvalue1 & 0x80000)
   1128  1.6  christos 	       Rvalue -= (~Rvalue1 + 1) & 0xfffff;
   1129  1.6  christos 	     else
   1130  1.6  christos 	       Rvalue += Rvalue1;
   1131  1.6  christos 
   1132  1.6  christos 	      /* Check for range.  */
   1133  1.6  christos 	     /* REVISIT: if ((long) Rvalue > 0xffffff
   1134  1.6  christos 			     || (long) Rvalue < -0x800000).  */
   1135  1.6  christos 	     if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
   1136  1.6  christos 	       return bfd_reloc_overflow;
   1137  1.6  christos 
   1138  1.6  christos 	     bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
   1139  1.6  christos 			 | (((Rvalue >> 16) & 0xf) << 8), hit_data);
   1140  1.6  christos 	     bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
   1141  1.6  christos 	  }
   1142  1.6  christos 	else
   1143  1.6  christos 	  {
   1144  1.6  christos 	     if (r_type == R_CR16_ABS24)
   1145  1.6  christos 	       {
   1146  1.6  christos 		  Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
   1147  1.6  christos 			     | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16)
   1148  1.6  christos 			     | (((bfd_get_32 (input_bfd, hit_data) & 0xf) <<20)));
   1149  1.6  christos 
   1150  1.6  christos 		  /* Add or subtract the offset value.  */
   1151  1.6  christos 		  if (Rvalue1 & 0x800000)
   1152  1.6  christos 		    Rvalue -= (~Rvalue1 + 1) & 0xffffff;
   1153  1.6  christos 		  else
   1154  1.6  christos 		    Rvalue += Rvalue1;
   1155  1.6  christos 
   1156  1.6  christos 		 /* Check for Range.  */
   1157  1.6  christos 		 if ((long) Rvalue > 0xffffff || (long) Rvalue < 0x0)
   1158  1.6  christos 		   return bfd_reloc_overflow;
   1159  1.6  christos 
   1160  1.6  christos 		 Rvalue = ((((Rvalue >> 20) & 0xf) | (((Rvalue >> 16) & 0xf)<<8)
   1161  1.6  christos 			   | (bfd_get_32 (input_bfd, hit_data) & 0xf0f0))
   1162  1.6  christos 			   | ((Rvalue & 0xffff) << 16));
   1163  1.6  christos 	       }
   1164  1.6  christos 	     else if (r_type == R_CR16_DISP24)
   1165  1.6  christos 	       {
   1166  1.6  christos 		  Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
   1167  1.6  christos 			    | (bfd_get_16 (input_bfd, hit_data)))
   1168  1.6  christos 			    | (((Rvalue & 0xfffe) | ((Rvalue >> 24) & 0x1)) << 16));
   1169  1.6  christos 	       }
   1170  1.6  christos 	     else if ((r_type == R_CR16_IMM32) || (r_type == R_CR16_IMM32a))
   1171  1.6  christos 	       {
   1172  1.6  christos 		  Rvalue1 =((((bfd_get_32 (input_bfd, hit_data)) >> 16) &0xffff)
   1173  1.6  christos 			    | (((bfd_get_32 (input_bfd, hit_data)) &0xffff)) << 16);
   1174  1.6  christos 
   1175  1.6  christos 		 /* Add or subtract the offset value.  */
   1176  1.6  christos 		 if (Rvalue1 & 0x80000000)
   1177  1.6  christos 		   Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
   1178  1.6  christos 		 else
   1179  1.6  christos 		   Rvalue += Rvalue1;
   1180  1.6  christos 
   1181  1.6  christos 		 /* Check for range.  */
   1182  1.6  christos 		 if (Rvalue > 0xffffffff || (long) Rvalue < 0x0)
   1183  1.6  christos 		   return bfd_reloc_overflow;
   1184  1.6  christos 
   1185  1.6  christos 		 Rvalue = (((Rvalue >> 16)& 0xffff) | (Rvalue & 0xffff) << 16);
   1186  1.6  christos 	       }
   1187  1.6  christos 	     else if (r_type == R_CR16_DISP24a)
   1188  1.6  christos 	       {
   1189  1.6  christos 		  Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23)));
   1190  1.6  christos 		  Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16)
   1191  1.6  christos 			    | (bfd_get_32 (input_bfd, hit_data));
   1192  1.6  christos 	       }
   1193  1.6  christos 	     else if ((r_type == R_CR16_REGREL20)
   1194  1.6  christos 		      || (r_type == R_CR16_REGREL20a))
   1195  1.6  christos 	       {
   1196  1.6  christos 		  Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
   1197  1.6  christos 			     | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
   1198  1.6  christos 		  /* Add or subtract the offset value.  */
   1199  1.6  christos 		  if (Rvalue1 & 0x80000)
   1200  1.6  christos 		     Rvalue -= (~Rvalue1 + 1) & 0xfffff;
   1201  1.6  christos 		  else
   1202  1.6  christos 		     Rvalue += Rvalue1;
   1203  1.6  christos 
   1204  1.6  christos 		  /* Check for range.  */
   1205  1.6  christos 		  if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
   1206  1.6  christos 		    return bfd_reloc_overflow;
   1207  1.6  christos 
   1208  1.6  christos 		  Rvalue = (((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
   1209  1.6  christos 			    | ((Rvalue & 0xffff) << 16)))
   1210  1.6  christos 			    | (bfd_get_32 (input_bfd, hit_data) & 0xf0ff));
   1211  1.6  christos 
   1212  1.6  christos 	      }
   1213  1.6  christos 	    else if (r_type == R_CR16_NUM32)
   1214  1.6  christos 	      {
   1215  1.6  christos 		 Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
   1216  1.6  christos 
   1217  1.6  christos 		 /* Add or subtract the offset value */
   1218  1.6  christos 		 if (Rvalue1 & 0x80000000)
   1219  1.6  christos 		   Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
   1220  1.6  christos 		 else
   1221  1.6  christos 		   Rvalue += Rvalue1;
   1222  1.6  christos 
   1223  1.6  christos 		/* Check for Ranga */
   1224  1.6  christos 		if (Rvalue > 0xffffffff)
   1225  1.6  christos 		  return bfd_reloc_overflow;
   1226  1.6  christos 	      }
   1227  1.6  christos 
   1228  1.6  christos 	    bfd_put_32 (input_bfd, Rvalue, hit_data);
   1229  1.6  christos 	  }
   1230  1.6  christos 	break;
   1231  1.1  christos 
   1232  1.1  christos       default:
   1233  1.6  christos 	return bfd_reloc_notsupported;
   1234  1.1  christos     }
   1235  1.1  christos 
   1236  1.1  christos   return bfd_reloc_ok;
   1237  1.1  christos }
   1238  1.1  christos 
   1239  1.1  christos /* Delete some bytes from a section while relaxing.  */
   1240  1.1  christos 
   1241  1.1  christos static bfd_boolean
   1242  1.1  christos elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
   1243  1.6  christos 			       asection *sec, bfd_vma addr, int count)
   1244  1.1  christos {
   1245  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1246  1.1  christos   unsigned int sec_shndx;
   1247  1.1  christos   bfd_byte *contents;
   1248  1.1  christos   Elf_Internal_Rela *irel, *irelend;
   1249  1.1  christos   bfd_vma toaddr;
   1250  1.1  christos   Elf_Internal_Sym *isym;
   1251  1.1  christos   Elf_Internal_Sym *isymend;
   1252  1.1  christos   struct elf_link_hash_entry **sym_hashes;
   1253  1.1  christos   struct elf_link_hash_entry **end_hashes;
   1254  1.1  christos   struct elf_link_hash_entry **start_hashes;
   1255  1.1  christos   unsigned int symcount;
   1256  1.1  christos 
   1257  1.1  christos   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   1258  1.1  christos 
   1259  1.1  christos   contents = elf_section_data (sec)->this_hdr.contents;
   1260  1.1  christos 
   1261  1.1  christos   toaddr = sec->size;
   1262  1.1  christos 
   1263  1.1  christos   irel = elf_section_data (sec)->relocs;
   1264  1.1  christos   irelend = irel + sec->reloc_count;
   1265  1.1  christos 
   1266  1.1  christos   /* Actually delete the bytes.  */
   1267  1.1  christos   memmove (contents + addr, contents + addr + count,
   1268  1.6  christos 	   (size_t) (toaddr - addr - count));
   1269  1.1  christos   sec->size -= count;
   1270  1.1  christos 
   1271  1.1  christos   /* Adjust all the relocs.  */
   1272  1.1  christos   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
   1273  1.1  christos     /* Get the new reloc address.  */
   1274  1.1  christos     if ((irel->r_offset > addr && irel->r_offset < toaddr))
   1275  1.6  christos 	irel->r_offset -= count;
   1276  1.1  christos 
   1277  1.1  christos   /* Adjust the local symbols defined in this section.  */
   1278  1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1279  1.1  christos   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
   1280  1.1  christos   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
   1281  1.1  christos     {
   1282  1.1  christos       if (isym->st_shndx == sec_shndx
   1283  1.6  christos 	  && isym->st_value > addr
   1284  1.6  christos 	  && isym->st_value < toaddr)
   1285  1.6  christos 	{
   1286  1.6  christos 	  /* Adjust the addend of SWITCH relocations in this section,
   1287  1.6  christos 	     which reference this local symbol.  */
   1288  1.1  christos #if 0
   1289  1.6  christos 	  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
   1290  1.6  christos 	    {
   1291  1.6  christos 	      unsigned long r_symndx;
   1292  1.6  christos 	      Elf_Internal_Sym *rsym;
   1293  1.6  christos 	      bfd_vma addsym, subsym;
   1294  1.6  christos 
   1295  1.6  christos 	      /* Skip if not a SWITCH relocation.  */
   1296  1.6  christos 	      if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH8
   1297  1.6  christos 		  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH16
   1298  1.6  christos 		  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH32)
   1299  1.6  christos 		 continue;
   1300  1.6  christos 
   1301  1.6  christos 	      r_symndx = ELF32_R_SYM (irel->r_info);
   1302  1.6  christos 	      rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
   1303  1.6  christos 
   1304  1.6  christos 	      /* Skip if not the local adjusted symbol.  */
   1305  1.6  christos 	      if (rsym != isym)
   1306  1.6  christos 		continue;
   1307  1.6  christos 
   1308  1.6  christos 	      addsym = isym->st_value;
   1309  1.6  christos 	      subsym = addsym - irel->r_addend;
   1310  1.6  christos 
   1311  1.6  christos 	      /* Fix the addend only when -->> (addsym > addr >= subsym).  */
   1312  1.6  christos 	      if (subsym <= addr)
   1313  1.6  christos 		irel->r_addend -= count;
   1314  1.6  christos 	      else
   1315  1.6  christos 		continue;
   1316  1.6  christos 	    }
   1317  1.1  christos #endif
   1318  1.1  christos 
   1319  1.6  christos 	  isym->st_value -= count;
   1320  1.6  christos 	}
   1321  1.1  christos     }
   1322  1.1  christos 
   1323  1.1  christos   /* Now adjust the global symbols defined in this section.  */
   1324  1.1  christos   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
   1325  1.6  christos 	       - symtab_hdr->sh_info);
   1326  1.1  christos   sym_hashes = start_hashes = elf_sym_hashes (abfd);
   1327  1.1  christos   end_hashes = sym_hashes + symcount;
   1328  1.1  christos 
   1329  1.1  christos   for (; sym_hashes < end_hashes; sym_hashes++)
   1330  1.1  christos     {
   1331  1.1  christos       struct elf_link_hash_entry *sym_hash = *sym_hashes;
   1332  1.1  christos 
   1333  1.1  christos       /* The '--wrap SYMBOL' option is causing a pain when the object file,
   1334  1.6  christos 	 containing the definition of __wrap_SYMBOL, includes a direct
   1335  1.6  christos 	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
   1336  1.6  christos 	 the same symbol (which is __wrap_SYMBOL), but still exist as two
   1337  1.6  christos 	 different symbols in 'sym_hashes', we don't want to adjust
   1338  1.6  christos 	 the global symbol __wrap_SYMBOL twice.
   1339  1.6  christos 	 This check is only relevant when symbols are being wrapped.  */
   1340  1.1  christos       if (link_info->wrap_hash != NULL)
   1341  1.6  christos 	{
   1342  1.6  christos 	  struct elf_link_hash_entry **cur_sym_hashes;
   1343  1.1  christos 
   1344  1.6  christos 	  /* Loop only over the symbols whom been already checked.  */
   1345  1.6  christos 	  for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
   1346  1.6  christos 	       cur_sym_hashes++)
   1347  1.6  christos 	    /* If the current symbol is identical to 'sym_hash', that means
   1348  1.6  christos 	       the symbol was already adjusted (or at least checked).  */
   1349  1.6  christos 	    if (*cur_sym_hashes == sym_hash)
   1350  1.6  christos 	      break;
   1351  1.6  christos 
   1352  1.6  christos 	  /* Don't adjust the symbol again.  */
   1353  1.6  christos 	  if (cur_sym_hashes < sym_hashes)
   1354  1.6  christos 	    continue;
   1355  1.6  christos 	}
   1356  1.1  christos 
   1357  1.1  christos       if ((sym_hash->root.type == bfd_link_hash_defined
   1358  1.6  christos 	  || sym_hash->root.type == bfd_link_hash_defweak)
   1359  1.6  christos 	  && sym_hash->root.u.def.section == sec
   1360  1.6  christos 	  && sym_hash->root.u.def.value > addr
   1361  1.6  christos 	  && sym_hash->root.u.def.value < toaddr)
   1362  1.6  christos 	sym_hash->root.u.def.value -= count;
   1363  1.1  christos     }
   1364  1.1  christos 
   1365  1.1  christos   return TRUE;
   1366  1.1  christos }
   1367  1.1  christos 
   1368  1.1  christos /* Relocate a CR16 ELF section.  */
   1369  1.1  christos 
   1370  1.1  christos static bfd_boolean
   1371  1.1  christos elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
   1372  1.6  christos 			     bfd *input_bfd, asection *input_section,
   1373  1.6  christos 			     bfd_byte *contents, Elf_Internal_Rela *relocs,
   1374  1.6  christos 			     Elf_Internal_Sym *local_syms,
   1375  1.6  christos 			     asection **local_sections)
   1376  1.1  christos {
   1377  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1378  1.1  christos   struct elf_link_hash_entry **sym_hashes;
   1379  1.1  christos   Elf_Internal_Rela *rel, *relend;
   1380  1.1  christos 
   1381  1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   1382  1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
   1383  1.1  christos 
   1384  1.1  christos   rel = relocs;
   1385  1.1  christos   relend = relocs + input_section->reloc_count;
   1386  1.1  christos   for (; rel < relend; rel++)
   1387  1.1  christos     {
   1388  1.1  christos       int r_type;
   1389  1.1  christos       reloc_howto_type *howto;
   1390  1.1  christos       unsigned long r_symndx;
   1391  1.1  christos       Elf_Internal_Sym *sym;
   1392  1.1  christos       asection *sec;
   1393  1.1  christos       struct elf_link_hash_entry *h;
   1394  1.1  christos       bfd_vma relocation;
   1395  1.1  christos       bfd_reloc_status_type r;
   1396  1.1  christos 
   1397  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1398  1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   1399  1.1  christos       howto = cr16_elf_howto_table + (r_type);
   1400  1.1  christos 
   1401  1.1  christos       h = NULL;
   1402  1.1  christos       sym = NULL;
   1403  1.1  christos       sec = NULL;
   1404  1.1  christos       if (r_symndx < symtab_hdr->sh_info)
   1405  1.6  christos 	{
   1406  1.6  christos 	  sym = local_syms + r_symndx;
   1407  1.6  christos 	  sec = local_sections[r_symndx];
   1408  1.6  christos 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
   1409  1.6  christos 	}
   1410  1.1  christos       else
   1411  1.6  christos 	{
   1412  1.6  christos 	  bfd_boolean unresolved_reloc, warned, ignored;
   1413  1.1  christos 
   1414  1.6  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   1415  1.6  christos 				   r_symndx, symtab_hdr, sym_hashes,
   1416  1.6  christos 				   h, sec, relocation,
   1417  1.6  christos 				   unresolved_reloc, warned, ignored);
   1418  1.6  christos 	}
   1419  1.1  christos 
   1420  1.1  christos       if (sec != NULL && discarded_section (sec))
   1421  1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   1422  1.1  christos 					 rel, 1, relend, howto, 0, contents);
   1423  1.1  christos 
   1424  1.3  christos       if (bfd_link_relocatable (info))
   1425  1.6  christos 	continue;
   1426  1.1  christos 
   1427  1.1  christos       r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd,
   1428  1.6  christos 					input_section,
   1429  1.6  christos 					contents, rel->r_offset,
   1430  1.6  christos 					relocation, rel->r_addend,
   1431  1.6  christos 					(struct elf_link_hash_entry *) h,
   1432  1.6  christos 					r_symndx,
   1433  1.6  christos 					info, sec, h == NULL);
   1434  1.1  christos 
   1435  1.1  christos       if (r != bfd_reloc_ok)
   1436  1.6  christos 	{
   1437  1.6  christos 	  const char *name;
   1438  1.6  christos 	  const char *msg = NULL;
   1439  1.6  christos 
   1440  1.6  christos 	  if (h != NULL)
   1441  1.6  christos 	    name = h->root.root.string;
   1442  1.6  christos 	  else
   1443  1.6  christos 	    {
   1444  1.6  christos 	      name = (bfd_elf_string_from_elf_section
   1445  1.6  christos 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
   1446  1.6  christos 	      if (name == NULL || *name == '\0')
   1447  1.6  christos 		name = bfd_section_name (input_bfd, sec);
   1448  1.6  christos 	    }
   1449  1.6  christos 
   1450  1.6  christos 	  switch (r)
   1451  1.6  christos 	    {
   1452  1.6  christos 	     case bfd_reloc_overflow:
   1453  1.5  christos 	       (*info->callbacks->reloc_overflow)
   1454  1.5  christos 		 (info, (h ? &h->root : NULL), name, howto->name,
   1455  1.5  christos 		  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
   1456  1.6  christos 	       break;
   1457  1.1  christos 
   1458  1.6  christos 	     case bfd_reloc_undefined:
   1459  1.5  christos 	       (*info->callbacks->undefined_symbol)
   1460  1.5  christos 		 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
   1461  1.6  christos 	       break;
   1462  1.1  christos 
   1463  1.6  christos 	     case bfd_reloc_outofrange:
   1464  1.6  christos 	       msg = _("internal error: out of range error");
   1465  1.6  christos 	       goto common_error;
   1466  1.1  christos 
   1467  1.6  christos 	     case bfd_reloc_notsupported:
   1468  1.6  christos 	       msg = _("internal error: unsupported relocation error");
   1469  1.6  christos 	       goto common_error;
   1470  1.1  christos 
   1471  1.6  christos 	     case bfd_reloc_dangerous:
   1472  1.6  christos 	       msg = _("internal error: dangerous error");
   1473  1.6  christos 	       goto common_error;
   1474  1.1  christos 
   1475  1.6  christos 	     default:
   1476  1.6  christos 	       msg = _("internal error: unknown error");
   1477  1.6  christos 	       /* Fall through.  */
   1478  1.1  christos 
   1479  1.6  christos 	     common_error:
   1480  1.5  christos 	       (*info->callbacks->warning) (info, msg, name, input_bfd,
   1481  1.5  christos 					    input_section, rel->r_offset);
   1482  1.6  christos 	       break;
   1483  1.6  christos 	    }
   1484  1.6  christos 	}
   1485  1.1  christos     }
   1486  1.1  christos 
   1487  1.1  christos   return TRUE;
   1488  1.1  christos }
   1489  1.1  christos 
   1490  1.1  christos /* This is a version of bfd_generic_get_relocated_section_contents
   1491  1.1  christos    which uses elf32_cr16_relocate_section.  */
   1492  1.1  christos 
   1493  1.1  christos static bfd_byte *
   1494  1.1  christos elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
   1495  1.6  christos 					   struct bfd_link_info *link_info,
   1496  1.6  christos 					   struct bfd_link_order *link_order,
   1497  1.6  christos 					   bfd_byte *data,
   1498  1.6  christos 					   bfd_boolean relocatable,
   1499  1.6  christos 					   asymbol **symbols)
   1500  1.1  christos {
   1501  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1502  1.1  christos   asection *input_section = link_order->u.indirect.section;
   1503  1.1  christos   bfd *input_bfd = input_section->owner;
   1504  1.1  christos   asection **sections = NULL;
   1505  1.1  christos   Elf_Internal_Rela *internal_relocs = NULL;
   1506  1.1  christos   Elf_Internal_Sym *isymbuf = NULL;
   1507  1.1  christos 
   1508  1.1  christos   /* We only need to handle the case of relaxing, or of having a
   1509  1.1  christos      particular set of section contents, specially.  */
   1510  1.1  christos   if (relocatable
   1511  1.1  christos       || elf_section_data (input_section)->this_hdr.contents == NULL)
   1512  1.1  christos     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
   1513  1.6  christos 						       link_order, data,
   1514  1.6  christos 						       relocatable,
   1515  1.6  christos 						       symbols);
   1516  1.1  christos 
   1517  1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   1518  1.1  christos 
   1519  1.1  christos   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
   1520  1.6  christos 	  (size_t) input_section->size);
   1521  1.1  christos 
   1522  1.1  christos   if ((input_section->flags & SEC_RELOC) != 0
   1523  1.1  christos       && input_section->reloc_count > 0)
   1524  1.1  christos     {
   1525  1.1  christos       Elf_Internal_Sym *isym;
   1526  1.1  christos       Elf_Internal_Sym *isymend;
   1527  1.1  christos       asection **secpp;
   1528  1.1  christos       bfd_size_type amt;
   1529  1.1  christos 
   1530  1.1  christos       internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
   1531  1.6  christos 						   NULL, NULL, FALSE);
   1532  1.1  christos       if (internal_relocs == NULL)
   1533  1.6  christos 	goto error_return;
   1534  1.1  christos 
   1535  1.1  christos       if (symtab_hdr->sh_info != 0)
   1536  1.6  christos 	{
   1537  1.6  christos 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1538  1.6  christos 	  if (isymbuf == NULL)
   1539  1.6  christos 	    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
   1540  1.6  christos 					    symtab_hdr->sh_info, 0,
   1541  1.6  christos 					    NULL, NULL, NULL);
   1542  1.6  christos 	  if (isymbuf == NULL)
   1543  1.6  christos 	    goto error_return;
   1544  1.6  christos 	}
   1545  1.1  christos 
   1546  1.1  christos       amt = symtab_hdr->sh_info;
   1547  1.1  christos       amt *= sizeof (asection *);
   1548  1.1  christos       sections = bfd_malloc (amt);
   1549  1.1  christos       if (sections == NULL && amt != 0)
   1550  1.6  christos 	goto error_return;
   1551  1.1  christos 
   1552  1.1  christos       isymend = isymbuf + symtab_hdr->sh_info;
   1553  1.1  christos       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
   1554  1.6  christos 	{
   1555  1.6  christos 	  asection *isec;
   1556  1.1  christos 
   1557  1.6  christos 	  if (isym->st_shndx == SHN_UNDEF)
   1558  1.6  christos 	    isec = bfd_und_section_ptr;
   1559  1.6  christos 	  else if (isym->st_shndx == SHN_ABS)
   1560  1.6  christos 	    isec = bfd_abs_section_ptr;
   1561  1.6  christos 	  else if (isym->st_shndx == SHN_COMMON)
   1562  1.6  christos 	    isec = bfd_com_section_ptr;
   1563  1.6  christos 	  else
   1564  1.6  christos 	    isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
   1565  1.1  christos 
   1566  1.6  christos 	  *secpp = isec;
   1567  1.6  christos 	}
   1568  1.1  christos 
   1569  1.1  christos       if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd,
   1570  1.6  christos 				     input_section, data, internal_relocs,
   1571  1.6  christos 				     isymbuf, sections))
   1572  1.6  christos 	goto error_return;
   1573  1.1  christos 
   1574  1.1  christos       if (sections != NULL)
   1575  1.6  christos 	free (sections);
   1576  1.1  christos       if (isymbuf != NULL
   1577  1.6  christos 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
   1578  1.6  christos 	free (isymbuf);
   1579  1.1  christos       if (elf_section_data (input_section)->relocs != internal_relocs)
   1580  1.6  christos 	free (internal_relocs);
   1581  1.1  christos     }
   1582  1.1  christos 
   1583  1.1  christos   return data;
   1584  1.1  christos 
   1585  1.1  christos  error_return:
   1586  1.1  christos   if (sections != NULL)
   1587  1.1  christos     free (sections);
   1588  1.1  christos   if (isymbuf != NULL
   1589  1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1590  1.1  christos     free (isymbuf);
   1591  1.1  christos   if (internal_relocs != NULL
   1592  1.1  christos       && elf_section_data (input_section)->relocs != internal_relocs)
   1593  1.1  christos     free (internal_relocs);
   1594  1.1  christos   return NULL;
   1595  1.1  christos }
   1596  1.1  christos 
   1597  1.1  christos /* Assorted hash table functions.  */
   1598  1.1  christos 
   1599  1.1  christos /* Initialize an entry in the link hash table.  */
   1600  1.1  christos 
   1601  1.1  christos /* Create an entry in an CR16 ELF linker hash table.  */
   1602  1.1  christos 
   1603  1.1  christos static struct bfd_hash_entry *
   1604  1.1  christos elf32_cr16_link_hash_newfunc (struct bfd_hash_entry *entry,
   1605  1.6  christos 			      struct bfd_hash_table *table,
   1606  1.6  christos 			      const char *string)
   1607  1.1  christos {
   1608  1.1  christos   struct elf32_cr16_link_hash_entry *ret =
   1609  1.1  christos     (struct elf32_cr16_link_hash_entry *) entry;
   1610  1.1  christos 
   1611  1.1  christos   /* Allocate the structure if it has not already been allocated by a
   1612  1.1  christos      subclass.  */
   1613  1.1  christos   if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
   1614  1.1  christos     ret = ((struct elf32_cr16_link_hash_entry *)
   1615  1.6  christos 	   bfd_hash_allocate (table,
   1616  1.6  christos 			      sizeof (struct elf32_cr16_link_hash_entry)));
   1617  1.1  christos   if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
   1618  1.1  christos     return (struct bfd_hash_entry *) ret;
   1619  1.1  christos 
   1620  1.1  christos   /* Call the allocation method of the superclass.  */
   1621  1.1  christos   ret = ((struct elf32_cr16_link_hash_entry *)
   1622  1.6  christos 	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
   1623  1.6  christos 				     table, string));
   1624  1.1  christos   if (ret != (struct elf32_cr16_link_hash_entry *) NULL)
   1625  1.1  christos     {
   1626  1.1  christos       ret->direct_calls = 0;
   1627  1.1  christos       ret->stack_size = 0;
   1628  1.1  christos       ret->movm_args = 0;
   1629  1.1  christos       ret->movm_stack_size = 0;
   1630  1.1  christos       ret->flags = 0;
   1631  1.1  christos       ret->value = 0;
   1632  1.1  christos     }
   1633  1.1  christos 
   1634  1.1  christos   return (struct bfd_hash_entry *) ret;
   1635  1.1  christos }
   1636  1.1  christos 
   1637  1.1  christos /* Create an cr16 ELF linker hash table.  */
   1638  1.1  christos 
   1639  1.1  christos static struct bfd_link_hash_table *
   1640  1.1  christos elf32_cr16_link_hash_table_create (bfd *abfd)
   1641  1.1  christos {
   1642  1.1  christos   struct elf_link_hash_table *ret;
   1643  1.1  christos   bfd_size_type amt = sizeof (struct elf_link_hash_table);
   1644  1.1  christos 
   1645  1.3  christos   ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
   1646  1.1  christos   if (ret == (struct elf_link_hash_table *) NULL)
   1647  1.1  christos     return NULL;
   1648  1.1  christos 
   1649  1.1  christos   if (!_bfd_elf_link_hash_table_init (ret, abfd,
   1650  1.6  christos 				      elf32_cr16_link_hash_newfunc,
   1651  1.6  christos 				      sizeof (struct elf32_cr16_link_hash_entry),
   1652  1.1  christos 				      GENERIC_ELF_DATA))
   1653  1.1  christos     {
   1654  1.1  christos       free (ret);
   1655  1.1  christos       return NULL;
   1656  1.1  christos     }
   1657  1.1  christos 
   1658  1.1  christos   return &ret->root;
   1659  1.1  christos }
   1660  1.1  christos 
   1661  1.1  christos static unsigned long
   1662  1.1  christos elf_cr16_mach (flagword flags)
   1663  1.1  christos {
   1664  1.1  christos   switch (flags)
   1665  1.1  christos     {
   1666  1.1  christos       case EM_CR16:
   1667  1.1  christos       default:
   1668  1.1  christos       return bfd_mach_cr16;
   1669  1.1  christos     }
   1670  1.1  christos }
   1671  1.1  christos 
   1672  1.1  christos /* The final processing done just before writing out a CR16 ELF object
   1673  1.1  christos    file.  This gets the CR16 architecture right based on the machine
   1674  1.1  christos    number.  */
   1675  1.1  christos 
   1676  1.1  christos static void
   1677  1.1  christos _bfd_cr16_elf_final_write_processing (bfd *abfd,
   1678  1.6  christos 				      bfd_boolean linker ATTRIBUTE_UNUSED)
   1679  1.1  christos {
   1680  1.1  christos   unsigned long val;
   1681  1.1  christos   switch (bfd_get_mach (abfd))
   1682  1.1  christos     {
   1683  1.1  christos      default:
   1684  1.1  christos      case bfd_mach_cr16:
   1685  1.6  christos 	val = EM_CR16;
   1686  1.6  christos 	break;
   1687  1.1  christos     }
   1688  1.1  christos 
   1689  1.1  christos 
   1690  1.1  christos  elf_elfheader (abfd)->e_flags |= val;
   1691  1.1  christos }
   1692  1.1  christos 
   1693  1.1  christos 
   1694  1.1  christos static bfd_boolean
   1695  1.1  christos _bfd_cr16_elf_object_p (bfd *abfd)
   1696  1.1  christos {
   1697  1.1  christos   bfd_default_set_arch_mach (abfd, bfd_arch_cr16,
   1698  1.6  christos 			     elf_cr16_mach (elf_elfheader (abfd)->e_flags));
   1699  1.1  christos   return TRUE;
   1700  1.1  christos }
   1701  1.1  christos 
   1702  1.1  christos /* Merge backend specific data from an object file to the output
   1703  1.1  christos    object file when linking.  */
   1704  1.1  christos 
   1705  1.1  christos static bfd_boolean
   1706  1.6  christos _bfd_cr16_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   1707  1.1  christos {
   1708  1.6  christos   bfd *obfd = info->output_bfd;
   1709  1.6  christos 
   1710  1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
   1711  1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
   1712  1.1  christos     return TRUE;
   1713  1.1  christos 
   1714  1.1  christos   if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
   1715  1.1  christos       && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
   1716  1.1  christos     {
   1717  1.1  christos       if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
   1718  1.6  christos 			       bfd_get_mach (ibfd)))
   1719  1.6  christos 	 return FALSE;
   1720  1.1  christos      }
   1721  1.1  christos 
   1722  1.1  christos   return TRUE;
   1723  1.1  christos }
   1724  1.1  christos 
   1725  1.1  christos 
   1726  1.1  christos /* This function handles relaxing for the CR16.
   1727  1.1  christos 
   1728  1.1  christos    There's quite a few relaxing opportunites available on the CR16:
   1729  1.1  christos 
   1730  1.6  christos 	* bcond:24 -> bcond:16				      1 byte
   1731  1.6  christos 	* bcond:16 -> bcond:8				      1 byte
   1732  1.6  christos 	* arithmetic imm32 -> arithmetic imm20		      12 bits
   1733  1.6  christos 	* arithmetic imm20/imm16 -> arithmetic imm4	      12/16 bits
   1734  1.1  christos 
   1735  1.1  christos    Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
   1736  1.1  christos 
   1737  1.1  christos static bfd_boolean
   1738  1.1  christos elf32_cr16_relax_section (bfd *abfd, asection *sec,
   1739  1.6  christos 			  struct bfd_link_info *link_info, bfd_boolean *again)
   1740  1.1  christos {
   1741  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1742  1.1  christos   Elf_Internal_Rela *internal_relocs;
   1743  1.1  christos   Elf_Internal_Rela *irel, *irelend;
   1744  1.1  christos   bfd_byte *contents = NULL;
   1745  1.1  christos   Elf_Internal_Sym *isymbuf = NULL;
   1746  1.1  christos 
   1747  1.1  christos   /* Assume nothing changes.  */
   1748  1.1  christos   *again = FALSE;
   1749  1.1  christos 
   1750  1.1  christos   /* We don't have to do anything for a relocatable link, if
   1751  1.1  christos      this section does not have relocs, or if this is not a
   1752  1.1  christos      code section.  */
   1753  1.3  christos   if (bfd_link_relocatable (link_info)
   1754  1.1  christos       || (sec->flags & SEC_RELOC) == 0
   1755  1.1  christos       || sec->reloc_count == 0
   1756  1.1  christos       || (sec->flags & SEC_CODE) == 0)
   1757  1.1  christos     return TRUE;
   1758  1.1  christos 
   1759  1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1760  1.1  christos 
   1761  1.1  christos   /* Get a copy of the native relocations.  */
   1762  1.1  christos   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
   1763  1.6  christos 					       link_info->keep_memory);
   1764  1.1  christos   if (internal_relocs == NULL)
   1765  1.1  christos     goto error_return;
   1766  1.1  christos 
   1767  1.1  christos   /* Walk through them looking for relaxing opportunities.  */
   1768  1.1  christos   irelend = internal_relocs + sec->reloc_count;
   1769  1.1  christos   for (irel = internal_relocs; irel < irelend; irel++)
   1770  1.1  christos     {
   1771  1.1  christos       bfd_vma symval;
   1772  1.1  christos 
   1773  1.1  christos       /* If this isn't something that can be relaxed, then ignore
   1774  1.6  christos 	 this reloc.  */
   1775  1.1  christos       if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP16
   1776  1.6  christos 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24
   1777  1.6  christos 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM32
   1778  1.6  christos 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM20
   1779  1.6  christos 	  && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM16)
   1780  1.6  christos 	continue;
   1781  1.1  christos 
   1782  1.1  christos       /* Get the section contents if we haven't done so already.  */
   1783  1.1  christos       if (contents == NULL)
   1784  1.6  christos 	{
   1785  1.6  christos 	  /* Get cached copy if it exists.  */
   1786  1.6  christos 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
   1787  1.6  christos 	    contents = elf_section_data (sec)->this_hdr.contents;
   1788  1.6  christos 	  /* Go get them off disk.  */
   1789  1.6  christos 	  else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
   1790  1.6  christos 	    goto error_return;
   1791  1.6  christos 	}
   1792  1.1  christos 
   1793  1.1  christos       /* Read this BFD's local symbols if we haven't done so already.  */
   1794  1.1  christos       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
   1795  1.6  christos 	{
   1796  1.6  christos 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1797  1.6  christos 	  if (isymbuf == NULL)
   1798  1.6  christos 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
   1799  1.6  christos 					    symtab_hdr->sh_info, 0,
   1800  1.6  christos 					    NULL, NULL, NULL);
   1801  1.6  christos 	  if (isymbuf == NULL)
   1802  1.6  christos 	    goto error_return;
   1803  1.6  christos 	}
   1804  1.1  christos 
   1805  1.1  christos       /* Get the value of the symbol referred to by the reloc.  */
   1806  1.1  christos       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
   1807  1.6  christos 	{
   1808  1.6  christos 	  /* A local symbol.  */
   1809  1.6  christos 	  Elf_Internal_Sym *isym;
   1810  1.6  christos 	  asection *sym_sec;
   1811  1.6  christos 
   1812  1.6  christos 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
   1813  1.6  christos 	  if (isym->st_shndx == SHN_UNDEF)
   1814  1.6  christos 	    sym_sec = bfd_und_section_ptr;
   1815  1.6  christos 	  else if (isym->st_shndx == SHN_ABS)
   1816  1.6  christos 	    sym_sec = bfd_abs_section_ptr;
   1817  1.6  christos 	  else if (isym->st_shndx == SHN_COMMON)
   1818  1.6  christos 	    sym_sec = bfd_com_section_ptr;
   1819  1.6  christos 	  else
   1820  1.6  christos 	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
   1821  1.6  christos 	  symval = (isym->st_value
   1822  1.6  christos 		    + sym_sec->output_section->vma
   1823  1.6  christos 		    + sym_sec->output_offset);
   1824  1.6  christos 	}
   1825  1.1  christos       else
   1826  1.6  christos 	{
   1827  1.6  christos 	  unsigned long indx;
   1828  1.6  christos 	  struct elf_link_hash_entry *h;
   1829  1.6  christos 
   1830  1.6  christos 	  /* An external symbol.  */
   1831  1.6  christos 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
   1832  1.6  christos 	  h = elf_sym_hashes (abfd)[indx];
   1833  1.6  christos 	  BFD_ASSERT (h != NULL);
   1834  1.6  christos 
   1835  1.6  christos 	  if (h->root.type != bfd_link_hash_defined
   1836  1.6  christos 	      && h->root.type != bfd_link_hash_defweak)
   1837  1.6  christos 	    /* This appears to be a reference to an undefined
   1838  1.6  christos 	       symbol.  Just ignore it--it will be caught by the
   1839  1.6  christos 	       regular reloc processing.  */
   1840  1.6  christos 	    continue;
   1841  1.6  christos 
   1842  1.6  christos 	  symval = (h->root.u.def.value
   1843  1.6  christos 		    + h->root.u.def.section->output_section->vma
   1844  1.6  christos 		    + h->root.u.def.section->output_offset);
   1845  1.6  christos 	}
   1846  1.1  christos 
   1847  1.1  christos       /* For simplicity of coding, we are going to modify the section
   1848  1.6  christos 	 contents, the section relocs, and the BFD symbol table.  We
   1849  1.6  christos 	 must tell the rest of the code not to free up this
   1850  1.6  christos 	 information.  It would be possible to instead create a table
   1851  1.6  christos 	 of changes which have to be made, as is done in coff-mips.c;
   1852  1.6  christos 	 that would be more work, but would require less memory when
   1853  1.6  christos 	 the linker is run.  */
   1854  1.1  christos 
   1855  1.1  christos       /* Try to turn a 24  branch/call into a 16bit relative
   1856  1.6  christos 	 branch/call.  */
   1857  1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24)
   1858  1.6  christos 	{
   1859  1.6  christos 	  bfd_vma value = symval;
   1860  1.1  christos 
   1861  1.6  christos 	  /* Deal with pc-relative gunk.  */
   1862  1.6  christos 	  value -= (sec->output_section->vma + sec->output_offset);
   1863  1.6  christos 	  value -= irel->r_offset;
   1864  1.6  christos 	  value += irel->r_addend;
   1865  1.6  christos 
   1866  1.6  christos 	  /* See if the value will fit in 16 bits, note the high value is
   1867  1.6  christos 	     0xfffe + 2 as the target will be two bytes closer if we are
   1868  1.6  christos 	     able to relax.  */
   1869  1.6  christos 	  if ((long) value < 0x10000 && (long) value > -0x10002)
   1870  1.6  christos 	    {
   1871  1.6  christos 	      unsigned int code;
   1872  1.6  christos 
   1873  1.6  christos 	      /* Get the opcode.  */
   1874  1.6  christos 	      code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset);
   1875  1.6  christos 
   1876  1.6  christos 	      /* Verify it's a 'bcond' and fix the opcode.  */
   1877  1.6  christos 	      if ((code  & 0xffff) == 0x0010)
   1878  1.6  christos 		bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset);
   1879  1.6  christos 	      else
   1880  1.6  christos 		continue;
   1881  1.6  christos 
   1882  1.6  christos 	      /* Note that we've changed the relocs, section contents, etc.  */
   1883  1.6  christos 	      elf_section_data (sec)->relocs = internal_relocs;
   1884  1.6  christos 	      elf_section_data (sec)->this_hdr.contents = contents;
   1885  1.6  christos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1886  1.6  christos 
   1887  1.6  christos 	      /* Fix the relocation's type.  */
   1888  1.6  christos 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1889  1.6  christos 					   R_CR16_DISP16);
   1890  1.6  christos 
   1891  1.6  christos 	      /* Delete two bytes of data.  */
   1892  1.6  christos 	      if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
   1893  1.6  christos 						   irel->r_offset + 2, 2))
   1894  1.6  christos 		goto error_return;
   1895  1.6  christos 
   1896  1.6  christos 	      /* That will change things, so, we should relax again.
   1897  1.6  christos 		 Note that this is not required, and it may be slow.  */
   1898  1.6  christos 	      *again = TRUE;
   1899  1.6  christos 	    }
   1900  1.6  christos 	}
   1901  1.1  christos 
   1902  1.1  christos       /* Try to turn a 16bit pc-relative branch into an
   1903  1.6  christos 	 8bit pc-relative branch.  */
   1904  1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16)
   1905  1.6  christos 	{
   1906  1.6  christos 	  bfd_vma value = symval;
   1907  1.1  christos 
   1908  1.6  christos 	  /* Deal with pc-relative gunk.  */
   1909  1.6  christos 	  value -= (sec->output_section->vma + sec->output_offset);
   1910  1.6  christos 	  value -= irel->r_offset;
   1911  1.6  christos 	  value += irel->r_addend;
   1912  1.6  christos 
   1913  1.6  christos 	  /* See if the value will fit in 8 bits, note the high value is
   1914  1.6  christos 	     0xfc + 2 as the target will be two bytes closer if we are
   1915  1.6  christos 	     able to relax.  */
   1916  1.6  christos 	  /*if ((long) value < 0x1fa && (long) value > -0x100) REVISIT:range */
   1917  1.6  christos 	  if ((long) value < 0xfa && (long) value > -0x100)
   1918  1.6  christos 	    {
   1919  1.6  christos 	      unsigned short code;
   1920  1.6  christos 
   1921  1.6  christos 	      /* Get the opcode.  */
   1922  1.6  christos 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   1923  1.6  christos 
   1924  1.6  christos 	      /* Verify it's a 'bcond' and fix the opcode.  */
   1925  1.6  christos 	      if ((code & 0xff0f) == 0x1800)
   1926  1.6  christos 		bfd_put_16 (abfd, (code & 0xf0f0), contents + irel->r_offset);
   1927  1.6  christos 	      else
   1928  1.6  christos 		continue;
   1929  1.6  christos 
   1930  1.6  christos 	      /* Note that we've changed the relocs, section contents, etc.  */
   1931  1.6  christos 	      elf_section_data (sec)->relocs = internal_relocs;
   1932  1.6  christos 	      elf_section_data (sec)->this_hdr.contents = contents;
   1933  1.6  christos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1934  1.6  christos 
   1935  1.6  christos 	      /* Fix the relocation's type.  */
   1936  1.6  christos 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1937  1.6  christos 					   R_CR16_DISP8);
   1938  1.6  christos 
   1939  1.6  christos 	      /* Delete two bytes of data.  */
   1940  1.6  christos 	      if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
   1941  1.6  christos 						   irel->r_offset + 2, 2))
   1942  1.6  christos 		goto error_return;
   1943  1.6  christos 
   1944  1.6  christos 	      /* That will change things, so, we should relax again.
   1945  1.6  christos 		 Note that this is not required, and it may be slow.  */
   1946  1.6  christos 	      *again = TRUE;
   1947  1.6  christos 	    }
   1948  1.6  christos 	}
   1949  1.1  christos 
   1950  1.1  christos       /* Try to turn a 32-bit IMM address into a 20/16-bit IMM address */
   1951  1.1  christos       if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32)
   1952  1.6  christos 	{
   1953  1.6  christos 	  bfd_vma value = symval;
   1954  1.6  christos 	  unsigned short is_add_mov = 0;
   1955  1.6  christos 	  bfd_vma value1 = 0;
   1956  1.6  christos 
   1957  1.6  christos 	  /* Get the existing value from the mcode */
   1958  1.6  christos 	  value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
   1959  1.6  christos 		   |(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
   1960  1.6  christos 
   1961  1.6  christos 	  /* See if the value will fit in 20 bits.  */
   1962  1.6  christos 	  if ((long) (value + value1) < 0xfffff && (long) (value + value1) > 0)
   1963  1.6  christos 	    {
   1964  1.6  christos 	      unsigned short code;
   1965  1.6  christos 
   1966  1.6  christos 	      /* Get the opcode.  */
   1967  1.6  christos 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   1968  1.6  christos 
   1969  1.6  christos 	      /* Verify it's a 'arithmetic ADDD or MOVD instruction'.
   1970  1.6  christos 		 For ADDD and MOVD only, convert to IMM32 -> IMM20.  */
   1971  1.6  christos 
   1972  1.6  christos 	      if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020))
   1973  1.6  christos 		 is_add_mov = 1;
   1974  1.6  christos 
   1975  1.6  christos 	      if (is_add_mov)
   1976  1.6  christos 		{
   1977  1.6  christos 		  /* Note that we've changed the relocs, section contents,
   1978  1.6  christos 		     etc.  */
   1979  1.6  christos 		  elf_section_data (sec)->relocs = internal_relocs;
   1980  1.6  christos 		  elf_section_data (sec)->this_hdr.contents = contents;
   1981  1.6  christos 		  symtab_hdr->contents = (unsigned char *) isymbuf;
   1982  1.6  christos 
   1983  1.6  christos 		  /* Fix the opcode.  */
   1984  1.6  christos 		  if ((code & 0xfff0) == 0x0070) /* For movd.  */
   1985  1.6  christos 		    bfd_put_8 (abfd, 0x05, contents + irel->r_offset + 1);
   1986  1.6  christos 		  else				 /* code == 0x0020 for addd.  */
   1987  1.6  christos 		    bfd_put_8 (abfd, 0x04, contents + irel->r_offset + 1);
   1988  1.6  christos 
   1989  1.6  christos 		  bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset);
   1990  1.6  christos 
   1991  1.6  christos 		  /* If existing value is nagavive adjust approriately
   1992  1.6  christos 		     place the 16-20bits (ie 4 bit) in new opcode,
   1993  1.6  christos 		     as the 0xffffxxxx, the higher 2 byte values removed. */
   1994  1.6  christos 		  if (value1 & 0x80000000)
   1995  1.6  christos 		    bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
   1996  1.6  christos 		  else
   1997  1.6  christos 		    bfd_put_8 (abfd, (((value1 >> 16)&0xf) | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
   1998  1.6  christos 
   1999  1.6  christos 		  /* Fix the relocation's type.  */
   2000  1.6  christos 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   2001  1.6  christos 					       R_CR16_IMM20);
   2002  1.6  christos 
   2003  1.6  christos 		  /* Delete two bytes of data.  */
   2004  1.6  christos 		  if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
   2005  1.6  christos 						      irel->r_offset + 2, 2))
   2006  1.6  christos 		    goto error_return;
   2007  1.6  christos 
   2008  1.6  christos 		  /* That will change things, so, we should relax again.
   2009  1.6  christos 		     Note that this is not required, and it may be slow.  */
   2010  1.6  christos 		  *again = TRUE;
   2011  1.6  christos 		}
   2012  1.6  christos 	    }
   2013  1.6  christos 
   2014  1.6  christos 	  /* See if the value will fit in 16 bits.  */
   2015  1.6  christos 	  if ((!is_add_mov)
   2016  1.6  christos 	      && ((long)(value + value1) < 0x7fff && (long)(value + value1) > 0))
   2017  1.6  christos 	    {
   2018  1.6  christos 	      unsigned short code;
   2019  1.6  christos 
   2020  1.6  christos 	      /* Get the opcode.  */
   2021  1.6  christos 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   2022  1.6  christos 
   2023  1.6  christos 	      /* Note that we've changed the relocs, section contents, etc.  */
   2024  1.6  christos 	      elf_section_data (sec)->relocs = internal_relocs;
   2025  1.6  christos 	      elf_section_data (sec)->this_hdr.contents = contents;
   2026  1.6  christos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   2027  1.6  christos 
   2028  1.6  christos 	      /* Fix the opcode.  */
   2029  1.6  christos 	      if ((code & 0xf0) == 0x70)	  /* For movd.  */
   2030  1.6  christos 		bfd_put_8 (abfd, 0x54, contents + irel->r_offset + 1);
   2031  1.6  christos 	      else if ((code & 0xf0) == 0x20)	  /* For addd.  */
   2032  1.6  christos 		bfd_put_8 (abfd, 0x60, contents + irel->r_offset + 1);
   2033  1.6  christos 	      else if ((code & 0xf0) == 0x90)	  /* For cmpd.  */
   2034  1.6  christos 		bfd_put_8 (abfd, 0x56, contents + irel->r_offset + 1);
   2035  1.6  christos 	      else
   2036  1.6  christos 		continue;
   2037  1.6  christos 
   2038  1.6  christos 	      bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset);
   2039  1.6  christos 
   2040  1.6  christos 	      /* If existing value is nagavive adjust approriately
   2041  1.6  christos 		 place the 12-16bits (ie 4 bit) in new opcode,
   2042  1.6  christos 		 as the 0xfffffxxx, the higher 2 byte values removed. */
   2043  1.6  christos 	      if (value1 & 0x80000000)
   2044  1.6  christos 		bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
   2045  1.6  christos 	      else
   2046  1.6  christos 		bfd_put_16 (abfd, value1, contents + irel->r_offset + 2);
   2047  1.6  christos 
   2048  1.6  christos 
   2049  1.6  christos 	      /* Fix the relocation's type.  */
   2050  1.6  christos 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   2051  1.6  christos 					   R_CR16_IMM16);
   2052  1.6  christos 
   2053  1.6  christos 	      /* Delete two bytes of data.  */
   2054  1.6  christos 	      if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
   2055  1.6  christos 						  irel->r_offset + 2, 2))
   2056  1.6  christos 		goto error_return;
   2057  1.6  christos 
   2058  1.6  christos 	      /* That will change things, so, we should relax again.
   2059  1.6  christos 		 Note that this is not required, and it may be slow.  */
   2060  1.6  christos 	      *again = TRUE;
   2061  1.6  christos 	    }
   2062  1.6  christos 	}
   2063  1.1  christos 
   2064  1.1  christos #if 0
   2065  1.1  christos       /* Try to turn a 16bit immediate address into a 4bit
   2066  1.6  christos 	 immediate address.  */
   2067  1.3  christos       if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
   2068  1.6  christos 	  || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16))
   2069  1.6  christos 	{
   2070  1.6  christos 	  bfd_vma value = symval;
   2071  1.6  christos 	  bfd_vma value1 = 0;
   2072  1.6  christos 
   2073  1.6  christos 	  /* Get the existing value from the mcode */
   2074  1.6  christos 	  value1 = ((bfd_get_16 (abfd, contents + irel->r_offset + 2) & 0xffff));
   2075  1.6  christos 
   2076  1.6  christos 	  if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
   2077  1.6  christos 	    {
   2078  1.6  christos 	      value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1) & 0xf000) << 0x4);
   2079  1.6  christos 	    }
   2080  1.6  christos 
   2081  1.6  christos 	  /* See if the value will fit in 4 bits.  */
   2082  1.6  christos 	  if ((((long) (value + value1)) < 0xf)
   2083  1.6  christos 	      && (((long) (value + value1)) > 0))
   2084  1.6  christos 	    {
   2085  1.6  christos 	      unsigned short code;
   2086  1.6  christos 
   2087  1.6  christos 	      /* Get the opcode.  */
   2088  1.6  christos 	      code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
   2089  1.6  christos 
   2090  1.6  christos 	      /* Note that we've changed the relocs, section contents, etc.  */
   2091  1.6  christos 	      elf_section_data (sec)->relocs = internal_relocs;
   2092  1.6  christos 	      elf_section_data (sec)->this_hdr.contents = contents;
   2093  1.6  christos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   2094  1.6  christos 
   2095  1.6  christos 	      /* Fix the opcode.  */
   2096  1.6  christos 	      if (((code & 0x0f00) == 0x0400) || ((code & 0x0f00) == 0x0500))
   2097  1.6  christos 		{
   2098  1.6  christos 		  if ((code & 0x0f00) == 0x0400)      /* For movd imm20.  */
   2099  1.6  christos 		    bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
   2100  1.6  christos 		  else				      /* For addd imm20.  */
   2101  1.6  christos 		    bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
   2102  1.6  christos 		  bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1);
   2103  1.6  christos 		}
   2104  1.6  christos 	      else
   2105  1.6  christos 		{
   2106  1.6  christos 		  if ((code & 0xfff0) == 0x56b0)       /*  For cmpd imm16.  */
   2107  1.6  christos 		    bfd_put_8 (abfd, 0x56, contents + irel->r_offset);
   2108  1.6  christos 		  else if ((code & 0xfff0) == 0x54b0)  /*  For movd imm16.  */
   2109  1.6  christos 		    bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
   2110  1.6  christos 		  else if ((code & 0xfff0) == 0x58b0)  /*  For movb imm16.  */
   2111  1.6  christos 		    bfd_put_8 (abfd, 0x58, contents + irel->r_offset);
   2112  1.6  christos 		  else if ((code & 0xfff0) == 0x5Ab0)  /*  For movw imm16.  */
   2113  1.6  christos 		    bfd_put_8 (abfd, 0x5A, contents + irel->r_offset);
   2114  1.6  christos 		  else if ((code & 0xfff0) == 0x60b0)  /*  For addd imm16.  */
   2115  1.6  christos 		    bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
   2116  1.6  christos 		  else if ((code & 0xfff0) == 0x30b0)  /*  For addb imm16.  */
   2117  1.6  christos 		    bfd_put_8 (abfd, 0x30, contents + irel->r_offset);
   2118  1.6  christos 		  else if ((code & 0xfff0) == 0x2Cb0)  /*  For addub imm16.  */
   2119  1.6  christos 		    bfd_put_8 (abfd, 0x2C, contents + irel->r_offset);
   2120  1.6  christos 		  else if ((code & 0xfff0) == 0x32b0)  /*  For adduw imm16.  */
   2121  1.6  christos 		    bfd_put_8 (abfd, 0x32, contents + irel->r_offset);
   2122  1.6  christos 		  else if ((code & 0xfff0) == 0x38b0)  /*  For subb imm16.  */
   2123  1.6  christos 		    bfd_put_8 (abfd, 0x38, contents + irel->r_offset);
   2124  1.6  christos 		  else if ((code & 0xfff0) == 0x3Cb0)  /*  For subcb imm16.  */
   2125  1.6  christos 		    bfd_put_8 (abfd, 0x3C, contents + irel->r_offset);
   2126  1.6  christos 		  else if ((code & 0xfff0) == 0x3Fb0)  /*  For subcw imm16.  */
   2127  1.6  christos 		    bfd_put_8 (abfd, 0x3F, contents + irel->r_offset);
   2128  1.6  christos 		  else if ((code & 0xfff0) == 0x3Ab0)  /*  For subw imm16.  */
   2129  1.6  christos 		    bfd_put_8 (abfd, 0x3A, contents + irel->r_offset);
   2130  1.6  christos 		  else if ((code & 0xfff0) == 0x50b0)  /*  For cmpb imm16.  */
   2131  1.6  christos 		    bfd_put_8 (abfd, 0x50, contents + irel->r_offset);
   2132  1.6  christos 		  else if ((code & 0xfff0) == 0x52b0)  /*  For cmpw imm16.  */
   2133  1.6  christos 		    bfd_put_8 (abfd, 0x52, contents + irel->r_offset);
   2134  1.6  christos 		  else
   2135  1.6  christos 		    continue;
   2136  1.6  christos 
   2137  1.6  christos 		  bfd_put_8 (abfd, (code & 0xf), contents + irel->r_offset + 1);
   2138  1.6  christos 		}
   2139  1.6  christos 
   2140  1.6  christos 	      /* Fix the relocation's type.  */
   2141  1.6  christos 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   2142  1.6  christos 					   R_CR16_IMM4);
   2143  1.6  christos 
   2144  1.6  christos 	      /* Delete two bytes of data.  */
   2145  1.6  christos 	      if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
   2146  1.6  christos 						  irel->r_offset + 2, 2))
   2147  1.6  christos 		goto error_return;
   2148  1.6  christos 
   2149  1.6  christos 	      /* That will change things, so, we should relax again.
   2150  1.6  christos 		 Note that this is not required, and it may be slow.  */
   2151  1.6  christos 	      *again = TRUE;
   2152  1.6  christos 	    }
   2153  1.6  christos 	}
   2154  1.1  christos #endif
   2155  1.1  christos     }
   2156  1.1  christos 
   2157  1.1  christos   if (isymbuf != NULL
   2158  1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   2159  1.1  christos     {
   2160  1.1  christos       if (! link_info->keep_memory)
   2161  1.6  christos 	free (isymbuf);
   2162  1.1  christos       else
   2163  1.1  christos        /* Cache the symbols for elf_link_input_bfd.  */
   2164  1.1  christos        symtab_hdr->contents = (unsigned char *) isymbuf;
   2165  1.1  christos     }
   2166  1.1  christos 
   2167  1.1  christos   if (contents != NULL
   2168  1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
   2169  1.1  christos     {
   2170  1.1  christos       if (! link_info->keep_memory)
   2171  1.6  christos 	free (contents);
   2172  1.1  christos       else
   2173  1.1  christos        /* Cache the section contents for elf_link_input_bfd.  */
   2174  1.1  christos        elf_section_data (sec)->this_hdr.contents = contents;
   2175  1.3  christos 
   2176  1.1  christos     }
   2177  1.1  christos 
   2178  1.1  christos   if (internal_relocs != NULL
   2179  1.1  christos       && elf_section_data (sec)->relocs != internal_relocs)
   2180  1.1  christos     free (internal_relocs);
   2181  1.1  christos 
   2182  1.1  christos   return TRUE;
   2183  1.1  christos 
   2184  1.1  christos  error_return:
   2185  1.1  christos   if (isymbuf != NULL
   2186  1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   2187  1.1  christos     free (isymbuf);
   2188  1.1  christos   if (contents != NULL
   2189  1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
   2190  1.1  christos     free (contents);
   2191  1.1  christos   if (internal_relocs != NULL
   2192  1.1  christos       && elf_section_data (sec)->relocs != internal_relocs)
   2193  1.1  christos     free (internal_relocs);
   2194  1.1  christos 
   2195  1.1  christos   return FALSE;
   2196  1.1  christos }
   2197  1.1  christos 
   2198  1.1  christos static asection *
   2199  1.1  christos elf32_cr16_gc_mark_hook (asection *sec,
   2200  1.6  christos 			 struct bfd_link_info *info,
   2201  1.6  christos 			 Elf_Internal_Rela *rel,
   2202  1.6  christos 			 struct elf_link_hash_entry *h,
   2203  1.6  christos 			 Elf_Internal_Sym *sym)
   2204  1.1  christos {
   2205  1.1  christos   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
   2206  1.1  christos }
   2207  1.1  christos 
   2208  1.1  christos /* Create dynamic sections when linking against a dynamic object.  */
   2209  1.1  christos 
   2210  1.1  christos static bfd_boolean
   2211  1.1  christos _bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   2212  1.1  christos {
   2213  1.1  christos   flagword   flags;
   2214  1.1  christos   asection * s;
   2215  1.1  christos   const struct elf_backend_data * bed = get_elf_backend_data (abfd);
   2216  1.6  christos   struct elf_link_hash_table *htab = elf_hash_table (info);
   2217  1.1  christos   int ptralign = 0;
   2218  1.1  christos 
   2219  1.1  christos   switch (bed->s->arch_size)
   2220  1.1  christos     {
   2221  1.1  christos     case 16:
   2222  1.1  christos       ptralign = 1;
   2223  1.1  christos       break;
   2224  1.1  christos 
   2225  1.1  christos     case 32:
   2226  1.1  christos       ptralign = 2;
   2227  1.1  christos       break;
   2228  1.1  christos 
   2229  1.1  christos     default:
   2230  1.1  christos       bfd_set_error (bfd_error_bad_value);
   2231  1.1  christos       return FALSE;
   2232  1.1  christos     }
   2233  1.1  christos 
   2234  1.1  christos   /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
   2235  1.1  christos      .rel[a].bss sections.  */
   2236  1.1  christos 
   2237  1.1  christos   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
   2238  1.6  christos 	   | SEC_LINKER_CREATED);
   2239  1.1  christos 
   2240  1.1  christos   s = bfd_make_section_anyway_with_flags (abfd,
   2241  1.1  christos 					  (bed->default_use_rela_p
   2242  1.1  christos 					   ? ".rela.plt" : ".rel.plt"),
   2243  1.1  christos 					  flags | SEC_READONLY);
   2244  1.6  christos   htab->srelplt = s;
   2245  1.1  christos   if (s == NULL
   2246  1.1  christos       || ! bfd_set_section_alignment (abfd, s, ptralign))
   2247  1.1  christos     return FALSE;
   2248  1.1  christos 
   2249  1.1  christos   if (! _bfd_cr16_elf_create_got_section (abfd, info))
   2250  1.1  christos     return FALSE;
   2251  1.1  christos 
   2252  1.1  christos   if (bed->want_dynbss)
   2253  1.1  christos     {
   2254  1.1  christos       /* The .dynbss section is a place to put symbols which are defined
   2255  1.6  christos 	 by dynamic objects, are referenced by regular objects, and are
   2256  1.6  christos 	 not functions.  We must allocate space for them in the process
   2257  1.6  christos 	 image and use a R_*_COPY reloc to tell the dynamic linker to
   2258  1.6  christos 	 initialize them at run time.  The linker script puts the .dynbss
   2259  1.6  christos 	 section into the .bss section of the final image.  */
   2260  1.1  christos       s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
   2261  1.1  christos 					      SEC_ALLOC | SEC_LINKER_CREATED);
   2262  1.1  christos       if (s == NULL)
   2263  1.6  christos 	return FALSE;
   2264  1.1  christos 
   2265  1.1  christos       /* The .rel[a].bss section holds copy relocs.  This section is not
   2266  1.6  christos 	 normally needed.  We need to create it here, though, so that the
   2267  1.6  christos 	 linker will map it to an output section.  We can't just create it
   2268  1.6  christos 	 only if we need it, because we will not know whether we need it
   2269  1.6  christos 	 until we have seen all the input files, and the first time the
   2270  1.6  christos 	 main linker code calls BFD after examining all the input files
   2271  1.6  christos 	 (size_dynamic_sections) the input sections have already been
   2272  1.6  christos 	 mapped to the output sections.  If the section turns out not to
   2273  1.6  christos 	 be needed, we can discard it later.  We will never need this
   2274  1.6  christos 	 section when generating a shared object, since they do not use
   2275  1.6  christos 	 copy relocs.  */
   2276  1.3  christos       if (! bfd_link_executable (info))
   2277  1.6  christos 	{
   2278  1.6  christos 	  s = bfd_make_section_anyway_with_flags (abfd,
   2279  1.1  christos 						  (bed->default_use_rela_p
   2280  1.1  christos 						   ? ".rela.bss" : ".rel.bss"),
   2281  1.1  christos 						  flags | SEC_READONLY);
   2282  1.6  christos 	  if (s == NULL
   2283  1.6  christos 	      || ! bfd_set_section_alignment (abfd, s, ptralign))
   2284  1.6  christos 	    return FALSE;
   2285  1.6  christos 	}
   2286  1.1  christos     }
   2287  1.1  christos 
   2288  1.1  christos   return TRUE;
   2289  1.1  christos }
   2290  1.1  christos 
   2291  1.1  christos /* Adjust a symbol defined by a dynamic object and referenced by a
   2293  1.1  christos    regular object.  The current definition is in some section of the
   2294  1.1  christos    dynamic object, but we're not including those sections.  We have to
   2295  1.1  christos    change the definition to something the rest of the link can
   2296  1.1  christos    understand.  */
   2297  1.1  christos 
   2298  1.1  christos static bfd_boolean
   2299  1.6  christos _bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
   2300  1.1  christos 				     struct elf_link_hash_entry * h)
   2301  1.1  christos {
   2302  1.1  christos   bfd * dynobj;
   2303  1.1  christos   asection * s;
   2304  1.1  christos 
   2305  1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   2306  1.1  christos 
   2307  1.1  christos   /* Make sure we know what is going on here.  */
   2308  1.6  christos   BFD_ASSERT (dynobj != NULL
   2309  1.6  christos 	      && (h->needs_plt
   2310  1.6  christos 		  || h->is_weakalias
   2311  1.6  christos 		  || (h->def_dynamic
   2312  1.6  christos 		      && h->ref_regular
   2313  1.1  christos 		      && !h->def_regular)));
   2314  1.1  christos 
   2315  1.1  christos   /* If this is a function, put it in the procedure linkage table.  We
   2316  1.1  christos      will fill in the contents of the procedure linkage table later,
   2317  1.1  christos      when we know the address of the .got section.  */
   2318  1.1  christos   if (h->type == STT_FUNC
   2319  1.1  christos       || h->needs_plt)
   2320  1.3  christos     {
   2321  1.6  christos       if (! bfd_link_executable (info)
   2322  1.6  christos 	  && !h->def_dynamic
   2323  1.6  christos 	  && !h->ref_dynamic)
   2324  1.6  christos 	{
   2325  1.6  christos 	  /* This case can occur if we saw a PLT reloc in an input
   2326  1.6  christos 	     file, but the symbol was never referred to by a dynamic
   2327  1.6  christos 	     object.  In such a case, we don't actually need to build
   2328  1.6  christos 	     a procedure linkage table, and we can just do a REL32
   2329  1.6  christos 	     reloc instead.  */
   2330  1.6  christos 	  BFD_ASSERT (h->needs_plt);
   2331  1.6  christos 	  return TRUE;
   2332  1.1  christos 	}
   2333  1.1  christos 
   2334  1.1  christos       /* Make sure this symbol is output as a dynamic symbol.  */
   2335  1.6  christos       if (h->dynindx == -1)
   2336  1.6  christos 	{
   2337  1.6  christos 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
   2338  1.6  christos 	    return FALSE;
   2339  1.1  christos 	}
   2340  1.1  christos 
   2341  1.6  christos       /* We also need to make an entry in the .got.plt section, which
   2342  1.1  christos 	 will be placed in the .got section by the linker script.  */
   2343  1.6  christos 
   2344  1.1  christos       s = elf_hash_table (info)->sgotplt;
   2345  1.1  christos       BFD_ASSERT (s != NULL);
   2346  1.1  christos       s->size += 4;
   2347  1.1  christos 
   2348  1.1  christos       /* We also need to make an entry in the .rela.plt section.  */
   2349  1.6  christos 
   2350  1.1  christos       s = elf_hash_table (info)->srelplt;
   2351  1.1  christos       BFD_ASSERT (s != NULL);
   2352  1.1  christos       s->size += sizeof (Elf32_External_Rela);
   2353  1.1  christos 
   2354  1.1  christos       return TRUE;
   2355  1.1  christos     }
   2356  1.1  christos 
   2357  1.1  christos   /* If this is a weak symbol, and there is a real definition, the
   2358  1.1  christos      processor independent code will have arranged for us to see the
   2359  1.6  christos      real definition first, and we can just use the same value.  */
   2360  1.1  christos   if (h->is_weakalias)
   2361  1.6  christos     {
   2362  1.6  christos       struct elf_link_hash_entry *def = weakdef (h);
   2363  1.6  christos       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
   2364  1.6  christos       h->root.u.def.section = def->root.u.def.section;
   2365  1.1  christos       h->root.u.def.value = def->root.u.def.value;
   2366  1.1  christos       return TRUE;
   2367  1.1  christos     }
   2368  1.1  christos 
   2369  1.1  christos   /* This is a reference to a symbol defined by a dynamic object which
   2370  1.1  christos      is not a function.  */
   2371  1.1  christos 
   2372  1.1  christos   /* If we are creating a shared library, we must presume that the
   2373  1.1  christos      only references to the symbol are via the global offset table.
   2374  1.1  christos      For such cases we need not do anything here; the relocations will
   2375  1.3  christos      be handled correctly by relocate_section.  */
   2376  1.1  christos   if (bfd_link_executable (info))
   2377  1.1  christos     return TRUE;
   2378  1.1  christos 
   2379  1.1  christos   /* If there are no references to this symbol that do not use the
   2380  1.1  christos      GOT, we don't need to generate a copy reloc.  */
   2381  1.1  christos   if (!h->non_got_ref)
   2382  1.1  christos     return TRUE;
   2383  1.1  christos 
   2384  1.1  christos   /* We must allocate the symbol in our .dynbss section, which will
   2385  1.1  christos      become part of the .bss section of the executable.  There will be
   2386  1.1  christos      an entry for this symbol in the .dynsym section.  The dynamic
   2387  1.1  christos      object will contain position independent code, so all references
   2388  1.1  christos      from the dynamic object to this symbol will go through the global
   2389  1.1  christos      offset table.  The dynamic linker will use the .dynsym entry to
   2390  1.1  christos      determine the address it must put in the global offset table, so
   2391  1.1  christos      both the dynamic object and the regular object will refer to the
   2392  1.1  christos      same memory location for the variable.  */
   2393  1.1  christos 
   2394  1.1  christos   s = bfd_get_linker_section (dynobj, ".dynbss");
   2395  1.1  christos   BFD_ASSERT (s != NULL);
   2396  1.1  christos 
   2397  1.1  christos   /* We must generate a R_CR16_COPY reloc to tell the dynamic linker to
   2398  1.1  christos      copy the initial value out of the dynamic object and into the
   2399  1.1  christos      runtime process image.  We need to remember the offset into the
   2400  1.1  christos      .rela.bss section we are going to use.  */
   2401  1.1  christos   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
   2402  1.1  christos     {
   2403  1.1  christos       asection * srel;
   2404  1.1  christos 
   2405  1.1  christos       srel = bfd_get_linker_section (dynobj, ".rela.bss");
   2406  1.1  christos       BFD_ASSERT (srel != NULL);
   2407  1.1  christos       srel->size += sizeof (Elf32_External_Rela);
   2408  1.1  christos       h->needs_copy = 1;
   2409  1.1  christos     }
   2410  1.3  christos 
   2411  1.1  christos   return _bfd_elf_adjust_dynamic_copy (info, h, s);
   2412  1.1  christos }
   2413  1.1  christos 
   2414  1.1  christos /* Set the sizes of the dynamic sections.  */
   2415  1.1  christos 
   2416  1.1  christos static bfd_boolean
   2417  1.6  christos _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
   2418  1.1  christos 				     struct bfd_link_info * info)
   2419  1.1  christos {
   2420  1.1  christos   bfd * dynobj;
   2421  1.1  christos   asection * s;
   2422  1.1  christos   bfd_boolean plt;
   2423  1.1  christos   bfd_boolean relocs;
   2424  1.1  christos   bfd_boolean reltext;
   2425  1.1  christos 
   2426  1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   2427  1.1  christos   BFD_ASSERT (dynobj != NULL);
   2428  1.1  christos 
   2429  1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   2430  1.1  christos     {
   2431  1.3  christos       /* Set the contents of the .interp section to the interpreter.  */
   2432  1.6  christos       if (bfd_link_executable (info) && !info->nointerp)
   2433  1.1  christos 	{
   2434  1.6  christos #if 0
   2435  1.6  christos 	  s = bfd_get_linker_section (dynobj, ".interp");
   2436  1.6  christos 	  BFD_ASSERT (s != NULL);
   2437  1.6  christos 	  s->size = sizeof ELF_DYNAMIC_INTERPRETER;
   2438  1.1  christos 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
   2439  1.6  christos #endif
   2440  1.1  christos 	}
   2441  1.1  christos     }
   2442  1.1  christos   else
   2443  1.1  christos     {
   2444  1.6  christos       /* We may have created entries in the .rela.got section.
   2445  1.6  christos 	 However, if we are not creating the dynamic sections, we will
   2446  1.6  christos 	 not actually use these entries.  Reset the size of .rela.got,
   2447  1.6  christos 	 which will cause it to get stripped from the output file
   2448  1.6  christos 	 below.  */
   2449  1.1  christos       s = elf_hash_table (info)->srelgot;
   2450  1.6  christos       if (s != NULL)
   2451  1.1  christos 	s->size = 0;
   2452  1.1  christos     }
   2453  1.1  christos 
   2454  1.1  christos   /* The check_relocs and adjust_dynamic_symbol entry points have
   2455  1.1  christos      determined the sizes of the various dynamic sections.  Allocate
   2456  1.1  christos      memory for them.  */
   2457  1.1  christos   plt = FALSE;
   2458  1.1  christos   relocs = FALSE;
   2459  1.1  christos   reltext = FALSE;
   2460  1.1  christos   for (s = dynobj->sections; s != NULL; s = s->next)
   2461  1.1  christos     {
   2462  1.1  christos       const char * name;
   2463  1.1  christos 
   2464  1.6  christos       if ((s->flags & SEC_LINKER_CREATED) == 0)
   2465  1.1  christos 	continue;
   2466  1.1  christos 
   2467  1.6  christos       /* It's OK to base decisions on the section name, because none
   2468  1.1  christos 	 of the dynobj section names depend upon the input files.  */
   2469  1.1  christos       name = bfd_get_section_name (dynobj, s);
   2470  1.1  christos 
   2471  1.6  christos       if (strcmp (name, ".plt") == 0)
   2472  1.6  christos 	{
   2473  1.6  christos 	  /* Remember whether there is a PLT.  */
   2474  1.6  christos 	  plt = s->size != 0;
   2475  1.1  christos 	}
   2476  1.6  christos       else if (CONST_STRNEQ (name, ".rela"))
   2477  1.6  christos 	{
   2478  1.6  christos 	  if (s->size != 0)
   2479  1.6  christos 	    {
   2480  1.6  christos 	      asection * target;
   2481  1.6  christos 
   2482  1.6  christos 	      /* Remember whether there are any reloc sections other
   2483  1.6  christos 		 than .rela.plt.  */
   2484  1.6  christos 	      if (strcmp (name, ".rela.plt") != 0)
   2485  1.6  christos 		{
   2486  1.6  christos 		  const char * outname;
   2487  1.6  christos 
   2488  1.6  christos 		  relocs = TRUE;
   2489  1.6  christos 
   2490  1.6  christos 		  /* If this relocation section applies to a read only
   2491  1.6  christos 		     section, then we probably need a DT_TEXTREL
   2492  1.6  christos 		     entry.  The entries in the .rela.plt section
   2493  1.6  christos 		     really apply to the .got section, which we
   2494  1.6  christos 		     created ourselves and so know is not readonly.  */
   2495  1.6  christos 		  outname = bfd_get_section_name (output_bfd,
   2496  1.6  christos 						  s->output_section);
   2497  1.6  christos 		  target = bfd_get_section_by_name (output_bfd, outname + 5);
   2498  1.6  christos 		  if (target != NULL
   2499  1.6  christos 		      && (target->flags & SEC_READONLY) != 0
   2500  1.6  christos 		      && (target->flags & SEC_ALLOC) != 0)
   2501  1.6  christos 		    reltext = TRUE;
   2502  1.6  christos 		}
   2503  1.6  christos 
   2504  1.6  christos 	      /* We use the reloc_count field as a counter if we need
   2505  1.6  christos 		 to copy relocs into the output file.  */
   2506  1.6  christos 	      s->reloc_count = 0;
   2507  1.6  christos 	    }
   2508  1.1  christos 	}
   2509  1.6  christos       else if (! CONST_STRNEQ (name, ".got")
   2510  1.6  christos 	       && strcmp (name, ".dynbss") != 0)
   2511  1.6  christos 	/* It's not one of our sections, so don't allocate space.  */
   2512  1.1  christos 	continue;
   2513  1.1  christos 
   2514  1.6  christos       if (s->size == 0)
   2515  1.6  christos 	{
   2516  1.6  christos 	  /* If we don't need this section, strip it from the
   2517  1.6  christos 	     output file.  This is mostly to handle .rela.bss and
   2518  1.6  christos 	     .rela.plt.  We must create both sections in
   2519  1.6  christos 	     create_dynamic_sections, because they must be created
   2520  1.6  christos 	     before the linker maps input sections to output
   2521  1.6  christos 	     sections.  The linker does that before
   2522  1.6  christos 	     adjust_dynamic_symbol is called, and it is that
   2523  1.6  christos 	     function which decides whether anything needs to go
   2524  1.6  christos 	     into these sections.  */
   2525  1.6  christos 	  s->flags |= SEC_EXCLUDE;
   2526  1.6  christos 	  continue;
   2527  1.1  christos 	}
   2528  1.6  christos 
   2529  1.6  christos 	if ((s->flags & SEC_HAS_CONTENTS) == 0)
   2530  1.1  christos 	  continue;
   2531  1.1  christos 
   2532  1.6  christos       /* Allocate memory for the section contents.  We use bfd_zalloc
   2533  1.6  christos 	 here in case unused entries are not reclaimed before the
   2534  1.6  christos 	 section's contents are written out.  This should not happen,
   2535  1.6  christos 	 but this way if it does, we get a R_CR16_NONE reloc
   2536  1.1  christos 	 instead of garbage.  */
   2537  1.1  christos       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
   2538  1.6  christos       if (s->contents == NULL)
   2539  1.1  christos 	return FALSE;
   2540  1.1  christos     }
   2541  1.1  christos 
   2542  1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   2543  1.1  christos     {
   2544  1.6  christos       /* Add some entries to the .dynamic section.  We fill in the
   2545  1.6  christos 	 values later, in _bfd_cr16_elf_finish_dynamic_sections,
   2546  1.6  christos 	 but we must add the entries now so that we get the correct
   2547  1.6  christos 	 size for the .dynamic section.  The DT_DEBUG entry is filled
   2548  1.3  christos 	 in by the dynamic linker and used by the debugger.  */
   2549  1.6  christos       if (! bfd_link_executable (info))
   2550  1.6  christos 	{
   2551  1.6  christos 	  if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
   2552  1.6  christos 	    return FALSE;
   2553  1.1  christos 	}
   2554  1.1  christos 
   2555  1.6  christos       if (plt)
   2556  1.6  christos 	{
   2557  1.6  christos 	  if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
   2558  1.6  christos 	      || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
   2559  1.6  christos 	      || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
   2560  1.6  christos 	      || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
   2561  1.6  christos 	    return FALSE;
   2562  1.1  christos 	}
   2563  1.1  christos 
   2564  1.6  christos       if (relocs)
   2565  1.6  christos 	{
   2566  1.6  christos 	  if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
   2567  1.6  christos 	      || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
   2568  1.6  christos 	      || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
   2569  1.6  christos 					      sizeof (Elf32_External_Rela)))
   2570  1.6  christos 	    return FALSE;
   2571  1.1  christos 	}
   2572  1.1  christos 
   2573  1.6  christos       if (reltext)
   2574  1.6  christos 	{
   2575  1.6  christos 	  if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
   2576  1.6  christos 	    return FALSE;
   2577  1.1  christos 	}
   2578  1.1  christos     }
   2579  1.1  christos 
   2580  1.1  christos   return TRUE;
   2581  1.1  christos }
   2582  1.1  christos 
   2583  1.1  christos /* Finish up dynamic symbol handling.  We set the contents of various
   2584  1.1  christos    dynamic sections here.  */
   2585  1.1  christos 
   2586  1.1  christos static bfd_boolean
   2587  1.6  christos _bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
   2588  1.6  christos 				     struct bfd_link_info * info,
   2589  1.6  christos 				     struct elf_link_hash_entry * h,
   2590  1.1  christos 				     Elf_Internal_Sym * sym)
   2591  1.1  christos {
   2592  1.1  christos   bfd * dynobj;
   2593  1.1  christos 
   2594  1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   2595  1.1  christos 
   2596  1.1  christos   if (h->got.offset != (bfd_vma) -1)
   2597  1.6  christos     {
   2598  1.6  christos       asection *	sgot;
   2599  1.1  christos       asection *	srel;
   2600  1.1  christos       Elf_Internal_Rela rel;
   2601  1.1  christos 
   2602  1.1  christos       /* This symbol has an entry in the global offset table.  Set it up.  */
   2603  1.6  christos 
   2604  1.6  christos       sgot = elf_hash_table (info)->sgot;
   2605  1.1  christos       srel = elf_hash_table (info)->srelgot;
   2606  1.1  christos       BFD_ASSERT (sgot != NULL && srel != NULL);
   2607  1.1  christos 
   2608  1.6  christos       rel.r_offset = (sgot->output_section->vma
   2609  1.6  christos 		      + sgot->output_offset
   2610  1.1  christos 		      + (h->got.offset & ~1));
   2611  1.1  christos 
   2612  1.6  christos       /* If this is a -Bsymbolic link, and the symbol is defined
   2613  1.6  christos 	 locally, we just want to emit a RELATIVE reloc.  Likewise if
   2614  1.6  christos 	 the symbol was forced to be local because of a version file.
   2615  1.6  christos 	 The entry in the global offset table will already have been
   2616  1.3  christos 	 initialized in the relocate_section function.  */
   2617  1.6  christos       if (bfd_link_executable (info)
   2618  1.6  christos 	  && (info->symbolic || h->dynindx == -1)
   2619  1.6  christos 	  && h->def_regular)
   2620  1.6  christos 	{
   2621  1.6  christos 	  rel.r_info = ELF32_R_INFO (0, R_CR16_GOT_REGREL20);
   2622  1.6  christos 	  rel.r_addend = (h->root.u.def.value
   2623  1.6  christos 			  + h->root.u.def.section->output_section->vma
   2624  1.6  christos 			  + h->root.u.def.section->output_offset);
   2625  1.1  christos 	}
   2626  1.6  christos       else
   2627  1.6  christos 	{
   2628  1.6  christos 	  bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
   2629  1.6  christos 	  rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
   2630  1.6  christos 	  rel.r_addend = 0;
   2631  1.1  christos 	}
   2632  1.1  christos 
   2633  1.6  christos       bfd_elf32_swap_reloca_out (output_bfd, &rel,
   2634  1.6  christos 				 (bfd_byte *) ((Elf32_External_Rela *) srel->contents
   2635  1.1  christos 					       + srel->reloc_count));
   2636  1.1  christos       ++ srel->reloc_count;
   2637  1.1  christos     }
   2638  1.1  christos 
   2639  1.1  christos   if (h->needs_copy)
   2640  1.6  christos     {
   2641  1.1  christos       asection *	s;
   2642  1.1  christos       Elf_Internal_Rela rel;
   2643  1.1  christos 
   2644  1.1  christos       /* This symbol needs a copy reloc.  Set it up.  */
   2645  1.6  christos       BFD_ASSERT (h->dynindx != -1
   2646  1.6  christos 		  && (h->root.type == bfd_link_hash_defined
   2647  1.1  christos 		      || h->root.type == bfd_link_hash_defweak));
   2648  1.1  christos 
   2649  1.1  christos       s = bfd_get_linker_section (dynobj, ".rela.bss");
   2650  1.1  christos       BFD_ASSERT (s != NULL);
   2651  1.1  christos 
   2652  1.6  christos       rel.r_offset = (h->root.u.def.value
   2653  1.6  christos 		      + h->root.u.def.section->output_section->vma
   2654  1.1  christos 		      + h->root.u.def.section->output_offset);
   2655  1.1  christos       rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
   2656  1.1  christos       rel.r_addend = 0;
   2657  1.6  christos       bfd_elf32_swap_reloca_out (output_bfd, &rel,
   2658  1.6  christos 				 (bfd_byte *) ((Elf32_External_Rela *) s->contents
   2659  1.1  christos 					       + s->reloc_count));
   2660  1.1  christos      ++ s->reloc_count;
   2661  1.1  christos     }
   2662  1.1  christos 
   2663  1.3  christos   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
   2664  1.1  christos   if (h == elf_hash_table (info)->hdynamic
   2665  1.1  christos       || h == elf_hash_table (info)->hgot)
   2666  1.1  christos     sym->st_shndx = SHN_ABS;
   2667  1.1  christos 
   2668  1.1  christos   return TRUE;
   2669  1.1  christos }
   2670  1.1  christos 
   2671  1.1  christos /* Finish up the dynamic sections.  */
   2672  1.1  christos 
   2673  1.1  christos static bfd_boolean
   2674  1.6  christos _bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
   2675  1.1  christos 				       struct bfd_link_info * info)
   2676  1.1  christos {
   2677  1.1  christos   bfd *      dynobj;
   2678  1.1  christos   asection * sgot;
   2679  1.1  christos   asection * sdyn;
   2680  1.1  christos 
   2681  1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   2682  1.6  christos 
   2683  1.1  christos   sgot = elf_hash_table (info)->sgotplt;
   2684  1.1  christos   BFD_ASSERT (sgot != NULL);
   2685  1.1  christos   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   2686  1.1  christos 
   2687  1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   2688  1.1  christos     {
   2689  1.1  christos       Elf32_External_Dyn * dyncon;
   2690  1.1  christos       Elf32_External_Dyn * dynconend;
   2691  1.1  christos 
   2692  1.1  christos       BFD_ASSERT (sdyn != NULL);
   2693  1.1  christos 
   2694  1.1  christos       dyncon = (Elf32_External_Dyn *) sdyn->contents;
   2695  1.1  christos       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
   2696  1.1  christos 
   2697  1.6  christos       for (; dyncon < dynconend; dyncon++)
   2698  1.6  christos 	{
   2699  1.6  christos 	  Elf_Internal_Dyn dyn;
   2700  1.6  christos 	  asection * s;
   2701  1.6  christos 
   2702  1.6  christos 	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
   2703  1.6  christos 
   2704  1.6  christos 	  switch (dyn.d_tag)
   2705  1.6  christos 	    {
   2706  1.6  christos 	    default:
   2707  1.6  christos 	      break;
   2708  1.6  christos 
   2709  1.6  christos 	    case DT_PLTGOT:
   2710  1.6  christos 	      s = elf_hash_table (info)->sgotplt;
   2711  1.6  christos 	      goto get_vma;
   2712  1.6  christos 
   2713  1.6  christos 	    case DT_JMPREL:
   2714  1.6  christos 	      s = elf_hash_table (info)->srelplt;
   2715  1.6  christos 	    get_vma:
   2716  1.6  christos 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
   2717  1.6  christos 	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
   2718  1.6  christos 	      break;
   2719  1.6  christos 
   2720  1.6  christos 	    case DT_PLTRELSZ:
   2721  1.6  christos 	      s = elf_hash_table (info)->srelplt;
   2722  1.6  christos 	      dyn.d_un.d_val = s->size;
   2723  1.6  christos 	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
   2724  1.6  christos 	      break;
   2725  1.6  christos 	    }
   2726  1.1  christos 	}
   2727  1.1  christos 
   2728  1.1  christos     }
   2729  1.1  christos 
   2730  1.1  christos   /* Fill in the first three entries in the global offset table.  */
   2731  1.1  christos   if (sgot->size > 0)
   2732  1.1  christos     {
   2733  1.6  christos       if (sdyn == NULL)
   2734  1.1  christos 	bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
   2735  1.6  christos       else
   2736  1.6  christos 	bfd_put_32 (output_bfd,
   2737  1.6  christos 		    sdyn->output_section->vma + sdyn->output_offset,
   2738  1.1  christos 		    sgot->contents);
   2739  1.1  christos     }
   2740  1.1  christos 
   2741  1.1  christos   elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
   2742  1.1  christos 
   2743  1.1  christos   return TRUE;
   2744  1.1  christos }
   2745  1.1  christos 
   2746  1.1  christos /* Given a .data.rel section and a .emreloc in-memory section, store
   2747  1.1  christos    relocation information into the .emreloc section which can be
   2748  1.1  christos    used at runtime to relocate the section.  This is called by the
   2749  1.1  christos    linker when the --embedded-relocs switch is used.  This is called
   2750  1.1  christos    after the add_symbols entry point has been called for all the
   2751  1.1  christos    objects, and before the final_link entry point is called.  */
   2752  1.1  christos 
   2753  1.1  christos bfd_boolean
   2754  1.6  christos bfd_cr16_elf32_create_embedded_relocs (bfd *abfd,
   2755  1.6  christos 				       struct bfd_link_info *info,
   2756  1.6  christos 				       asection *datasec,
   2757  1.6  christos 				       asection *relsec,
   2758  1.1  christos 				       char **errmsg)
   2759  1.1  christos {
   2760  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   2761  1.1  christos   Elf_Internal_Sym *isymbuf = NULL;
   2762  1.1  christos   Elf_Internal_Rela *internal_relocs = NULL;
   2763  1.1  christos   Elf_Internal_Rela *irel, *irelend;
   2764  1.1  christos   bfd_byte *p;
   2765  1.1  christos   bfd_size_type amt;
   2766  1.3  christos 
   2767  1.1  christos   BFD_ASSERT (! bfd_link_relocatable (info));
   2768  1.1  christos 
   2769  1.1  christos   *errmsg = NULL;
   2770  1.1  christos 
   2771  1.1  christos   if (datasec->reloc_count == 0)
   2772  1.1  christos     return TRUE;
   2773  1.1  christos 
   2774  1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   2775  1.1  christos 
   2776  1.1  christos   /* Get a copy of the native relocations.  */
   2777  1.6  christos   internal_relocs = (_bfd_elf_link_read_relocs
   2778  1.1  christos 		     (abfd, datasec, NULL, NULL, info->keep_memory));
   2779  1.1  christos   if (internal_relocs == NULL)
   2780  1.1  christos     goto error_return;
   2781  1.1  christos 
   2782  1.1  christos   amt = (bfd_size_type) datasec->reloc_count * 8;
   2783  1.1  christos   relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
   2784  1.1  christos   if (relsec->contents == NULL)
   2785  1.1  christos     goto error_return;
   2786  1.1  christos 
   2787  1.1  christos   p = relsec->contents;
   2788  1.1  christos 
   2789  1.1  christos   irelend = internal_relocs + datasec->reloc_count;
   2790  1.1  christos   for (irel = internal_relocs; irel < irelend; irel++, p += 8)
   2791  1.1  christos     {
   2792  1.1  christos       asection *targetsec;
   2793  1.1  christos 
   2794  1.1  christos       /* We are going to write a four byte longword into the runtime
   2795  1.1  christos        reloc section.  The longword will be the address in the data
   2796  1.1  christos        section which must be relocated.  It is followed by the name
   2797  1.1  christos        of the target section NUL-padded or truncated to 8
   2798  1.1  christos        characters.  */
   2799  1.1  christos 
   2800  1.1  christos       /* We can only relocate absolute longword relocs at run time.  */
   2801  1.6  christos       if (!((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
   2802  1.6  christos 	  || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32)))
   2803  1.6  christos 	{
   2804  1.6  christos 	  *errmsg = _("unsupported relocation type");
   2805  1.6  christos 	  bfd_set_error (bfd_error_bad_value);
   2806  1.6  christos 	  goto error_return;
   2807  1.1  christos 	}
   2808  1.1  christos 
   2809  1.1  christos       /* Get the target section referred to by the reloc.  */
   2810  1.6  christos       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
   2811  1.6  christos 	{
   2812  1.6  christos 	  /* A local symbol.  */
   2813  1.6  christos 	  Elf_Internal_Sym *isym;
   2814  1.6  christos 
   2815  1.6  christos 	  /* Read this BFD's local symbols if we haven't done so already.  */
   2816  1.6  christos 	  if (isymbuf == NULL)
   2817  1.6  christos 	    {
   2818  1.6  christos 	      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   2819  1.6  christos 	      if (isymbuf == NULL)
   2820  1.6  christos 		isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
   2821  1.6  christos 						symtab_hdr->sh_info, 0,
   2822  1.6  christos 						NULL, NULL, NULL);
   2823  1.6  christos 	      if (isymbuf == NULL)
   2824  1.6  christos 		goto error_return;
   2825  1.6  christos 	    }
   2826  1.6  christos 
   2827  1.6  christos 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
   2828  1.6  christos 	  targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
   2829  1.1  christos 	}
   2830  1.6  christos       else
   2831  1.6  christos 	{
   2832  1.6  christos 	  unsigned long indx;
   2833  1.6  christos 	  struct elf_link_hash_entry *h;
   2834  1.6  christos 
   2835  1.6  christos 	  /* An external symbol.  */
   2836  1.6  christos 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
   2837  1.6  christos 	  h = elf_sym_hashes (abfd)[indx];
   2838  1.6  christos 	  BFD_ASSERT (h != NULL);
   2839  1.6  christos 	  if (h->root.type == bfd_link_hash_defined
   2840  1.6  christos 	      || h->root.type == bfd_link_hash_defweak)
   2841  1.6  christos 	    targetsec = h->root.u.def.section;
   2842  1.6  christos 	  else
   2843  1.6  christos 	    targetsec = NULL;
   2844  1.1  christos 	}
   2845  1.1  christos 
   2846  1.1  christos       bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
   2847  1.1  christos       memset (p + 4, 0, 4);
   2848  1.6  christos       if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
   2849  1.6  christos 	  && (targetsec != NULL) )
   2850  1.1  christos 	 strncpy ((char *) p + 4, targetsec->output_section->name, 4);
   2851  1.1  christos     }
   2852  1.1  christos 
   2853  1.1  christos   if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
   2854  1.1  christos     free (isymbuf);
   2855  1.1  christos   if (internal_relocs != NULL
   2856  1.1  christos       && elf_section_data (datasec)->relocs != internal_relocs)
   2857  1.1  christos     free (internal_relocs);
   2858  1.1  christos   return TRUE;
   2859  1.1  christos 
   2860  1.1  christos error_return:
   2861  1.1  christos   if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
   2862  1.1  christos     free (isymbuf);
   2863  1.1  christos   if (internal_relocs != NULL
   2864  1.1  christos       && elf_section_data (datasec)->relocs != internal_relocs)
   2865  1.1  christos     free (internal_relocs);
   2866  1.1  christos   return FALSE;
   2867  1.1  christos }
   2868  1.1  christos 
   2869  1.1  christos 
   2870  1.1  christos /* Classify relocation types, such that combreloc can sort them
   2871  1.1  christos    properly.  */
   2872  1.1  christos 
   2873  1.3  christos static enum elf_reloc_type_class
   2874  1.3  christos _bfd_cr16_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
   2875  1.3  christos 				const asection *rel_sec ATTRIBUTE_UNUSED,
   2876  1.1  christos 				const Elf_Internal_Rela *rela)
   2877  1.1  christos {
   2878  1.1  christos   switch ((int) ELF32_R_TYPE (rela->r_info))
   2879  1.1  christos     {
   2880  1.1  christos     case R_CR16_GOT_REGREL20:
   2881  1.1  christos     case R_CR16_GOTC_REGREL20:
   2882  1.1  christos       return reloc_class_relative;
   2883  1.1  christos     default:
   2884  1.1  christos       return reloc_class_normal;
   2885  1.1  christos     }
   2886  1.1  christos }
   2887  1.1  christos 
   2888  1.6  christos /* Definitions for setting CR16 target vector.  */
   2889  1.6  christos #define TARGET_LITTLE_SYM		  cr16_elf32_vec
   2890  1.6  christos #define TARGET_LITTLE_NAME		  "elf32-cr16"
   2891  1.6  christos #define ELF_ARCH			  bfd_arch_cr16
   2892  1.6  christos #define ELF_MACHINE_CODE		  EM_CR16
   2893  1.6  christos #define ELF_MACHINE_ALT1		  EM_CR16_OLD
   2894  1.6  christos #define ELF_MAXPAGESIZE			  0x1
   2895  1.6  christos #define elf_symbol_leading_char		  '_'
   2896  1.6  christos 
   2897  1.6  christos #define bfd_elf32_bfd_reloc_type_lookup	  elf_cr16_reloc_type_lookup
   2898  1.6  christos #define bfd_elf32_bfd_reloc_name_lookup	  elf_cr16_reloc_name_lookup
   2899  1.6  christos #define elf_info_to_howto		  elf_cr16_info_to_howto
   2900  1.6  christos #define elf_info_to_howto_rel		  NULL
   2901  1.6  christos #define elf_backend_relocate_section	  elf32_cr16_relocate_section
   2902  1.1  christos #define bfd_elf32_bfd_relax_section	  elf32_cr16_relax_section
   2903  1.6  christos #define bfd_elf32_bfd_get_relocated_section_contents \
   2904  1.6  christos 				elf32_cr16_get_relocated_section_contents
   2905  1.6  christos #define elf_backend_gc_mark_hook	  elf32_cr16_gc_mark_hook
   2906  1.6  christos #define elf_backend_can_gc_sections	  1
   2907  1.6  christos #define elf_backend_rela_normal		  1
   2908  1.1  christos #define elf_backend_check_relocs	  cr16_elf_check_relocs
   2909  1.1  christos /* So we can set bits in e_flags.  */
   2910  1.6  christos #define elf_backend_final_write_processing \
   2911  1.6  christos 				 _bfd_cr16_elf_final_write_processing
   2912  1.1  christos #define elf_backend_object_p	 _bfd_cr16_elf_object_p
   2913  1.1  christos 
   2914  1.6  christos #define bfd_elf32_bfd_merge_private_bfd_data \
   2915  1.1  christos 				 _bfd_cr16_elf_merge_private_bfd_data
   2916  1.1  christos 
   2917  1.1  christos 
   2918  1.6  christos #define bfd_elf32_bfd_link_hash_table_create \
   2919  1.1  christos 				  elf32_cr16_link_hash_table_create
   2920  1.1  christos 
   2921  1.6  christos #define elf_backend_create_dynamic_sections \
   2922  1.1  christos 				  _bfd_cr16_elf_create_dynamic_sections
   2923  1.6  christos #define elf_backend_adjust_dynamic_symbol \
   2924  1.1  christos 				  _bfd_cr16_elf_adjust_dynamic_symbol
   2925  1.6  christos #define elf_backend_size_dynamic_sections \
   2926  1.6  christos 				  _bfd_cr16_elf_size_dynamic_sections
   2927  1.1  christos #define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
   2928  1.6  christos #define elf_backend_finish_dynamic_symbol \
   2929  1.1  christos 				   _bfd_cr16_elf_finish_dynamic_symbol
   2930  1.6  christos #define elf_backend_finish_dynamic_sections \
   2931  1.1  christos 				   _bfd_cr16_elf_finish_dynamic_sections
   2932  1.1  christos 
   2933  1.1  christos #define elf_backend_reloc_type_class   _bfd_cr16_elf_reloc_type_class
   2934  1.1  christos 
   2935  1.6  christos 
   2936  1.6  christos #define elf_backend_want_got_plt	1
   2937  1.6  christos #define elf_backend_plt_readonly	1
   2938  1.6  christos #define elf_backend_want_plt_sym	0
   2939  1.6  christos #define elf_backend_got_header_size	12
   2940  1.1  christos #define elf_backend_dtrel_excludes_plt	1
   2941  1.1  christos 
   2942                #include "elf32-target.h"
   2943