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