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