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