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