Home | History | Annotate | Line # | Download | only in bfd
elf32-rl78.c revision 1.9.2.1
      1      1.1  christos /* Renesas RL78 specific support for 32-bit ELF.
      2  1.9.2.1  perseant    Copyright (C) 2011-2022 Free Software Foundation, Inc.
      3      1.1  christos 
      4      1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      5      1.1  christos 
      6      1.1  christos    This program is free software; you can redistribute it and/or modify
      7      1.1  christos    it under the terms of the GNU General Public License as published by
      8      1.1  christos    the Free Software Foundation; either version 3 of the License, or
      9      1.1  christos    (at your option) any later version.
     10      1.1  christos 
     11      1.1  christos    This program is distributed in the hope that it will be useful,
     12      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14      1.1  christos    GNU General Public License for more details.
     15      1.1  christos 
     16      1.1  christos    You should have received a copy of the GNU General Public License
     17      1.1  christos    along with this program; if not, write to the Free Software
     18      1.8  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19      1.8  christos    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 "libbfd.h"
     24      1.1  christos #include "elf-bfd.h"
     25      1.1  christos #include "elf/rl78.h"
     26      1.1  christos #include "libiberty.h"
     27      1.1  christos 
     28      1.1  christos #define valid_16bit_address(v) ((v) <= 0x0ffff || (v) >= 0xf0000)
     29      1.1  christos 
     30  1.9.2.1  perseant #define RL78REL(n,sz,bit,mask,shift,complain,pcrel) \
     31      1.1  christos   HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
     32  1.9.2.1  perseant 	 bfd_elf_generic_reloc, "R_RL78_" #n, false, 0, mask, false)
     33      1.1  christos 
     34      1.5  christos static bfd_reloc_status_type rl78_special_reloc (bfd *, arelent *, asymbol *, void *,
     35      1.5  christos 						 asection *, bfd *, char **);
     36      1.5  christos 
     37  1.9.2.1  perseant #define RL78_OP_REL(n,sz,bit,mask,shift,complain,pcrel)			\
     38      1.5  christos   HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
     39  1.9.2.1  perseant 	 rl78_special_reloc, "R_RL78_" #n, false, 0, mask, false)
     40      1.5  christos 
     41      1.1  christos /* Note that the relocations around 0x7f are internal to this file;
     42      1.1  christos    feel free to move them as needed to avoid conflicts with published
     43      1.1  christos    relocation numbers.  */
     44      1.1  christos 
     45      1.1  christos static reloc_howto_type rl78_elf_howto_table [] =
     46      1.1  christos {
     47  1.9.2.1  perseant   RL78REL (NONE,	 0,  0, 0,          0, dont,     false),
     48  1.9.2.1  perseant   RL78REL (DIR32,	 4, 32, 0xffffffff, 0, dont,     false),
     49  1.9.2.1  perseant   RL78REL (DIR24S,	 4, 24, 0xffffff,   0, signed,   false),
     50  1.9.2.1  perseant   RL78REL (DIR16,	 2, 16, 0xffff,     0, bitfield, false),
     51  1.9.2.1  perseant   RL78REL (DIR16U,	 2, 16, 0xffff,     0, unsigned, false),
     52  1.9.2.1  perseant   RL78REL (DIR16S,	 2, 16, 0xffff,     0, bitfield, false),
     53  1.9.2.1  perseant   RL78REL (DIR8,	 1,  8, 0xff,       0, dont,     false),
     54  1.9.2.1  perseant   RL78REL (DIR8U,	 1,  8, 0xff,       0, unsigned, false),
     55  1.9.2.1  perseant   RL78REL (DIR8S,	 1,  8, 0xff,       0, bitfield, false),
     56  1.9.2.1  perseant   RL78REL (DIR24S_PCREL, 4, 24, 0xffffff,   0, signed,   true),
     57  1.9.2.1  perseant   RL78REL (DIR16S_PCREL, 2, 16, 0xffff,     0, signed,   true),
     58  1.9.2.1  perseant   RL78REL (DIR8S_PCREL,	 1,  8, 0xff,       0, signed,   true),
     59  1.9.2.1  perseant   RL78REL (DIR16UL,	 2, 16, 0xffff,     2, unsigned, false),
     60  1.9.2.1  perseant   RL78REL (DIR16UW,	 2, 16, 0xffff,     1, unsigned, false),
     61  1.9.2.1  perseant   RL78REL (DIR8UL,	 1,  8, 0xff,       2, unsigned, false),
     62  1.9.2.1  perseant   RL78REL (DIR8UW,	 1,  8, 0xff,       1, unsigned, false),
     63  1.9.2.1  perseant   RL78REL (DIR32_REV,	 4, 32, 0xffffffff, 0, dont,     false),
     64  1.9.2.1  perseant   RL78REL (DIR16_REV,	 2, 16, 0xffff,     0, bitfield, false),
     65  1.9.2.1  perseant   RL78REL (DIR3U_PCREL,	 1,  3, 0x7,        0, unsigned, true),
     66      1.1  christos 
     67      1.1  christos   EMPTY_HOWTO (0x13),
     68      1.1  christos   EMPTY_HOWTO (0x14),
     69      1.1  christos   EMPTY_HOWTO (0x15),
     70      1.1  christos   EMPTY_HOWTO (0x16),
     71      1.1  christos   EMPTY_HOWTO (0x17),
     72      1.1  christos   EMPTY_HOWTO (0x18),
     73      1.1  christos   EMPTY_HOWTO (0x19),
     74      1.1  christos   EMPTY_HOWTO (0x1a),
     75      1.1  christos   EMPTY_HOWTO (0x1b),
     76      1.1  christos   EMPTY_HOWTO (0x1c),
     77      1.1  christos   EMPTY_HOWTO (0x1d),
     78      1.1  christos   EMPTY_HOWTO (0x1e),
     79      1.1  christos   EMPTY_HOWTO (0x1f),
     80      1.1  christos 
     81      1.1  christos   EMPTY_HOWTO (0x20),
     82      1.1  christos   EMPTY_HOWTO (0x21),
     83      1.1  christos   EMPTY_HOWTO (0x22),
     84      1.1  christos   EMPTY_HOWTO (0x23),
     85      1.1  christos   EMPTY_HOWTO (0x24),
     86      1.1  christos   EMPTY_HOWTO (0x25),
     87      1.1  christos   EMPTY_HOWTO (0x26),
     88      1.1  christos   EMPTY_HOWTO (0x27),
     89      1.1  christos   EMPTY_HOWTO (0x28),
     90      1.1  christos   EMPTY_HOWTO (0x29),
     91      1.1  christos   EMPTY_HOWTO (0x2a),
     92      1.1  christos   EMPTY_HOWTO (0x2b),
     93      1.1  christos   EMPTY_HOWTO (0x2c),
     94      1.1  christos 
     95  1.9.2.1  perseant   RL78REL (RH_RELAX,	 0,  0, 0,          0, dont,	 false),
     96  1.9.2.1  perseant   RL78REL (RH_SFR,	 1,  8, 0xff,       0, unsigned, false),
     97  1.9.2.1  perseant   RL78REL (RH_SADDR,	 1,  8, 0xff,       0, unsigned, false),
     98  1.9.2.1  perseant 
     99      1.1  christos   EMPTY_HOWTO (0x30),
    100      1.1  christos   EMPTY_HOWTO (0x31),
    101      1.1  christos   EMPTY_HOWTO (0x32),
    102      1.1  christos   EMPTY_HOWTO (0x33),
    103      1.1  christos   EMPTY_HOWTO (0x34),
    104      1.1  christos   EMPTY_HOWTO (0x35),
    105      1.1  christos   EMPTY_HOWTO (0x36),
    106      1.1  christos   EMPTY_HOWTO (0x37),
    107      1.1  christos   EMPTY_HOWTO (0x38),
    108      1.1  christos   EMPTY_HOWTO (0x39),
    109      1.1  christos   EMPTY_HOWTO (0x3a),
    110      1.1  christos   EMPTY_HOWTO (0x3b),
    111      1.1  christos   EMPTY_HOWTO (0x3c),
    112      1.1  christos   EMPTY_HOWTO (0x3d),
    113      1.1  christos   EMPTY_HOWTO (0x3e),
    114      1.1  christos   EMPTY_HOWTO (0x3f),
    115      1.1  christos   EMPTY_HOWTO (0x40),
    116      1.1  christos 
    117  1.9.2.1  perseant   RL78_OP_REL (ABS32,	     4, 32, 0xffffffff, 0, dont,	false),
    118  1.9.2.1  perseant   RL78_OP_REL (ABS24S,	     4, 24, 0xffffff,   0, signed,	false),
    119  1.9.2.1  perseant   RL78_OP_REL (ABS16,	     2, 16, 0xffff,     0, bitfield,	false),
    120  1.9.2.1  perseant   RL78_OP_REL (ABS16U,	     2, 16, 0xffff,     0, unsigned,	false),
    121  1.9.2.1  perseant   RL78_OP_REL (ABS16S,	     2, 16, 0xffff,     0, signed,	false),
    122  1.9.2.1  perseant   RL78_OP_REL (ABS8,	     1,	 8, 0xff,       0, bitfield,	false),
    123  1.9.2.1  perseant   RL78_OP_REL (ABS8U,	     1,	 8, 0xff,       0, unsigned,	false),
    124  1.9.2.1  perseant   RL78_OP_REL (ABS8S,	     1,	 8, 0xff,       0, signed,	false),
    125  1.9.2.1  perseant   RL78_OP_REL (ABS24S_PCREL, 4, 24, 0xffffff,   0, signed,	true),
    126  1.9.2.1  perseant   RL78_OP_REL (ABS16S_PCREL, 2, 16, 0xffff,     0, signed,	true),
    127  1.9.2.1  perseant   RL78_OP_REL (ABS8S_PCREL,  1,	 8, 0xff,       0, signed,	true),
    128  1.9.2.1  perseant   RL78_OP_REL (ABS16UL,	     2, 16, 0xffff,     0, unsigned,	false),
    129  1.9.2.1  perseant   RL78_OP_REL (ABS16UW,	     2, 16, 0xffff,     0, unsigned,	false),
    130  1.9.2.1  perseant   RL78_OP_REL (ABS8UL,	     1,	 8, 0xff,       0, unsigned,	false),
    131  1.9.2.1  perseant   RL78_OP_REL (ABS8UW,	     1,	 8, 0xff,       0, unsigned,	false),
    132  1.9.2.1  perseant   RL78_OP_REL (ABS32_REV,    4, 32, 0xffffffff, 0, dont,	false),
    133  1.9.2.1  perseant   RL78_OP_REL (ABS16_REV,    2, 16, 0xffff,     0, bitfield,	false),
    134      1.1  christos 
    135      1.1  christos #define STACK_REL_P(x) ((x) <= R_RL78_ABS16_REV && (x) >= R_RL78_ABS32)
    136      1.1  christos 
    137      1.1  christos   EMPTY_HOWTO (0x52),
    138      1.1  christos   EMPTY_HOWTO (0x53),
    139      1.1  christos   EMPTY_HOWTO (0x54),
    140      1.1  christos   EMPTY_HOWTO (0x55),
    141      1.1  christos   EMPTY_HOWTO (0x56),
    142      1.1  christos   EMPTY_HOWTO (0x57),
    143      1.1  christos   EMPTY_HOWTO (0x58),
    144      1.1  christos   EMPTY_HOWTO (0x59),
    145      1.1  christos   EMPTY_HOWTO (0x5a),
    146      1.1  christos   EMPTY_HOWTO (0x5b),
    147      1.1  christos   EMPTY_HOWTO (0x5c),
    148      1.1  christos   EMPTY_HOWTO (0x5d),
    149      1.1  christos   EMPTY_HOWTO (0x5e),
    150      1.1  christos   EMPTY_HOWTO (0x5f),
    151      1.1  christos   EMPTY_HOWTO (0x60),
    152      1.1  christos   EMPTY_HOWTO (0x61),
    153      1.1  christos   EMPTY_HOWTO (0x62),
    154      1.1  christos   EMPTY_HOWTO (0x63),
    155      1.1  christos   EMPTY_HOWTO (0x64),
    156      1.1  christos   EMPTY_HOWTO (0x65),
    157      1.1  christos   EMPTY_HOWTO (0x66),
    158      1.1  christos   EMPTY_HOWTO (0x67),
    159      1.1  christos   EMPTY_HOWTO (0x68),
    160      1.1  christos   EMPTY_HOWTO (0x69),
    161      1.1  christos   EMPTY_HOWTO (0x6a),
    162      1.1  christos   EMPTY_HOWTO (0x6b),
    163      1.1  christos   EMPTY_HOWTO (0x6c),
    164      1.1  christos   EMPTY_HOWTO (0x6d),
    165      1.1  christos   EMPTY_HOWTO (0x6e),
    166      1.1  christos   EMPTY_HOWTO (0x6f),
    167      1.1  christos   EMPTY_HOWTO (0x70),
    168      1.1  christos   EMPTY_HOWTO (0x71),
    169      1.1  christos   EMPTY_HOWTO (0x72),
    170      1.1  christos   EMPTY_HOWTO (0x73),
    171      1.1  christos   EMPTY_HOWTO (0x74),
    172      1.1  christos   EMPTY_HOWTO (0x75),
    173      1.1  christos   EMPTY_HOWTO (0x76),
    174      1.1  christos   EMPTY_HOWTO (0x77),
    175      1.1  christos 
    176      1.1  christos   EMPTY_HOWTO (0x78),
    177      1.1  christos   EMPTY_HOWTO (0x79),
    178      1.1  christos   EMPTY_HOWTO (0x7a),
    179      1.1  christos   EMPTY_HOWTO (0x7b),
    180      1.1  christos   EMPTY_HOWTO (0x7c),
    181      1.1  christos   EMPTY_HOWTO (0x7d),
    182      1.1  christos   EMPTY_HOWTO (0x7e),
    183      1.1  christos   EMPTY_HOWTO (0x7f),
    184      1.1  christos 
    185  1.9.2.1  perseant   RL78_OP_REL (SYM,	  0, 0, 0, 0, dont, false),
    186  1.9.2.1  perseant   RL78_OP_REL (OPneg,	  0, 0, 0, 0, dont, false),
    187  1.9.2.1  perseant   RL78_OP_REL (OPadd,	  0, 0, 0, 0, dont, false),
    188  1.9.2.1  perseant   RL78_OP_REL (OPsub,	  0, 0, 0, 0, dont, false),
    189  1.9.2.1  perseant   RL78_OP_REL (OPmul,	  0, 0, 0, 0, dont, false),
    190  1.9.2.1  perseant   RL78_OP_REL (OPdiv,	  0, 0, 0, 0, dont, false),
    191  1.9.2.1  perseant   RL78_OP_REL (OPshla,	  0, 0, 0, 0, dont, false),
    192  1.9.2.1  perseant   RL78_OP_REL (OPshra,	  0, 0, 0, 0, dont, false),
    193  1.9.2.1  perseant   RL78_OP_REL (OPsctsize, 0, 0, 0, 0, dont, false),
    194      1.1  christos   EMPTY_HOWTO (0x89),
    195      1.1  christos   EMPTY_HOWTO (0x8a),
    196      1.1  christos   EMPTY_HOWTO (0x8b),
    197      1.1  christos   EMPTY_HOWTO (0x8c),
    198  1.9.2.1  perseant   RL78_OP_REL (OPscttop,  0, 0, 0, 0, dont, false),
    199      1.1  christos   EMPTY_HOWTO (0x8e),
    200      1.1  christos   EMPTY_HOWTO (0x8f),
    201  1.9.2.1  perseant   RL78_OP_REL (OPand,	  0, 0, 0, 0, dont, false),
    202  1.9.2.1  perseant   RL78_OP_REL (OPor,	  0, 0, 0, 0, dont, false),
    203  1.9.2.1  perseant   RL78_OP_REL (OPxor,	  0, 0, 0, 0, dont, false),
    204  1.9.2.1  perseant   RL78_OP_REL (OPnot,	  0, 0, 0, 0, dont, false),
    205  1.9.2.1  perseant   RL78_OP_REL (OPmod,	  0, 0, 0, 0, dont, false),
    206  1.9.2.1  perseant   RL78_OP_REL (OPromtop,  0, 0, 0, 0, dont, false),
    207  1.9.2.1  perseant   RL78_OP_REL (OPramtop,  0, 0, 0, 0, dont, false)
    208      1.1  christos };
    209      1.1  christos 
    210      1.1  christos /* Map BFD reloc types to RL78 ELF reloc types.  */
    212      1.1  christos 
    213      1.1  christos struct rl78_reloc_map
    214      1.1  christos {
    215      1.8  christos   bfd_reloc_code_real_type  bfd_reloc_val;
    216      1.1  christos   unsigned int		    rl78_reloc_val;
    217      1.1  christos };
    218      1.1  christos 
    219      1.1  christos static const struct rl78_reloc_map rl78_reloc_map [] =
    220      1.1  christos {
    221      1.1  christos   { BFD_RELOC_NONE,		R_RL78_NONE },
    222      1.1  christos   { BFD_RELOC_8,		R_RL78_DIR8S },
    223      1.1  christos   { BFD_RELOC_16,		R_RL78_DIR16S },
    224      1.1  christos   { BFD_RELOC_24,		R_RL78_DIR24S },
    225      1.1  christos   { BFD_RELOC_32,		R_RL78_DIR32 },
    226      1.1  christos   { BFD_RELOC_RL78_16_OP,	R_RL78_DIR16 },
    227      1.1  christos   { BFD_RELOC_RL78_DIR3U_PCREL,	R_RL78_DIR3U_PCREL },
    228      1.1  christos   { BFD_RELOC_8_PCREL,		R_RL78_DIR8S_PCREL },
    229      1.1  christos   { BFD_RELOC_16_PCREL,		R_RL78_DIR16S_PCREL },
    230      1.1  christos   { BFD_RELOC_24_PCREL,		R_RL78_DIR24S_PCREL },
    231      1.1  christos   { BFD_RELOC_RL78_8U,		R_RL78_DIR8U },
    232      1.1  christos   { BFD_RELOC_RL78_16U,		R_RL78_DIR16U },
    233      1.1  christos   { BFD_RELOC_RL78_SYM,		R_RL78_SYM },
    234      1.1  christos   { BFD_RELOC_RL78_OP_SUBTRACT,	R_RL78_OPsub },
    235      1.1  christos   { BFD_RELOC_RL78_OP_NEG,	R_RL78_OPneg },
    236      1.1  christos   { BFD_RELOC_RL78_OP_AND,	R_RL78_OPand },
    237      1.1  christos   { BFD_RELOC_RL78_OP_SHRA,	R_RL78_OPshra },
    238      1.1  christos   { BFD_RELOC_RL78_ABS8,	R_RL78_ABS8 },
    239      1.1  christos   { BFD_RELOC_RL78_ABS16,	R_RL78_ABS16 },
    240      1.1  christos   { BFD_RELOC_RL78_ABS16_REV,	R_RL78_ABS16_REV },
    241      1.1  christos   { BFD_RELOC_RL78_ABS32,	R_RL78_ABS32 },
    242      1.1  christos   { BFD_RELOC_RL78_ABS32_REV,	R_RL78_ABS32_REV },
    243      1.1  christos   { BFD_RELOC_RL78_ABS16UL,	R_RL78_ABS16UL },
    244      1.1  christos   { BFD_RELOC_RL78_ABS16UW,	R_RL78_ABS16UW },
    245      1.5  christos   { BFD_RELOC_RL78_ABS16U,	R_RL78_ABS16U },
    246      1.1  christos   { BFD_RELOC_RL78_SADDR,	R_RL78_RH_SADDR },
    247      1.1  christos   { BFD_RELOC_RL78_RELAX,	R_RL78_RH_RELAX }
    248      1.1  christos };
    249      1.1  christos 
    250      1.1  christos static reloc_howto_type *
    251      1.1  christos rl78_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    252      1.1  christos 			bfd_reloc_code_real_type code)
    253      1.1  christos {
    254      1.1  christos   unsigned int i;
    255      1.1  christos 
    256      1.1  christos   if (code == BFD_RELOC_RL78_32_OP)
    257      1.1  christos     return rl78_elf_howto_table + R_RL78_DIR32;
    258      1.5  christos 
    259      1.1  christos   for (i = ARRAY_SIZE (rl78_reloc_map); i--;)
    260      1.1  christos     if (rl78_reloc_map [i].bfd_reloc_val == code)
    261      1.1  christos       return rl78_elf_howto_table + rl78_reloc_map[i].rl78_reloc_val;
    262      1.1  christos 
    263      1.1  christos   return NULL;
    264      1.1  christos }
    265      1.1  christos 
    266      1.1  christos static reloc_howto_type *
    267      1.1  christos rl78_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name)
    268      1.1  christos {
    269      1.1  christos   unsigned int i;
    270      1.1  christos 
    271      1.1  christos   for (i = 0; i < ARRAY_SIZE (rl78_elf_howto_table); i++)
    272      1.1  christos     if (rl78_elf_howto_table[i].name != NULL
    273      1.1  christos 	&& strcasecmp (rl78_elf_howto_table[i].name, r_name) == 0)
    274      1.1  christos       return rl78_elf_howto_table + i;
    275      1.1  christos 
    276      1.1  christos   return NULL;
    277      1.1  christos }
    278      1.1  christos 
    279      1.1  christos /* Set the howto pointer for an RL78 ELF reloc.  */
    280  1.9.2.1  perseant 
    281      1.8  christos static bool
    282      1.8  christos rl78_info_to_howto_rela (bfd *		     abfd,
    283      1.1  christos 			 arelent *	     cache_ptr,
    284      1.1  christos 			 Elf_Internal_Rela * dst)
    285      1.1  christos {
    286      1.1  christos   unsigned int r_type;
    287      1.1  christos 
    288      1.3  christos   r_type = ELF32_R_TYPE (dst->r_info);
    289      1.3  christos   if (r_type >= (unsigned int) R_RL78_max)
    290      1.7  christos     {
    291      1.8  christos       /* xgettext:c-format */
    292      1.8  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    293      1.8  christos 			  abfd, r_type);
    294  1.9.2.1  perseant       bfd_set_error (bfd_error_bad_value);
    295      1.3  christos       return false;
    296      1.1  christos     }
    297  1.9.2.1  perseant   cache_ptr->howto = rl78_elf_howto_table + r_type;
    298      1.1  christos   return true;
    299      1.1  christos }
    300      1.1  christos 
    301      1.8  christos static bfd_vma
    303      1.8  christos get_symbol_value (const char *		  name,
    304      1.8  christos 		  struct bfd_link_info *  info,
    305      1.1  christos 		  bfd *			  input_bfd,
    306      1.1  christos 		  asection *		  input_section,
    307      1.1  christos 		  int			  offset)
    308      1.1  christos {
    309      1.5  christos   struct bfd_link_hash_entry * h;
    310      1.5  christos 
    311      1.5  christos   if (info == NULL)
    312  1.9.2.1  perseant     return 0;
    313      1.1  christos 
    314      1.1  christos   h = bfd_link_hash_lookup (info->hash, name, false, false, true);
    315      1.1  christos 
    316      1.1  christos   if (h == NULL
    317      1.5  christos       || (h->type != bfd_link_hash_defined
    318      1.6  christos 	  && h->type != bfd_link_hash_defweak))
    319  1.9.2.1  perseant     {
    320      1.5  christos       (*info->callbacks->undefined_symbol)
    321      1.5  christos 	(info, name, input_bfd, input_section, offset, true);
    322      1.1  christos       return 0;
    323      1.5  christos     }
    324      1.5  christos 
    325      1.5  christos   return (h->u.def.value
    326      1.1  christos 	  + h->u.def.section->output_section->vma
    327      1.1  christos 	  + h->u.def.section->output_offset);
    328      1.1  christos }
    329      1.6  christos 
    330      1.8  christos static bfd_vma
    331      1.8  christos get_romstart (struct bfd_link_info *  info,
    332      1.1  christos 	      bfd *		      abfd,
    333      1.1  christos 	      asection *	      sec,
    334  1.9.2.1  perseant 	      int		      offset)
    335  1.9.2.1  perseant {
    336      1.1  christos   static bool cached = false;
    337      1.1  christos   static bfd_vma cached_value = 0;
    338      1.1  christos 
    339      1.6  christos   if (!cached)
    340  1.9.2.1  perseant     {
    341      1.1  christos       cached_value = get_symbol_value ("_start", info, abfd, sec, offset);
    342      1.1  christos       cached = true;
    343      1.1  christos     }
    344      1.1  christos   return cached_value;
    345      1.1  christos }
    346      1.6  christos 
    347      1.8  christos static bfd_vma
    348      1.8  christos get_ramstart (struct bfd_link_info *  info,
    349      1.1  christos 	      bfd *		      abfd,
    350      1.1  christos 	      asection *	      sec,
    351  1.9.2.1  perseant 	      int		      offset)
    352  1.9.2.1  perseant {
    353      1.1  christos   static bool cached = false;
    354      1.1  christos   static bfd_vma cached_value = 0;
    355      1.1  christos 
    356      1.6  christos   if (!cached)
    357  1.9.2.1  perseant     {
    358      1.1  christos       cached_value = get_symbol_value ("__datastart", info, abfd, sec, offset);
    359      1.1  christos       cached = true;
    360      1.1  christos     }
    361      1.1  christos   return cached_value;
    362      1.1  christos }
    363      1.1  christos 
    364      1.1  christos #define NUM_STACK_ENTRIES 16
    365      1.1  christos static int32_t rl78_stack [ NUM_STACK_ENTRIES ];
    366  1.9.2.1  perseant static unsigned int rl78_stack_top;
    367  1.9.2.1  perseant 
    368  1.9.2.1  perseant static inline void
    369  1.9.2.1  perseant rl78_stack_push (bfd_vma val, bfd_reloc_status_type *r)
    370  1.9.2.1  perseant {
    371  1.9.2.1  perseant   if (rl78_stack_top < NUM_STACK_ENTRIES)
    372  1.9.2.1  perseant     rl78_stack[rl78_stack_top++] = val;
    373  1.9.2.1  perseant   else
    374  1.9.2.1  perseant     *r = bfd_reloc_dangerous;
    375  1.9.2.1  perseant }
    376  1.9.2.1  perseant 
    377  1.9.2.1  perseant static inline bfd_vma
    378  1.9.2.1  perseant rl78_stack_pop (bfd_reloc_status_type *r)
    379  1.9.2.1  perseant {
    380  1.9.2.1  perseant   if (rl78_stack_top > 0)
    381  1.9.2.1  perseant     return rl78_stack[-- rl78_stack_top];
    382  1.9.2.1  perseant   else
    383  1.9.2.1  perseant     *r = bfd_reloc_dangerous;
    384      1.1  christos   return 0;
    385      1.5  christos }
    386      1.5  christos 
    387      1.5  christos /* Special handling for RL78 complex relocs.  Returns the
    388      1.5  christos    value of the reloc, or 0 for relocs which do not generate
    389      1.5  christos    a result.  SYMVAL is the value of the symbol for relocs
    390      1.5  christos    which use a symbolic argument.  */
    391      1.5  christos 
    392  1.9.2.1  perseant static bfd_vma
    393  1.9.2.1  perseant rl78_compute_complex_reloc (unsigned long  r_type,
    394  1.9.2.1  perseant 			    bfd_vma symval,
    395  1.9.2.1  perseant 			    asection *input_section,
    396      1.5  christos 			    bfd_reloc_status_type *r,
    397      1.5  christos 			    char **error_message)
    398  1.9.2.1  perseant {
    399  1.9.2.1  perseant   int32_t tmp1, tmp2;
    400      1.5  christos   bfd_vma relocation = 0;
    401      1.5  christos   bfd_reloc_status_type stat = bfd_reloc_ok;
    402      1.5  christos 
    403      1.5  christos   switch (r_type)
    404  1.9.2.1  perseant     {
    405  1.9.2.1  perseant     default:
    406      1.5  christos       stat = bfd_reloc_notsupported;
    407      1.5  christos       break;
    408      1.5  christos 
    409      1.5  christos     case R_RL78_ABS24S_PCREL:
    410  1.9.2.1  perseant     case R_RL78_ABS16S_PCREL:
    411      1.5  christos     case R_RL78_ABS8S_PCREL:
    412  1.9.2.1  perseant       relocation = rl78_stack_pop (&stat);
    413      1.5  christos       relocation -= input_section->output_section->vma + input_section->output_offset;
    414      1.5  christos       break;
    415      1.5  christos 
    416      1.5  christos     case R_RL78_ABS32:
    417      1.5  christos     case R_RL78_ABS32_REV:
    418      1.5  christos     case R_RL78_ABS16:
    419      1.5  christos     case R_RL78_ABS16_REV:
    420      1.5  christos     case R_RL78_ABS16S:
    421      1.5  christos     case R_RL78_ABS16U:
    422      1.5  christos     case R_RL78_ABS8:
    423  1.9.2.1  perseant     case R_RL78_ABS8U:
    424  1.9.2.1  perseant     case R_RL78_ABS8S:
    425      1.5  christos       relocation = rl78_stack_pop (&stat);
    426      1.5  christos       break;
    427      1.5  christos 
    428  1.9.2.1  perseant     case R_RL78_ABS16UL:
    429  1.9.2.1  perseant     case R_RL78_ABS8UL:
    430      1.5  christos       relocation = rl78_stack_pop (&stat) >> 2;
    431      1.5  christos       break;;
    432      1.5  christos 
    433  1.9.2.1  perseant     case R_RL78_ABS16UW:
    434  1.9.2.1  perseant     case R_RL78_ABS8UW:
    435      1.5  christos       relocation = rl78_stack_pop (&stat) >> 1;
    436      1.5  christos       break;
    437      1.5  christos 
    438      1.5  christos       /* The rest of the relocs compute values and then push them onto the stack.  */
    439      1.5  christos     case R_RL78_OPramtop:
    440  1.9.2.1  perseant     case R_RL78_OPromtop:
    441  1.9.2.1  perseant     case R_RL78_SYM:
    442      1.6  christos       rl78_stack_push (symval, &stat);
    443      1.5  christos       break;
    444  1.9.2.1  perseant 
    445      1.5  christos     case R_RL78_OPneg:
    446  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    447  1.9.2.1  perseant       tmp1 = - tmp1;
    448      1.5  christos       rl78_stack_push (tmp1, &stat);
    449      1.5  christos       break;
    450  1.9.2.1  perseant 
    451  1.9.2.1  perseant     case R_RL78_OPadd:
    452      1.5  christos       tmp2 = rl78_stack_pop (&stat);
    453  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    454  1.9.2.1  perseant       tmp1 += tmp2;
    455      1.5  christos       rl78_stack_push (tmp1, &stat);
    456      1.5  christos       break;
    457      1.5  christos 
    458      1.5  christos     case R_RL78_OPsub:
    459  1.9.2.1  perseant       /* For the expression "A - B", the assembler pushes A,
    460  1.9.2.1  perseant 	 then B, then OPSUB.  So the first op we pop is B, not A.  */
    461      1.5  christos       tmp2 = rl78_stack_pop (&stat);	/* B */
    462  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);	/* A */
    463  1.9.2.1  perseant       tmp1 -= tmp2;		/* A - B */
    464      1.5  christos       rl78_stack_push (tmp1, &stat);
    465      1.5  christos       break;
    466  1.9.2.1  perseant 
    467  1.9.2.1  perseant     case R_RL78_OPmul:
    468      1.5  christos       tmp2 = rl78_stack_pop (&stat);
    469  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    470  1.9.2.1  perseant       tmp1 *= tmp2;
    471      1.5  christos       rl78_stack_push (tmp1, &stat);
    472      1.5  christos       break;
    473  1.9.2.1  perseant 
    474  1.9.2.1  perseant     case R_RL78_OPdiv:
    475  1.9.2.1  perseant       tmp2 = rl78_stack_pop (&stat);
    476  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    477  1.9.2.1  perseant       if (tmp2 != 0)
    478  1.9.2.1  perseant 	tmp1 /= tmp2;
    479  1.9.2.1  perseant       else
    480  1.9.2.1  perseant 	{
    481  1.9.2.1  perseant 	  tmp1 = 0;
    482  1.9.2.1  perseant 	  stat = bfd_reloc_overflow;
    483  1.9.2.1  perseant 	}
    484      1.5  christos       rl78_stack_push (tmp1, &stat);
    485      1.5  christos       break;
    486  1.9.2.1  perseant 
    487  1.9.2.1  perseant     case R_RL78_OPshla:
    488      1.5  christos       tmp2 = rl78_stack_pop (&stat);
    489  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    490  1.9.2.1  perseant       tmp1 <<= tmp2;
    491      1.5  christos       rl78_stack_push (tmp1, &stat);
    492      1.5  christos       break;
    493  1.9.2.1  perseant 
    494  1.9.2.1  perseant     case R_RL78_OPshra:
    495      1.5  christos       tmp2 = rl78_stack_pop (&stat);
    496  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    497  1.9.2.1  perseant       tmp1 >>= tmp2;
    498      1.5  christos       rl78_stack_push (tmp1, &stat);
    499      1.5  christos       break;
    500  1.9.2.1  perseant 
    501  1.9.2.1  perseant     case R_RL78_OPsctsize:
    502      1.5  christos       rl78_stack_push (input_section->size, &stat);
    503      1.5  christos       break;
    504  1.9.2.1  perseant 
    505  1.9.2.1  perseant     case R_RL78_OPscttop:
    506      1.5  christos       rl78_stack_push (input_section->output_section->vma, &stat);
    507      1.5  christos       break;
    508  1.9.2.1  perseant 
    509  1.9.2.1  perseant     case R_RL78_OPand:
    510      1.5  christos       tmp2 = rl78_stack_pop (&stat);
    511  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    512  1.9.2.1  perseant       tmp1 &= tmp2;
    513      1.5  christos       rl78_stack_push (tmp1, &stat);
    514      1.5  christos       break;
    515  1.9.2.1  perseant 
    516  1.9.2.1  perseant     case R_RL78_OPor:
    517      1.5  christos       tmp2 = rl78_stack_pop (&stat);
    518  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    519  1.9.2.1  perseant       tmp1 |= tmp2;
    520      1.5  christos       rl78_stack_push (tmp1, &stat);
    521      1.5  christos       break;
    522  1.9.2.1  perseant 
    523  1.9.2.1  perseant     case R_RL78_OPxor:
    524      1.5  christos       tmp2 = rl78_stack_pop (&stat);
    525  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    526  1.9.2.1  perseant       tmp1 ^= tmp2;
    527      1.5  christos       rl78_stack_push (tmp1, &stat);
    528      1.5  christos       break;
    529  1.9.2.1  perseant 
    530      1.5  christos     case R_RL78_OPnot:
    531  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    532  1.9.2.1  perseant       tmp1 = ~ tmp1;
    533      1.5  christos       rl78_stack_push (tmp1, &stat);
    534      1.5  christos       break;
    535  1.9.2.1  perseant 
    536  1.9.2.1  perseant     case R_RL78_OPmod:
    537  1.9.2.1  perseant       tmp2 = rl78_stack_pop (&stat);
    538  1.9.2.1  perseant       tmp1 = rl78_stack_pop (&stat);
    539  1.9.2.1  perseant       if (tmp2 != 0)
    540  1.9.2.1  perseant 	tmp1 %= tmp2;
    541  1.9.2.1  perseant       else
    542  1.9.2.1  perseant 	{
    543  1.9.2.1  perseant 	  tmp1 = 0;
    544  1.9.2.1  perseant 	  stat = bfd_reloc_overflow;
    545  1.9.2.1  perseant 	}
    546      1.5  christos       rl78_stack_push (tmp1, &stat);
    547  1.9.2.1  perseant       break;
    548  1.9.2.1  perseant     }
    549  1.9.2.1  perseant 
    550  1.9.2.1  perseant   if (r)
    551  1.9.2.1  perseant     {
    552  1.9.2.1  perseant       if (stat == bfd_reloc_dangerous)
    553  1.9.2.1  perseant 	*error_message = (_("RL78 reloc stack overflow/underflow"));
    554  1.9.2.1  perseant       else if (stat == bfd_reloc_overflow)
    555  1.9.2.1  perseant 	{
    556  1.9.2.1  perseant 	  stat = bfd_reloc_dangerous;
    557  1.9.2.1  perseant 	  *error_message = (_("RL78 reloc divide by zero"));
    558  1.9.2.1  perseant 	}
    559  1.9.2.1  perseant       *r = stat;
    560      1.5  christos     }
    561      1.5  christos   return relocation;
    562  1.9.2.1  perseant }
    563  1.9.2.1  perseant 
    564  1.9.2.1  perseant /* Check whether RELOCATION overflows a relocation field described by
    565  1.9.2.1  perseant    HOWTO.  */
    566  1.9.2.1  perseant 
    567  1.9.2.1  perseant static bfd_reloc_status_type
    568  1.9.2.1  perseant check_overflow (reloc_howto_type *howto, bfd_vma relocation)
    569  1.9.2.1  perseant {
    570  1.9.2.1  perseant   switch (howto->complain_on_overflow)
    571  1.9.2.1  perseant     {
    572  1.9.2.1  perseant     case complain_overflow_dont:
    573  1.9.2.1  perseant       break;
    574  1.9.2.1  perseant 
    575  1.9.2.1  perseant     case complain_overflow_bitfield:
    576  1.9.2.1  perseant       if ((bfd_signed_vma) relocation < -(1LL << (howto->bitsize - 1))
    577  1.9.2.1  perseant 	  || (bfd_signed_vma) relocation >= 1LL << howto->bitsize)
    578  1.9.2.1  perseant 	return bfd_reloc_overflow;
    579  1.9.2.1  perseant       break;
    580  1.9.2.1  perseant 
    581  1.9.2.1  perseant     case complain_overflow_signed:
    582  1.9.2.1  perseant       if ((bfd_signed_vma) relocation < -(1LL << (howto->bitsize - 1))
    583  1.9.2.1  perseant 	  || (bfd_signed_vma) relocation >= 1LL << (howto->bitsize - 1))
    584      1.5  christos 	return bfd_reloc_overflow;
    585  1.9.2.1  perseant       break;
    586  1.9.2.1  perseant 
    587  1.9.2.1  perseant     case complain_overflow_unsigned:
    588  1.9.2.1  perseant       if (relocation >= 1ULL << howto->bitsize)
    589  1.9.2.1  perseant 	return bfd_reloc_overflow;
    590  1.9.2.1  perseant       break;
    591  1.9.2.1  perseant     }
    592      1.5  christos   return bfd_reloc_ok;
    593      1.5  christos }
    594      1.5  christos 
    595      1.5  christos static bfd_reloc_status_type
    596      1.5  christos rl78_special_reloc (bfd *      input_bfd,
    597      1.5  christos 		    arelent *  reloc,
    598      1.5  christos 		    asymbol *  symbol,
    599      1.5  christos 		    void *     data,
    600  1.9.2.1  perseant 		    asection * input_section,
    601      1.5  christos 		    bfd *      output_bfd ATTRIBUTE_UNUSED,
    602      1.8  christos 		    char **    error_message)
    603      1.8  christos {
    604      1.8  christos   bfd_reloc_status_type	 r = bfd_reloc_ok;
    605      1.8  christos   bfd_vma		 relocation = 0;
    606      1.5  christos   unsigned long		 r_type = reloc->howto->type;
    607      1.5  christos   bfd_byte *		 contents = data;
    608      1.5  christos 
    609      1.5  christos   /* If necessary, compute the symbolic value of the relocation.  */
    610      1.5  christos   switch (r_type)
    611      1.5  christos     {
    612      1.5  christos     case R_RL78_SYM:
    613      1.5  christos       relocation = (symbol->value
    614      1.5  christos 		    + symbol->section->output_section->vma
    615      1.5  christos 		    + symbol->section->output_offset
    616      1.5  christos 		    + reloc->addend);
    617      1.5  christos 	break;
    618      1.6  christos 
    619      1.5  christos     case R_RL78_OPromtop:
    620      1.5  christos       relocation = get_romstart (NULL, input_bfd, input_section,
    621      1.5  christos 				 reloc->address);
    622      1.5  christos       break;
    623      1.6  christos 
    624      1.5  christos     case R_RL78_OPramtop:
    625      1.5  christos       relocation = get_ramstart (NULL, input_bfd, input_section,
    626      1.5  christos 				 reloc->address);
    627      1.5  christos       break;
    628      1.5  christos     }
    629  1.9.2.1  perseant 
    630  1.9.2.1  perseant   /* Get the value of the relocation.  */
    631      1.5  christos   relocation = rl78_compute_complex_reloc (r_type, relocation, input_section,
    632  1.9.2.1  perseant 					   &r, error_message);
    633      1.5  christos 
    634  1.9.2.1  perseant   if (STACK_REL_P (r_type))
    635  1.9.2.1  perseant     {
    636      1.5  christos       bfd_size_type limit;
    637  1.9.2.1  perseant       unsigned int nbytes;
    638  1.9.2.1  perseant 
    639      1.5  christos       if (r == bfd_reloc_ok)
    640  1.9.2.1  perseant 	r = check_overflow (reloc->howto, relocation);
    641  1.9.2.1  perseant 
    642  1.9.2.1  perseant       if (r_type == R_RL78_ABS16_REV)
    643  1.9.2.1  perseant 	relocation = ((relocation & 0xff) << 8) | ((relocation >> 8) & 0xff);
    644  1.9.2.1  perseant       else if (r_type == R_RL78_ABS32_REV)
    645  1.9.2.1  perseant 	relocation = (((relocation & 0xff) << 24)
    646  1.9.2.1  perseant 		      | ((relocation & 0xff00) << 8)
    647      1.5  christos 		      | ((relocation >> 8) & 0xff00)
    648  1.9.2.1  perseant 		      | ((relocation >> 24) & 0xff));
    649  1.9.2.1  perseant 
    650  1.9.2.1  perseant       limit = bfd_get_section_limit_octets (input_bfd, input_section);
    651  1.9.2.1  perseant       nbytes = reloc->howto->bitsize / 8;
    652  1.9.2.1  perseant       if (reloc->address < limit
    653  1.9.2.1  perseant 	  && nbytes <= limit - reloc->address)
    654      1.5  christos 	{
    655  1.9.2.1  perseant 	  unsigned int i;
    656  1.9.2.1  perseant 
    657  1.9.2.1  perseant 	  for (i = 0; i < nbytes; i++)
    658  1.9.2.1  perseant 	    {
    659  1.9.2.1  perseant 	      contents[reloc->address + i] = relocation;
    660  1.9.2.1  perseant 	      relocation >>= 8;
    661  1.9.2.1  perseant 	    }
    662  1.9.2.1  perseant 	}
    663      1.5  christos       else
    664      1.5  christos 	r = bfd_reloc_outofrange;
    665      1.5  christos     }
    666      1.5  christos 
    667      1.5  christos   return r;
    668      1.5  christos }
    669      1.5  christos 
    670      1.1  christos #define OP(i)      (contents[rel->r_offset + (i)])
    671      1.1  christos 
    672      1.1  christos /* Relocate an RL78 ELF section.
    673      1.1  christos    There is some attempt to make this function usable for many architectures,
    674      1.1  christos    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
    675      1.1  christos    if only to serve as a learning tool.
    676      1.1  christos 
    677      1.1  christos    The RELOCATE_SECTION function is called by the new ELF backend linker
    678      1.1  christos    to handle the relocations for a section.
    679      1.1  christos 
    680      1.1  christos    The relocs are always passed as Rela structures; if the section
    681      1.1  christos    actually uses Rel structures, the r_addend field will always be
    682      1.1  christos    zero.
    683      1.1  christos 
    684      1.1  christos    This function is responsible for adjusting the section contents as
    685      1.1  christos    necessary, and (if using Rela relocs and generating a relocatable
    686      1.1  christos    output file) adjusting the reloc addend as necessary.
    687      1.1  christos 
    688      1.1  christos    This function does not have to worry about setting the reloc
    689      1.1  christos    address or the reloc symbol index.
    690      1.1  christos 
    691      1.1  christos    LOCAL_SYMS is a pointer to the swapped in local symbols.
    692      1.1  christos 
    693      1.1  christos    LOCAL_SECTIONS is an array giving the section in the input file
    694      1.1  christos    corresponding to the st_shndx field of each local symbol.
    695      1.1  christos 
    696      1.1  christos    The global hash table entry for the global symbols can be found
    697      1.1  christos    via elf_sym_hashes (input_bfd).
    698      1.1  christos 
    699      1.1  christos    When generating relocatable output, this function must handle
    700      1.1  christos    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
    701      1.1  christos    going to be the section symbol corresponding to the output
    702      1.1  christos    section, which means that the addend must be adjusted
    703  1.9.2.1  perseant    accordingly.  */
    704      1.1  christos 
    705      1.8  christos static int
    706      1.1  christos rl78_elf_relocate_section
    707      1.8  christos     (bfd *		     output_bfd,
    708      1.8  christos      struct bfd_link_info *  info,
    709      1.8  christos      bfd *		     input_bfd,
    710      1.1  christos      asection *		     input_section,
    711      1.8  christos      bfd_byte *		     contents,
    712      1.8  christos      Elf_Internal_Rela *     relocs,
    713      1.1  christos      Elf_Internal_Sym *	     local_syms,
    714      1.8  christos      asection **	     local_sections)
    715      1.1  christos {
    716      1.8  christos   Elf_Internal_Shdr *		symtab_hdr;
    717      1.8  christos   struct elf_link_hash_entry ** sym_hashes;
    718      1.1  christos   Elf_Internal_Rela *		rel;
    719  1.9.2.1  perseant   Elf_Internal_Rela *		relend;
    720      1.1  christos   asection *splt;
    721      1.1  christos   bool ret;
    722      1.1  christos 
    723      1.1  christos   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
    724      1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
    725      1.7  christos   relend     = relocs + input_section->reloc_count;
    726  1.9.2.1  perseant 
    727      1.1  christos   splt = elf_hash_table (info)->splt;
    728      1.1  christos   ret = true;
    729  1.9.2.1  perseant   for (rel = relocs; rel < relend; rel ++)
    730  1.9.2.1  perseant     {
    731  1.9.2.1  perseant       reloc_howto_type *howto;
    732  1.9.2.1  perseant       unsigned long r_symndx;
    733  1.9.2.1  perseant       Elf_Internal_Sym *sym;
    734  1.9.2.1  perseant       asection *sec;
    735  1.9.2.1  perseant       struct elf_link_hash_entry *h;
    736  1.9.2.1  perseant       bfd_vma relocation;
    737  1.9.2.1  perseant       bfd_reloc_status_type r;
    738  1.9.2.1  perseant       const char *name = NULL;
    739  1.9.2.1  perseant       bool unresolved_reloc = true;
    740      1.1  christos       int r_type;
    741      1.1  christos       char *error_message;
    742      1.1  christos 
    743      1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
    744      1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
    745      1.8  christos 
    746      1.1  christos       howto  = rl78_elf_howto_table + ELF32_R_TYPE (rel->r_info);
    747      1.1  christos       h	     = NULL;
    748      1.1  christos       sym    = NULL;
    749      1.1  christos       sec    = NULL;
    750      1.1  christos       relocation = 0;
    751      1.1  christos 
    752      1.1  christos       if (r_symndx < symtab_hdr->sh_info)
    753      1.1  christos 	{
    754      1.1  christos 	  sym = local_syms + r_symndx;
    755      1.1  christos 	  sec = local_sections [r_symndx];
    756      1.1  christos 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
    757      1.1  christos 
    758      1.9  christos 	  name = bfd_elf_string_from_elf_section
    759      1.1  christos 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
    760      1.1  christos 	  name = sym->st_name == 0 ? bfd_section_name (sec) : name;
    761      1.1  christos 	}
    762  1.9.2.1  perseant       else
    763  1.9.2.1  perseant 	{
    764      1.1  christos 	  bool warned ATTRIBUTE_UNUSED;
    765      1.1  christos 	  bool ignored ATTRIBUTE_UNUSED;
    766      1.1  christos 
    767      1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    768      1.1  christos 				   r_symndx, symtab_hdr, sym_hashes, h,
    769      1.1  christos 				   sec, relocation, unresolved_reloc,
    770      1.1  christos 				   warned, ignored);
    771      1.1  christos 
    772      1.1  christos 	  name = h->root.root.string;
    773      1.1  christos 	}
    774      1.1  christos 
    775      1.1  christos       if (sec != NULL && discarded_section (sec))
    776      1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    777      1.6  christos 					 rel, 1, relend, howto, 0, contents);
    778      1.1  christos 
    779      1.1  christos       if (bfd_link_relocatable (info))
    780      1.8  christos 	{
    781      1.8  christos 	  /* This is a relocatable link.  We don't have to change
    782      1.8  christos 	     anything, unless the reloc is against a section symbol,
    783      1.1  christos 	     in which case we have to adjust according to where the
    784      1.1  christos 	     section symbol winds up in the output section.  */
    785      1.1  christos 	  if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
    786      1.1  christos 	    rel->r_addend += sec->output_offset;
    787      1.1  christos 	  continue;
    788      1.1  christos 	}
    789      1.1  christos 
    790      1.1  christos       switch (ELF32_R_TYPE (rel->r_info))
    791      1.1  christos 	{
    792      1.1  christos 	case R_RL78_DIR16S:
    793      1.1  christos 	  {
    794      1.1  christos 	    bfd_vma *plt_offset;
    795      1.1  christos 
    796      1.1  christos 	    if (h != NULL)
    797      1.1  christos 	      plt_offset = &h->plt.offset;
    798      1.1  christos 	    else
    799      1.1  christos 	      plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
    800      1.1  christos 
    801      1.1  christos 	    if (! valid_16bit_address (relocation))
    802      1.1  christos 	      {
    803      1.1  christos 		/* If this is the first time we've processed this symbol,
    804      1.1  christos 		   fill in the plt entry with the correct symbol address.  */
    805      1.1  christos 		if ((*plt_offset & 1) == 0)
    806      1.1  christos 		  {
    807      1.1  christos 		    unsigned int x;
    808      1.1  christos 
    809      1.1  christos 		    x = 0x000000ec;  /* br !!abs24 */
    810      1.1  christos 		    x |= (relocation << 8) & 0xffffff00;
    811      1.1  christos 		    bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
    812      1.1  christos 		    *plt_offset |= 1;
    813      1.1  christos 		  }
    814      1.1  christos 
    815      1.1  christos 		relocation = (splt->output_section->vma
    816      1.1  christos 			      + splt->output_offset
    817      1.1  christos 			      + (*plt_offset & -2));
    818      1.1  christos 		if (name)
    819      1.1  christos 		{
    820      1.1  christos 		  char *newname = bfd_malloc (strlen(name)+5);
    821      1.1  christos 		  strcpy (newname, name);
    822      1.1  christos 		  strcat(newname, ".plt");
    823      1.1  christos 		  _bfd_generic_link_add_one_symbol (info,
    824      1.1  christos 						    input_bfd,
    825      1.1  christos 						    newname,
    826      1.1  christos 						    BSF_FUNCTION | BSF_WEAK,
    827      1.1  christos 						    splt,
    828      1.1  christos 						    (*plt_offset & -2),
    829      1.1  christos 						    0,
    830      1.1  christos 						    1,
    831      1.1  christos 						    0,
    832      1.1  christos 						    0);
    833      1.1  christos 		}
    834      1.1  christos 	      }
    835      1.1  christos 	  }
    836      1.1  christos 	  break;
    837      1.1  christos 	}
    838      1.1  christos 
    839      1.1  christos       if (h != NULL && h->root.type == bfd_link_hash_undefweak)
    840      1.1  christos 	/* If the symbol is undefined and weak
    841      1.1  christos 	   then the relocation resolves to zero.  */
    842      1.1  christos 	relocation = 0;
    843      1.1  christos       else
    844      1.1  christos 	{
    845      1.1  christos 	  if (howto->pc_relative)
    846      1.1  christos 	    {
    847      1.1  christos 	      relocation -= (input_section->output_section->vma
    848      1.1  christos 			     + input_section->output_offset
    849      1.1  christos 			     + rel->r_offset);
    850      1.1  christos 	      relocation -= bfd_get_reloc_size (howto);
    851      1.1  christos 	    }
    852      1.1  christos 
    853      1.1  christos 	  relocation += rel->r_addend;
    854      1.1  christos 	}
    855  1.9.2.1  perseant 
    856  1.9.2.1  perseant       r = bfd_reloc_ok;
    857  1.9.2.1  perseant       if (howto->bitsize != 0
    858  1.9.2.1  perseant 	  && (rel->r_offset >= input_section->size
    859  1.9.2.1  perseant 	      || ((howto->bitsize + 7u) / 8
    860  1.9.2.1  perseant 		  > input_section->size - rel->r_offset)))
    861  1.9.2.1  perseant 	r = bfd_reloc_outofrange;
    862  1.9.2.1  perseant       else
    863  1.9.2.1  perseant 	switch (r_type)
    864  1.9.2.1  perseant 	  {
    865      1.1  christos 	  case R_RL78_NONE:
    866  1.9.2.1  perseant 	    break;
    867  1.9.2.1  perseant 
    868      1.1  christos 	  case R_RL78_RH_RELAX:
    869  1.9.2.1  perseant 	    break;
    870  1.9.2.1  perseant 
    871  1.9.2.1  perseant 	  case R_RL78_DIR8S_PCREL:
    872  1.9.2.1  perseant 	    OP (0) = relocation;
    873  1.9.2.1  perseant 	    break;
    874  1.9.2.1  perseant 
    875  1.9.2.1  perseant 	  case R_RL78_DIR8S:
    876  1.9.2.1  perseant 	    OP (0) = relocation;
    877  1.9.2.1  perseant 	    break;
    878  1.9.2.1  perseant 
    879  1.9.2.1  perseant 	  case R_RL78_DIR8U:
    880  1.9.2.1  perseant 	    OP (0) = relocation;
    881  1.9.2.1  perseant 	    break;
    882  1.9.2.1  perseant 
    883  1.9.2.1  perseant 	  case R_RL78_DIR16S_PCREL:
    884  1.9.2.1  perseant 	    OP (0) = relocation;
    885  1.9.2.1  perseant 	    OP (1) = relocation >> 8;
    886  1.9.2.1  perseant 	    break;
    887  1.9.2.1  perseant 
    888  1.9.2.1  perseant 	  case R_RL78_DIR16S:
    889  1.9.2.1  perseant 	    if ((relocation & 0xf0000) == 0xf0000)
    890  1.9.2.1  perseant 	      relocation &= 0xffff;
    891  1.9.2.1  perseant 	    OP (0) = relocation;
    892  1.9.2.1  perseant 	    OP (1) = relocation >> 8;
    893  1.9.2.1  perseant 	    break;
    894  1.9.2.1  perseant 
    895  1.9.2.1  perseant 	  case R_RL78_DIR16U:
    896  1.9.2.1  perseant 	    OP (0) = relocation;
    897  1.9.2.1  perseant 	    OP (1) = relocation >> 8;
    898  1.9.2.1  perseant 	    break;
    899  1.9.2.1  perseant 
    900  1.9.2.1  perseant 	  case R_RL78_DIR16:
    901  1.9.2.1  perseant 	    OP (0) = relocation;
    902  1.9.2.1  perseant 	    OP (1) = relocation >> 8;
    903  1.9.2.1  perseant 	    break;
    904  1.9.2.1  perseant 
    905  1.9.2.1  perseant 	  case R_RL78_DIR16_REV:
    906  1.9.2.1  perseant 	    OP (1) = relocation;
    907  1.9.2.1  perseant 	    OP (0) = relocation >> 8;
    908  1.9.2.1  perseant 	    break;
    909  1.9.2.1  perseant 
    910  1.9.2.1  perseant 	  case R_RL78_DIR3U_PCREL:
    911  1.9.2.1  perseant 	    OP (0) &= 0xf8;
    912  1.9.2.1  perseant 	    OP (0) |= relocation & 0x07;
    913  1.9.2.1  perseant 	    /* Map [3, 10] to [0, 7].  The code below using howto
    914  1.9.2.1  perseant 	       bitsize will check for unsigned overflow.  */
    915  1.9.2.1  perseant 	    relocation -= 3;
    916  1.9.2.1  perseant 	    break;
    917  1.9.2.1  perseant 
    918  1.9.2.1  perseant 	  case R_RL78_DIR24S_PCREL:
    919  1.9.2.1  perseant 	    OP (0) = relocation;
    920  1.9.2.1  perseant 	    OP (1) = relocation >> 8;
    921  1.9.2.1  perseant 	    OP (2) = relocation >> 16;
    922  1.9.2.1  perseant 	    break;
    923  1.9.2.1  perseant 
    924  1.9.2.1  perseant 	  case R_RL78_DIR24S:
    925  1.9.2.1  perseant 	    OP (0) = relocation;
    926  1.9.2.1  perseant 	    OP (1) = relocation >> 8;
    927  1.9.2.1  perseant 	    OP (2) = relocation >> 16;
    928  1.9.2.1  perseant 	    break;
    929  1.9.2.1  perseant 
    930  1.9.2.1  perseant 	  case R_RL78_DIR32:
    931  1.9.2.1  perseant 	    OP (0) = relocation;
    932  1.9.2.1  perseant 	    OP (1) = relocation >> 8;
    933  1.9.2.1  perseant 	    OP (2) = relocation >> 16;
    934  1.9.2.1  perseant 	    OP (3) = relocation >> 24;
    935  1.9.2.1  perseant 	    break;
    936  1.9.2.1  perseant 
    937  1.9.2.1  perseant 	  case R_RL78_DIR32_REV:
    938  1.9.2.1  perseant 	    OP (3) = relocation;
    939  1.9.2.1  perseant 	    OP (2) = relocation >> 8;
    940  1.9.2.1  perseant 	    OP (1) = relocation >> 16;
    941  1.9.2.1  perseant 	    OP (0) = relocation >> 24;
    942  1.9.2.1  perseant 	    break;
    943  1.9.2.1  perseant 
    944  1.9.2.1  perseant 	  case R_RL78_RH_SFR:
    945  1.9.2.1  perseant 	    relocation -= 0xfff00;
    946  1.9.2.1  perseant 	    OP (0) = relocation;
    947  1.9.2.1  perseant 	    break;
    948  1.9.2.1  perseant 
    949  1.9.2.1  perseant 	  case R_RL78_RH_SADDR:
    950  1.9.2.1  perseant 	    relocation -= 0xffe20;
    951  1.9.2.1  perseant 	    OP (0) = relocation;
    952  1.9.2.1  perseant 	    break;
    953  1.9.2.1  perseant 
    954  1.9.2.1  perseant 	    /* Complex reloc handling:  */
    955  1.9.2.1  perseant 	  case R_RL78_ABS32:
    956  1.9.2.1  perseant 	  case R_RL78_ABS32_REV:
    957  1.9.2.1  perseant 	  case R_RL78_ABS24S_PCREL:
    958  1.9.2.1  perseant 	  case R_RL78_ABS24S:
    959  1.9.2.1  perseant 	  case R_RL78_ABS16:
    960  1.9.2.1  perseant 	  case R_RL78_ABS16_REV:
    961  1.9.2.1  perseant 	  case R_RL78_ABS16S_PCREL:
    962  1.9.2.1  perseant 	  case R_RL78_ABS16S:
    963  1.9.2.1  perseant 	  case R_RL78_ABS16U:
    964  1.9.2.1  perseant 	  case R_RL78_ABS16UL:
    965  1.9.2.1  perseant 	  case R_RL78_ABS16UW:
    966  1.9.2.1  perseant 	  case R_RL78_ABS8:
    967  1.9.2.1  perseant 	  case R_RL78_ABS8U:
    968  1.9.2.1  perseant 	  case R_RL78_ABS8UL:
    969  1.9.2.1  perseant 	  case R_RL78_ABS8UW:
    970  1.9.2.1  perseant 	  case R_RL78_ABS8S_PCREL:
    971  1.9.2.1  perseant 	  case R_RL78_ABS8S:
    972  1.9.2.1  perseant 	  case R_RL78_OPneg:
    973  1.9.2.1  perseant 	  case R_RL78_OPadd:
    974  1.9.2.1  perseant 	  case R_RL78_OPsub:
    975  1.9.2.1  perseant 	  case R_RL78_OPmul:
    976  1.9.2.1  perseant 	  case R_RL78_OPdiv:
    977  1.9.2.1  perseant 	  case R_RL78_OPshla:
    978  1.9.2.1  perseant 	  case R_RL78_OPshra:
    979  1.9.2.1  perseant 	  case R_RL78_OPsctsize:
    980  1.9.2.1  perseant 	  case R_RL78_OPscttop:
    981  1.9.2.1  perseant 	  case R_RL78_OPand:
    982  1.9.2.1  perseant 	  case R_RL78_OPor:
    983  1.9.2.1  perseant 	  case R_RL78_OPxor:
    984  1.9.2.1  perseant 	  case R_RL78_OPnot:
    985  1.9.2.1  perseant 	  case R_RL78_OPmod:
    986      1.6  christos 	    relocation = rl78_compute_complex_reloc (r_type, 0, input_section,
    987  1.9.2.1  perseant 						     &r, &error_message);
    988  1.9.2.1  perseant 
    989  1.9.2.1  perseant 	    switch (r_type)
    990  1.9.2.1  perseant 	      {
    991  1.9.2.1  perseant 	      case R_RL78_ABS32:
    992  1.9.2.1  perseant 		OP (0) = relocation;
    993  1.9.2.1  perseant 		OP (1) = relocation >> 8;
    994  1.9.2.1  perseant 		OP (2) = relocation >> 16;
    995  1.9.2.1  perseant 		OP (3) = relocation >> 24;
    996  1.9.2.1  perseant 		break;
    997  1.9.2.1  perseant 
    998  1.9.2.1  perseant 	      case R_RL78_ABS32_REV:
    999  1.9.2.1  perseant 		OP (3) = relocation;
   1000  1.9.2.1  perseant 		OP (2) = relocation >> 8;
   1001  1.9.2.1  perseant 		OP (1) = relocation >> 16;
   1002  1.9.2.1  perseant 		OP (0) = relocation >> 24;
   1003  1.9.2.1  perseant 		break;
   1004  1.9.2.1  perseant 
   1005  1.9.2.1  perseant 	      case R_RL78_ABS24S_PCREL:
   1006  1.9.2.1  perseant 	      case R_RL78_ABS24S:
   1007  1.9.2.1  perseant 		OP (0) = relocation;
   1008  1.9.2.1  perseant 		OP (1) = relocation >> 8;
   1009  1.9.2.1  perseant 		OP (2) = relocation >> 16;
   1010  1.9.2.1  perseant 		break;
   1011  1.9.2.1  perseant 
   1012  1.9.2.1  perseant 	      case R_RL78_ABS16:
   1013  1.9.2.1  perseant 		OP (0) = relocation;
   1014  1.9.2.1  perseant 		OP (1) = relocation >> 8;
   1015  1.9.2.1  perseant 		break;
   1016  1.9.2.1  perseant 
   1017  1.9.2.1  perseant 	      case R_RL78_ABS16_REV:
   1018  1.9.2.1  perseant 		OP (1) = relocation;
   1019  1.9.2.1  perseant 		OP (0) = relocation >> 8;
   1020  1.9.2.1  perseant 		break;
   1021  1.9.2.1  perseant 
   1022  1.9.2.1  perseant 	      case R_RL78_ABS16S_PCREL:
   1023  1.9.2.1  perseant 	      case R_RL78_ABS16S:
   1024  1.9.2.1  perseant 		OP (0) = relocation;
   1025  1.9.2.1  perseant 		OP (1) = relocation >> 8;
   1026  1.9.2.1  perseant 		break;
   1027  1.9.2.1  perseant 
   1028  1.9.2.1  perseant 	      case R_RL78_ABS16U:
   1029  1.9.2.1  perseant 	      case R_RL78_ABS16UL:
   1030  1.9.2.1  perseant 	      case R_RL78_ABS16UW:
   1031  1.9.2.1  perseant 		OP (0) = relocation;
   1032  1.9.2.1  perseant 		OP (1) = relocation >> 8;
   1033  1.9.2.1  perseant 		break;
   1034  1.9.2.1  perseant 
   1035  1.9.2.1  perseant 	      case R_RL78_ABS8:
   1036  1.9.2.1  perseant 		OP (0) = relocation;
   1037  1.9.2.1  perseant 		break;
   1038  1.9.2.1  perseant 
   1039  1.9.2.1  perseant 	      case R_RL78_ABS8U:
   1040  1.9.2.1  perseant 	      case R_RL78_ABS8UL:
   1041  1.9.2.1  perseant 	      case R_RL78_ABS8UW:
   1042  1.9.2.1  perseant 		OP (0) = relocation;
   1043  1.9.2.1  perseant 		break;
   1044  1.9.2.1  perseant 
   1045  1.9.2.1  perseant 	      case R_RL78_ABS8S_PCREL:
   1046  1.9.2.1  perseant 	      case R_RL78_ABS8S:
   1047      1.1  christos 		OP (0) = relocation;
   1048  1.9.2.1  perseant 		break;
   1049  1.9.2.1  perseant 
   1050  1.9.2.1  perseant 	      default:
   1051  1.9.2.1  perseant 		break;
   1052      1.1  christos 	      }
   1053  1.9.2.1  perseant 	    break;
   1054  1.9.2.1  perseant 
   1055  1.9.2.1  perseant 	  case R_RL78_SYM:
   1056  1.9.2.1  perseant 	    if (r_symndx < symtab_hdr->sh_info)
   1057  1.9.2.1  perseant 	      relocation = sec->output_section->vma + sec->output_offset
   1058  1.9.2.1  perseant 		+ sym->st_value + rel->r_addend;
   1059  1.9.2.1  perseant 	    else if (h != NULL
   1060  1.9.2.1  perseant 		     && (h->root.type == bfd_link_hash_defined
   1061  1.9.2.1  perseant 			 || h->root.type == bfd_link_hash_defweak))
   1062  1.9.2.1  perseant 	      relocation = h->root.u.def.value
   1063  1.9.2.1  perseant 		+ sec->output_section->vma
   1064  1.9.2.1  perseant 		+ sec->output_offset
   1065  1.9.2.1  perseant 		+ rel->r_addend;
   1066  1.9.2.1  perseant 	    else
   1067  1.9.2.1  perseant 	      {
   1068  1.9.2.1  perseant 		relocation = 0;
   1069  1.9.2.1  perseant 		if (h->root.type != bfd_link_hash_undefweak)
   1070  1.9.2.1  perseant 		  _bfd_error_handler
   1071  1.9.2.1  perseant 		    (_("warning: RL78_SYM reloc with an unknown symbol"));
   1072  1.9.2.1  perseant 	      }
   1073  1.9.2.1  perseant 	    (void) rl78_compute_complex_reloc (r_type, relocation, input_section,
   1074  1.9.2.1  perseant 					       &r, &error_message);
   1075  1.9.2.1  perseant 	    break;
   1076  1.9.2.1  perseant 
   1077  1.9.2.1  perseant 	  case R_RL78_OPromtop:
   1078  1.9.2.1  perseant 	    relocation = get_romstart (info, input_bfd, input_section,
   1079  1.9.2.1  perseant 				       rel->r_offset);
   1080  1.9.2.1  perseant 	    (void) rl78_compute_complex_reloc (r_type, relocation, input_section,
   1081  1.9.2.1  perseant 					       &r, &error_message);
   1082  1.9.2.1  perseant 	    break;
   1083  1.9.2.1  perseant 
   1084  1.9.2.1  perseant 	  case R_RL78_OPramtop:
   1085  1.9.2.1  perseant 	    relocation = get_ramstart (info, input_bfd, input_section,
   1086  1.9.2.1  perseant 				       rel->r_offset);
   1087  1.9.2.1  perseant 	    (void) rl78_compute_complex_reloc (r_type, relocation, input_section,
   1088  1.9.2.1  perseant 					       &r, &error_message);
   1089  1.9.2.1  perseant 	    break;
   1090  1.9.2.1  perseant 
   1091  1.9.2.1  perseant 	  default:
   1092  1.9.2.1  perseant 	    r = bfd_reloc_notsupported;
   1093      1.1  christos 	    break;
   1094  1.9.2.1  perseant 	  }
   1095  1.9.2.1  perseant 
   1096      1.1  christos       if (r == bfd_reloc_ok)
   1097      1.1  christos 	r = check_overflow (howto, relocation);
   1098      1.1  christos 
   1099      1.1  christos       if (r != bfd_reloc_ok)
   1100      1.1  christos 	{
   1101      1.1  christos 	  switch (r)
   1102  1.9.2.1  perseant 	    {
   1103  1.9.2.1  perseant 	    case bfd_reloc_overflow:
   1104  1.9.2.1  perseant 	      (*info->callbacks->reloc_overflow)
   1105      1.1  christos 		(info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
   1106      1.1  christos 		 input_bfd, input_section, rel->r_offset);
   1107      1.1  christos 	      break;
   1108      1.6  christos 
   1109  1.9.2.1  perseant 	    case bfd_reloc_undefined:
   1110      1.1  christos 	      (*info->callbacks->undefined_symbol)
   1111      1.1  christos 		(info, name, input_bfd, input_section, rel->r_offset, true);
   1112      1.1  christos 	      break;
   1113  1.9.2.1  perseant 
   1114  1.9.2.1  perseant 	    case bfd_reloc_outofrange:
   1115  1.9.2.1  perseant 	       /* xgettext:c-format */
   1116  1.9.2.1  perseant 	      (*info->callbacks->einfo)
   1117      1.1  christos 		(_("%H: %s out of range\n"),
   1118      1.1  christos 		 input_bfd, input_section, rel->r_offset, howto->name);
   1119      1.1  christos 	      break;
   1120      1.7  christos 
   1121  1.9.2.1  perseant 	    case bfd_reloc_notsupported:
   1122  1.9.2.1  perseant 	      /* xgettext:c-format */
   1123  1.9.2.1  perseant 	      (*info->callbacks->einfo)
   1124      1.1  christos 		(_("%H: relocation type %u is not supported\n"),
   1125      1.1  christos 		 input_bfd, input_section, rel->r_offset, r_type);
   1126      1.1  christos 	      break;
   1127  1.9.2.1  perseant 
   1128  1.9.2.1  perseant 	    case bfd_reloc_dangerous:
   1129      1.1  christos 	      (*info->callbacks->reloc_dangerous)
   1130      1.1  christos 		(info, error_message, input_bfd, input_section, rel->r_offset);
   1131      1.1  christos 	      break;
   1132      1.7  christos 
   1133  1.9.2.1  perseant 	    default:
   1134  1.9.2.1  perseant 	      /* xgettext:c-format */
   1135  1.9.2.1  perseant 	      (*info->callbacks->einfo)
   1136      1.1  christos 		(_("%H: relocation %s returns an unrecognized value %x\n"),
   1137      1.1  christos 		 input_bfd, input_section, rel->r_offset, howto->name, r);
   1138  1.9.2.1  perseant 	      break;
   1139      1.1  christos 	    }
   1140      1.1  christos 	  ret = false;
   1141      1.1  christos 	}
   1142  1.9.2.1  perseant     }
   1143      1.1  christos 
   1144      1.1  christos   return ret;
   1145      1.1  christos }
   1146      1.1  christos 
   1147  1.9.2.1  perseant /* Function to set the ELF flag bits.  */
   1149      1.1  christos 
   1150      1.1  christos static bool
   1151  1.9.2.1  perseant rl78_elf_set_private_flags (bfd * abfd, flagword flags)
   1152  1.9.2.1  perseant {
   1153      1.1  christos   elf_elfheader (abfd)->e_flags = flags;
   1154      1.1  christos   elf_flags_init (abfd) = true;
   1155  1.9.2.1  perseant   return true;
   1156      1.1  christos }
   1157  1.9.2.1  perseant 
   1158      1.1  christos static bool no_warn_mismatch = false;
   1159      1.1  christos 
   1160  1.9.2.1  perseant void bfd_elf32_rl78_set_target_flags (bool);
   1161      1.1  christos 
   1162      1.1  christos void
   1163      1.1  christos bfd_elf32_rl78_set_target_flags (bool user_no_warn_mismatch)
   1164      1.1  christos {
   1165      1.5  christos   no_warn_mismatch = user_no_warn_mismatch;
   1166      1.5  christos }
   1167      1.5  christos 
   1168      1.5  christos static const char *
   1169      1.5  christos rl78_cpu_name (flagword flags)
   1170      1.5  christos {
   1171      1.5  christos   switch (flags & E_FLAG_RL78_CPU_MASK)
   1172      1.5  christos     {
   1173      1.5  christos     default: return "";
   1174      1.5  christos     case E_FLAG_RL78_G10:     return "G10";
   1175      1.5  christos     case E_FLAG_RL78_G13:     return "G13";
   1176      1.5  christos     case E_FLAG_RL78_G14:     return "G14";
   1177      1.1  christos     }
   1178      1.1  christos }
   1179      1.1  christos 
   1180  1.9.2.1  perseant /* Merge backend specific data from an object file to the output
   1181      1.7  christos    object file when linking.  */
   1182      1.1  christos 
   1183      1.7  christos static bool
   1184      1.1  christos rl78_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   1185      1.1  christos {
   1186  1.9.2.1  perseant   bfd *obfd = info->output_bfd;
   1187      1.1  christos   flagword new_flags;
   1188      1.1  christos   flagword old_flags;
   1189      1.1  christos   bool error = false;
   1190      1.1  christos 
   1191      1.1  christos   new_flags = elf_elfheader (ibfd)->e_flags;
   1192      1.1  christos   old_flags = elf_elfheader (obfd)->e_flags;
   1193      1.1  christos 
   1194  1.9.2.1  perseant   if (!elf_flags_init (obfd))
   1195      1.1  christos     {
   1196      1.1  christos       /* First call, no flags set.  */
   1197      1.1  christos       elf_flags_init (obfd) = true;
   1198      1.1  christos       elf_elfheader (obfd)->e_flags = new_flags;
   1199      1.1  christos     }
   1200      1.1  christos   else if (old_flags != new_flags)
   1201      1.5  christos     {
   1202      1.1  christos       flagword changed_flags = old_flags ^ new_flags;
   1203      1.5  christos 
   1204      1.5  christos       if (changed_flags & E_FLAG_RL78_CPU_MASK)
   1205      1.1  christos 	{
   1206      1.5  christos 	  flagword out_cpu = old_flags & E_FLAG_RL78_CPU_MASK;
   1207      1.5  christos 	  flagword in_cpu = new_flags & E_FLAG_RL78_CPU_MASK;
   1208      1.5  christos 
   1209      1.5  christos 	  if (in_cpu == E_FLAG_RL78_ANY_CPU || in_cpu == out_cpu)
   1210      1.5  christos 	    /* It does not matter what new_cpu may have.  */;
   1211      1.5  christos 	  else if (out_cpu == E_FLAG_RL78_ANY_CPU)
   1212      1.5  christos 	    {
   1213      1.5  christos 	      if (in_cpu == E_FLAG_RL78_G10)
   1214      1.5  christos 		{
   1215      1.5  christos 		  /* G10 files can only be linked with other G10 files.
   1216  1.9.2.1  perseant 		     If the output is set to "any" this means that it is
   1217      1.5  christos 		     a G14 file that does not use hardware multiply/divide,
   1218      1.7  christos 		     but that is still incompatible with the G10 ABI.  */
   1219      1.7  christos 		  error = true;
   1220      1.8  christos 
   1221      1.8  christos 		  _bfd_error_handler
   1222      1.7  christos 		    /* xgettext:c-format */
   1223      1.5  christos 		    (_("RL78 ABI conflict: G10 file %pB cannot be linked"
   1224      1.5  christos 		       " with %s file %pB"),
   1225      1.5  christos 		     ibfd, rl78_cpu_name (out_cpu), obfd);
   1226      1.5  christos 		}
   1227      1.5  christos 	      else
   1228      1.5  christos 		{
   1229      1.5  christos 		  old_flags &= ~ E_FLAG_RL78_CPU_MASK;
   1230      1.5  christos 		  old_flags |= in_cpu;
   1231      1.1  christos 		  elf_elfheader (obfd)->e_flags = old_flags;
   1232      1.5  christos 		}
   1233  1.9.2.1  perseant 	    }
   1234      1.5  christos 	  else
   1235      1.7  christos 	    {
   1236      1.7  christos 	      error = true;
   1237      1.8  christos 
   1238      1.7  christos 	      _bfd_error_handler
   1239      1.7  christos 		/* xgettext:c-format */
   1240      1.5  christos 		(_("RL78 ABI conflict: cannot link %s file %pB with %s file %pB"),
   1241      1.1  christos 		 rl78_cpu_name (in_cpu),  ibfd,
   1242      1.3  christos 		 rl78_cpu_name (out_cpu), obfd);
   1243      1.3  christos 	    }
   1244      1.3  christos 	}
   1245      1.7  christos 
   1246      1.3  christos       if (changed_flags & E_FLAG_RL78_64BIT_DOUBLES)
   1247      1.3  christos 	{
   1248      1.3  christos 	  _bfd_error_handler
   1249      1.7  christos 	    (_("RL78 merge conflict: cannot link 32-bit and 64-bit objects together"));
   1250      1.8  christos 
   1251      1.7  christos 	  if (old_flags & E_FLAG_RL78_64BIT_DOUBLES)
   1252      1.3  christos 	    /* xgettext:c-format */
   1253      1.7  christos 	    _bfd_error_handler (_("- %pB is 64-bit, %pB is not"),
   1254      1.8  christos 				obfd, ibfd);
   1255      1.7  christos 	  else
   1256  1.9.2.1  perseant 	    /* xgettext:c-format */
   1257      1.6  christos 	    _bfd_error_handler (_("- %pB is 64-bit, %pB is not"),
   1258      1.1  christos 				ibfd, obfd);
   1259      1.1  christos 	  error = true;
   1260      1.1  christos 	}
   1261      1.1  christos     }
   1262      1.1  christos 
   1263  1.9.2.1  perseant   return !error;
   1264      1.1  christos }
   1265      1.1  christos 
   1266      1.1  christos static bool
   1268      1.1  christos rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
   1269      1.1  christos {
   1270      1.1  christos   FILE * file = (FILE *) ptr;
   1271      1.1  christos   flagword flags;
   1272      1.1  christos 
   1273      1.1  christos   BFD_ASSERT (abfd != NULL && ptr != NULL);
   1274      1.1  christos 
   1275      1.1  christos   /* Print normal ELF private data.  */
   1276      1.1  christos   _bfd_elf_print_private_bfd_data (abfd, ptr);
   1277      1.5  christos 
   1278      1.5  christos   flags = elf_elfheader (abfd)->e_flags;
   1279      1.1  christos   fprintf (file, _("private flags = 0x%lx:"), (long) flags);
   1280      1.3  christos 
   1281      1.3  christos   if (flags & E_FLAG_RL78_CPU_MASK)
   1282      1.3  christos     fprintf (file, " [%s]", rl78_cpu_name (flags));
   1283      1.1  christos 
   1284  1.9.2.1  perseant   if (flags & E_FLAG_RL78_64BIT_DOUBLES)
   1285      1.1  christos     fprintf (file, _(" [64-bit doubles]"));
   1286      1.1  christos 
   1287      1.1  christos   fputc ('\n', file);
   1288      1.1  christos   return true;
   1289      1.1  christos }
   1290      1.5  christos 
   1291      1.1  christos /* Return the MACH for an e_flags value.  */
   1292      1.5  christos 
   1293      1.1  christos static int
   1294      1.1  christos elf32_rl78_machine (bfd * abfd ATTRIBUTE_UNUSED)
   1295  1.9.2.1  perseant {
   1296      1.1  christos   return bfd_mach_rl78;
   1297      1.1  christos }
   1298      1.1  christos 
   1299      1.1  christos static bool
   1300  1.9.2.1  perseant rl78_elf_object_p (bfd * abfd)
   1301      1.1  christos {
   1302      1.1  christos   bfd_default_set_arch_mach (abfd, bfd_arch_rl78,
   1303      1.1  christos 			     elf32_rl78_machine (abfd));
   1304      1.1  christos   return true;
   1305      1.1  christos }
   1306      1.1  christos 
   1307      1.1  christos /* support PLT for 16-bit references to 24-bit functions.  */
   1309      1.1  christos 
   1310      1.8  christos /* We support 16-bit pointers to code above 64k by generating a thunk
   1311      1.1  christos    below 64k containing a JMP instruction to the final address.  */
   1312      1.8  christos 
   1313      1.1  christos static bool
   1314      1.1  christos rl78_elf_check_relocs
   1315      1.8  christos     (bfd *		       abfd,
   1316      1.1  christos      struct bfd_link_info *    info,
   1317      1.8  christos      asection *		       sec,
   1318      1.8  christos      const Elf_Internal_Rela * relocs)
   1319      1.1  christos {
   1320      1.1  christos   Elf_Internal_Shdr *		symtab_hdr;
   1321      1.1  christos   struct elf_link_hash_entry ** sym_hashes;
   1322      1.1  christos   const Elf_Internal_Rela *	rel;
   1323      1.6  christos   const Elf_Internal_Rela *	rel_end;
   1324  1.9.2.1  perseant   bfd_vma *local_plt_offsets;
   1325      1.1  christos   asection *splt;
   1326      1.1  christos   bfd *dynobj;
   1327      1.1  christos 
   1328      1.1  christos   if (bfd_link_relocatable (info))
   1329      1.1  christos     return true;
   1330      1.1  christos 
   1331      1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1332      1.1  christos   sym_hashes = elf_sym_hashes (abfd);
   1333      1.1  christos   local_plt_offsets = elf_local_got_offsets (abfd);
   1334      1.1  christos   dynobj = elf_hash_table(info)->dynobj;
   1335      1.1  christos 
   1336      1.1  christos   rel_end = relocs + sec->reloc_count;
   1337      1.1  christos   for (rel = relocs; rel < rel_end; rel++)
   1338      1.1  christos     {
   1339      1.1  christos       struct elf_link_hash_entry *h;
   1340      1.8  christos       unsigned long r_symndx;
   1341      1.1  christos       bfd_vma *offset;
   1342      1.1  christos 
   1343      1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1344      1.1  christos       if (r_symndx < symtab_hdr->sh_info)
   1345      1.1  christos 	h = NULL;
   1346      1.1  christos       else
   1347      1.1  christos 	{
   1348      1.1  christos 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1349      1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   1350      1.8  christos 		 || h->root.type == bfd_link_hash_warning)
   1351      1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1352      1.1  christos 	}
   1353      1.1  christos 
   1354      1.1  christos       switch (ELF32_R_TYPE (rel->r_info))
   1355      1.1  christos 	{
   1356      1.1  christos 	  /* This relocation describes a 16-bit pointer to a function.
   1357      1.7  christos 	     We may need to allocate a thunk in low memory; reserve memory
   1358      1.1  christos 	     for it now.  */
   1359      1.1  christos 	case R_RL78_DIR16S:
   1360      1.7  christos 	  if (dynobj == NULL)
   1361      1.7  christos 	    elf_hash_table (info)->dynobj = dynobj = abfd;
   1362      1.7  christos 	  splt = elf_hash_table (info)->splt;
   1363      1.7  christos 	  if (splt == NULL)
   1364      1.7  christos 	    {
   1365      1.7  christos 	      flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
   1366      1.7  christos 				| SEC_IN_MEMORY | SEC_LINKER_CREATED
   1367      1.9  christos 				| SEC_READONLY | SEC_CODE);
   1368  1.9.2.1  perseant 	      splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
   1369      1.1  christos 							 flags);
   1370      1.1  christos 	      elf_hash_table (info)->splt = splt;
   1371      1.1  christos 	      if (splt == NULL
   1372      1.1  christos 		  || !bfd_set_section_alignment (splt, 1))
   1373      1.1  christos 		return false;
   1374      1.1  christos 	    }
   1375      1.1  christos 
   1376      1.1  christos 	  if (h != NULL)
   1377      1.1  christos 	    offset = &h->plt.offset;
   1378      1.1  christos 	  else
   1379      1.1  christos 	    {
   1380      1.1  christos 	      if (local_plt_offsets == NULL)
   1381      1.1  christos 		{
   1382      1.1  christos 		  size_t size;
   1383  1.9.2.1  perseant 		  unsigned int i;
   1384      1.1  christos 
   1385      1.1  christos 		  size = symtab_hdr->sh_info * sizeof (bfd_vma);
   1386      1.1  christos 		  local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
   1387      1.1  christos 		  if (local_plt_offsets == NULL)
   1388      1.1  christos 		    return false;
   1389      1.1  christos 		  elf_local_got_offsets (abfd) = local_plt_offsets;
   1390      1.1  christos 
   1391      1.1  christos 		  for (i = 0; i < symtab_hdr->sh_info; i++)
   1392      1.1  christos 		    local_plt_offsets[i] = (bfd_vma) -1;
   1393      1.1  christos 		}
   1394      1.1  christos 	      offset = &local_plt_offsets[r_symndx];
   1395      1.1  christos 	    }
   1396      1.1  christos 
   1397      1.1  christos 	  if (*offset == (bfd_vma) -1)
   1398      1.8  christos 	    {
   1399      1.1  christos 	      *offset = splt->size;
   1400      1.1  christos 	      splt->size += 4;
   1401  1.9.2.1  perseant 	    }
   1402      1.1  christos 	  break;
   1403      1.1  christos 	}
   1404      1.1  christos     }
   1405      1.1  christos 
   1406  1.9.2.1  perseant   return true;
   1407      1.1  christos }
   1408      1.8  christos 
   1409      1.1  christos /* This must exist if dynobj is ever set.  */
   1410      1.1  christos 
   1411      1.1  christos static bool
   1412      1.1  christos rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
   1413      1.1  christos 				  struct bfd_link_info *info)
   1414  1.9.2.1  perseant {
   1415      1.1  christos   bfd *dynobj;
   1416      1.1  christos   asection *splt;
   1417      1.1  christos 
   1418      1.1  christos   if (!elf_hash_table (info)->dynamic_sections_created)
   1419      1.1  christos     return true;
   1420      1.1  christos 
   1421      1.1  christos   /* As an extra sanity check, verify that all plt entries have been
   1422      1.5  christos      filled in.  However, relaxing might have changed the relocs so
   1423  1.9.2.1  perseant      that some plt entries don't get filled in, so we have to skip
   1424      1.1  christos      this check if we're relaxing.  Unfortunately, check_relocs is
   1425      1.7  christos      called before relaxation.  */
   1426      1.7  christos 
   1427      1.7  christos   if (info->relax_trip > 0)
   1428      1.1  christos     return true;
   1429      1.1  christos 
   1430      1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   1431      1.1  christos   splt = elf_hash_table (info)->splt;
   1432      1.1  christos   if (dynobj != NULL && splt != NULL)
   1433      1.1  christos     {
   1434      1.1  christos       bfd_byte *contents = splt->contents;
   1435      1.1  christos       unsigned int i, size = splt->size;
   1436      1.1  christos 
   1437      1.1  christos       for (i = 0; i < size; i += 4)
   1438      1.1  christos 	{
   1439  1.9.2.1  perseant 	  unsigned int x = bfd_get_32 (dynobj, contents + i);
   1440      1.1  christos 	  BFD_ASSERT (x != 0);
   1441      1.1  christos 	}
   1442  1.9.2.1  perseant     }
   1443      1.1  christos 
   1444      1.8  christos   return true;
   1445      1.1  christos }
   1446      1.1  christos 
   1447      1.1  christos static bool
   1448      1.1  christos rl78_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   1449      1.6  christos 			       struct bfd_link_info *info)
   1450  1.9.2.1  perseant {
   1451      1.1  christos   bfd *dynobj;
   1452      1.1  christos   asection *splt;
   1453      1.1  christos 
   1454  1.9.2.1  perseant   if (bfd_link_relocatable (info))
   1455      1.1  christos     return true;
   1456      1.7  christos 
   1457      1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   1458      1.1  christos   if (dynobj == NULL)
   1459      1.1  christos     return true;
   1460      1.1  christos 
   1461  1.9.2.1  perseant   splt = elf_hash_table (info)->splt;
   1462      1.1  christos   BFD_ASSERT (splt != NULL);
   1463  1.9.2.1  perseant 
   1464      1.1  christos   splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
   1465      1.1  christos   if (splt->contents == NULL)
   1466      1.1  christos     return false;
   1467      1.1  christos 
   1468      1.1  christos   return true;
   1469      1.1  christos }
   1470      1.1  christos 
   1471      1.1  christos 
   1472      1.1  christos 
   1474      1.1  christos /* Handle relaxing.  */
   1475      1.1  christos 
   1476  1.9.2.1  perseant /* A subroutine of rl78_elf_relax_section.  If the global symbol H
   1477      1.1  christos    is within the low 64k, remove any entry for it in the plt.  */
   1478      1.1  christos 
   1479  1.9.2.1  perseant struct relax_plt_data
   1480      1.1  christos {
   1481      1.1  christos   asection *splt;
   1482      1.1  christos   bool *again;
   1483      1.1  christos };
   1484      1.1  christos 
   1485      1.1  christos static bool
   1486      1.1  christos rl78_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
   1487      1.1  christos {
   1488      1.1  christos   struct relax_plt_data *data = (struct relax_plt_data *) xdata;
   1489      1.1  christos 
   1490      1.1  christos   if (h->plt.offset != (bfd_vma) -1)
   1491      1.1  christos     {
   1492      1.1  christos       bfd_vma address;
   1493      1.1  christos 
   1494      1.1  christos       if (h->root.type == bfd_link_hash_undefined
   1495      1.1  christos 	  || h->root.type == bfd_link_hash_undefweak)
   1496      1.1  christos 	address = 0;
   1497      1.1  christos       else
   1498      1.1  christos 	address = (h->root.u.def.section->output_section->vma
   1499      1.1  christos 		   + h->root.u.def.section->output_offset
   1500  1.9.2.1  perseant 		   + h->root.u.def.value);
   1501      1.1  christos 
   1502      1.1  christos       if (valid_16bit_address (address))
   1503      1.1  christos 	{
   1504  1.9.2.1  perseant 	  h->plt.offset = -1;
   1505      1.1  christos 	  data->splt->size -= 4;
   1506      1.1  christos 	  *data->again = true;
   1507      1.1  christos 	}
   1508      1.1  christos     }
   1509      1.1  christos 
   1510  1.9.2.1  perseant   return true;
   1511      1.1  christos }
   1512      1.1  christos 
   1513      1.1  christos /* A subroutine of rl78_elf_relax_section.  If the global symbol H
   1514      1.1  christos    previously had a plt entry, give it a new entry offset.  */
   1515      1.1  christos 
   1516      1.1  christos static bool
   1517      1.1  christos rl78_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
   1518      1.1  christos {
   1519      1.1  christos   bfd_vma *entry = (bfd_vma *) xdata;
   1520      1.1  christos 
   1521  1.9.2.1  perseant   if (h->plt.offset != (bfd_vma) -1)
   1522      1.1  christos     {
   1523      1.1  christos       h->plt.offset = *entry;
   1524  1.9.2.1  perseant       *entry += 4;
   1525      1.1  christos     }
   1526      1.8  christos 
   1527      1.8  christos   return true;
   1528  1.9.2.1  perseant }
   1529      1.1  christos 
   1530      1.1  christos static bool
   1531      1.1  christos rl78_elf_relax_plt_section (bfd *dynobj,
   1532      1.1  christos 			    asection *splt,
   1533      1.1  christos 			    struct bfd_link_info *info,
   1534  1.9.2.1  perseant 			    bool *again)
   1535      1.1  christos {
   1536      1.6  christos   struct relax_plt_data relax_plt_data;
   1537  1.9.2.1  perseant   bfd *ibfd;
   1538      1.1  christos 
   1539      1.1  christos   /* Assume nothing changes.  */
   1540      1.1  christos   *again = false;
   1541      1.1  christos 
   1542  1.9.2.1  perseant   if (bfd_link_relocatable (info))
   1543      1.1  christos     return true;
   1544      1.1  christos 
   1545      1.1  christos   /* We only relax the .plt section at the moment.  */
   1546  1.9.2.1  perseant   if (dynobj != elf_hash_table (info)->dynobj
   1547      1.1  christos       || strcmp (splt->name, ".plt") != 0)
   1548      1.1  christos     return true;
   1549      1.1  christos 
   1550      1.1  christos   /* Quick check for an empty plt.  */
   1551      1.1  christos   if (splt->size == 0)
   1552      1.1  christos     return true;
   1553      1.1  christos 
   1554      1.1  christos   /* Map across all global symbols; see which ones happen to
   1555      1.1  christos      fall in the low 64k.  */
   1556      1.1  christos   relax_plt_data.splt = splt;
   1557      1.3  christos   relax_plt_data.again = again;
   1558      1.1  christos   elf_link_hash_traverse (elf_hash_table (info), rl78_relax_plt_check,
   1559      1.1  christos 			  &relax_plt_data);
   1560      1.1  christos 
   1561      1.1  christos   /* Likewise for local symbols, though that's somewhat less convenient
   1562      1.1  christos      as we have to walk the list of input bfds and swap in symbol data.  */
   1563      1.1  christos   for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
   1564      1.1  christos     {
   1565      1.1  christos       bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
   1566      1.1  christos       Elf_Internal_Shdr *symtab_hdr;
   1567      1.1  christos       Elf_Internal_Sym *isymbuf = NULL;
   1568      1.1  christos       unsigned int idx;
   1569      1.1  christos 
   1570      1.1  christos       if (! local_plt_offsets)
   1571      1.1  christos 	continue;
   1572      1.1  christos 
   1573      1.1  christos       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
   1574      1.1  christos       if (symtab_hdr->sh_info != 0)
   1575      1.1  christos 	{
   1576  1.9.2.1  perseant 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1577      1.1  christos 	  if (isymbuf == NULL)
   1578      1.1  christos 	    isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
   1579      1.1  christos 					    symtab_hdr->sh_info, 0,
   1580      1.1  christos 					    NULL, NULL, NULL);
   1581      1.1  christos 	  if (isymbuf == NULL)
   1582      1.1  christos 	    return false;
   1583      1.1  christos 	}
   1584      1.1  christos 
   1585      1.1  christos       for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
   1586      1.1  christos 	{
   1587      1.1  christos 	  Elf_Internal_Sym *isym;
   1588      1.1  christos 	  asection *tsec;
   1589      1.1  christos 	  bfd_vma address;
   1590      1.1  christos 
   1591      1.1  christos 	  if (local_plt_offsets[idx] == (bfd_vma) -1)
   1592      1.1  christos 	    continue;
   1593      1.1  christos 
   1594      1.1  christos 	  isym = &isymbuf[idx];
   1595      1.1  christos 	  if (isym->st_shndx == SHN_UNDEF)
   1596      1.1  christos 	    continue;
   1597      1.1  christos 	  else if (isym->st_shndx == SHN_ABS)
   1598      1.1  christos 	    tsec = bfd_abs_section_ptr;
   1599      1.1  christos 	  else if (isym->st_shndx == SHN_COMMON)
   1600      1.1  christos 	    tsec = bfd_com_section_ptr;
   1601      1.1  christos 	  else
   1602      1.1  christos 	    tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
   1603      1.1  christos 
   1604      1.1  christos 	  address = (tsec->output_section->vma
   1605  1.9.2.1  perseant 		     + tsec->output_offset
   1606      1.1  christos 		     + isym->st_value);
   1607      1.1  christos 	  if (valid_16bit_address (address))
   1608      1.1  christos 	    {
   1609      1.1  christos 	      local_plt_offsets[idx] = -1;
   1610      1.1  christos 	      splt->size -= 4;
   1611      1.1  christos 	      *again = true;
   1612      1.1  christos 	    }
   1613      1.1  christos 	}
   1614      1.1  christos 
   1615      1.1  christos       if (isymbuf != NULL
   1616      1.1  christos 	  && symtab_hdr->contents != (unsigned char *) isymbuf)
   1617      1.1  christos 	{
   1618      1.1  christos 	  if (! info->keep_memory)
   1619      1.1  christos 	    free (isymbuf);
   1620      1.1  christos 	  else
   1621      1.1  christos 	    {
   1622      1.1  christos 	      /* Cache the symbols for elf_link_input_bfd.  */
   1623      1.1  christos 	      symtab_hdr->contents = (unsigned char *) isymbuf;
   1624      1.1  christos 	    }
   1625      1.1  christos 	}
   1626      1.1  christos     }
   1627      1.1  christos 
   1628      1.1  christos   /* If we changed anything, walk the symbols again to reallocate
   1629      1.1  christos      .plt entry addresses.  */
   1630      1.1  christos   if (*again && splt->size > 0)
   1631      1.3  christos     {
   1632      1.1  christos       bfd_vma entry = 0;
   1633      1.1  christos 
   1634      1.1  christos       elf_link_hash_traverse (elf_hash_table (info),
   1635      1.1  christos 			      rl78_relax_plt_realloc, &entry);
   1636      1.1  christos 
   1637      1.1  christos       for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
   1638      1.1  christos 	{
   1639      1.1  christos 	  bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
   1640      1.1  christos 	  unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
   1641      1.1  christos 	  unsigned int idx;
   1642      1.1  christos 
   1643      1.8  christos 	  if (! local_plt_offsets)
   1644      1.1  christos 	    continue;
   1645      1.1  christos 
   1646      1.1  christos 	  for (idx = 0; idx < nlocals; ++idx)
   1647      1.1  christos 	    if (local_plt_offsets[idx] != (bfd_vma) -1)
   1648      1.1  christos 	      {
   1649  1.9.2.1  perseant 		local_plt_offsets[idx] = entry;
   1650      1.1  christos 		entry += 4;
   1651      1.1  christos 	      }
   1652      1.1  christos 	}
   1653      1.1  christos     }
   1654  1.9.2.1  perseant 
   1655      1.1  christos   return true;
   1656      1.5  christos }
   1657      1.1  christos 
   1658      1.1  christos /* Delete some bytes from a section while relaxing.  */
   1659      1.8  christos 
   1660      1.8  christos static bool
   1661      1.1  christos elf32_rl78_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
   1662      1.1  christos 			       Elf_Internal_Rela *alignment_rel, int force_snip)
   1663      1.1  christos {
   1664      1.1  christos   Elf_Internal_Shdr * symtab_hdr;
   1665      1.8  christos   unsigned int	      sec_shndx;
   1666      1.8  christos   bfd_byte *	      contents;
   1667      1.1  christos   Elf_Internal_Rela * irel;
   1668      1.1  christos   Elf_Internal_Rela * irelend;
   1669      1.1  christos   Elf_Internal_Sym *  isym;
   1670      1.1  christos   Elf_Internal_Sym *  isymend;
   1671      1.1  christos   bfd_vma	      toaddr;
   1672      1.1  christos   unsigned int	      symcount;
   1673      1.1  christos   struct elf_link_hash_entry ** sym_hashes;
   1674      1.1  christos   struct elf_link_hash_entry ** end_hashes;
   1675      1.1  christos 
   1676      1.1  christos   if (!alignment_rel)
   1677      1.1  christos     force_snip = 1;
   1678      1.1  christos 
   1679      1.1  christos   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   1680      1.1  christos 
   1681      1.1  christos   contents = elf_section_data (sec)->this_hdr.contents;
   1682      1.1  christos 
   1683      1.1  christos   /* The deletion must stop at the next alignment boundary, if
   1684      1.1  christos      ALIGNMENT_REL is non-NULL.  */
   1685      1.1  christos   toaddr = sec->size;
   1686  1.9.2.1  perseant   if (alignment_rel)
   1687      1.1  christos     toaddr = alignment_rel->r_offset;
   1688      1.1  christos 
   1689      1.1  christos   irel = elf_section_data (sec)->relocs;
   1690      1.1  christos   if (irel == NULL)
   1691      1.1  christos     {
   1692      1.1  christos       _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, true);
   1693      1.1  christos       irel = elf_section_data (sec)->relocs;
   1694      1.1  christos     }
   1695      1.1  christos 
   1696      1.1  christos   irelend = irel + sec->reloc_count;
   1697      1.1  christos 
   1698      1.1  christos   /* Actually delete the bytes.  */
   1699      1.1  christos   memmove (contents + addr, contents + addr + count,
   1700      1.1  christos 	   (size_t) (toaddr - addr - count));
   1701      1.1  christos 
   1702      1.1  christos   /* If we don't have an alignment marker to worry about, we can just
   1703      1.1  christos      shrink the section.  Otherwise, we have to fill in the newly
   1704      1.1  christos      created gap with NOP insns (0x03).  */
   1705      1.1  christos   if (force_snip)
   1706      1.1  christos     sec->size -= count;
   1707      1.1  christos   else
   1708      1.1  christos     memset (contents + toaddr - count, 0x03, count);
   1709      1.1  christos 
   1710      1.1  christos   /* Adjust all the relocs.  */
   1711      1.1  christos   for (; irel && irel < irelend; irel++)
   1712      1.1  christos     {
   1713      1.1  christos       /* Get the new reloc address.  */
   1714      1.1  christos       if (irel->r_offset > addr
   1715      1.1  christos 	  && (irel->r_offset < toaddr
   1716      1.1  christos 	      || (force_snip && irel->r_offset == toaddr)))
   1717      1.1  christos 	irel->r_offset -= count;
   1718      1.1  christos 
   1719      1.1  christos       /* If we see an ALIGN marker at the end of the gap, we move it
   1720      1.1  christos 	 to the beginning of the gap, since marking these gaps is what
   1721      1.1  christos 	 they're for.  */
   1722      1.1  christos       if (irel->r_offset == toaddr
   1723      1.1  christos 	  && ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
   1724      1.1  christos 	  && irel->r_addend & RL78_RELAXA_ALIGN)
   1725      1.1  christos 	irel->r_offset -= count;
   1726      1.1  christos     }
   1727      1.1  christos 
   1728      1.1  christos   /* Adjust the local symbols defined in this section.  */
   1729      1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1730      1.1  christos   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
   1731      1.1  christos   isymend = isym + symtab_hdr->sh_info;
   1732      1.1  christos 
   1733      1.1  christos   for (; isym < isymend; isym++)
   1734      1.1  christos     {
   1735      1.1  christos       /* If the symbol is in the range of memory we just moved, we
   1736      1.1  christos 	 have to adjust its value.  */
   1737      1.1  christos       if (isym->st_shndx == sec_shndx
   1738      1.1  christos 	  && isym->st_value > addr
   1739      1.1  christos 	  && isym->st_value < toaddr)
   1740      1.1  christos 	isym->st_value -= count;
   1741      1.1  christos 
   1742      1.1  christos       /* If the symbol *spans* the bytes we just deleted (i.e. it's
   1743      1.1  christos 	 *end* is in the moved bytes but it's *start* isn't), then we
   1744      1.1  christos 	 must adjust its size.  */
   1745      1.1  christos       if (isym->st_shndx == sec_shndx
   1746      1.1  christos 	  && isym->st_value < addr
   1747      1.1  christos 	  && isym->st_value + isym->st_size > addr
   1748      1.1  christos 	  && isym->st_value + isym->st_size < toaddr)
   1749      1.1  christos 	isym->st_size -= count;
   1750      1.1  christos     }
   1751      1.1  christos 
   1752      1.1  christos   /* Now adjust the global symbols defined in this section.  */
   1753      1.1  christos   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
   1754      1.1  christos 	      - symtab_hdr->sh_info);
   1755      1.1  christos   sym_hashes = elf_sym_hashes (abfd);
   1756      1.1  christos   end_hashes = sym_hashes + symcount;
   1757      1.1  christos 
   1758      1.1  christos   for (; sym_hashes < end_hashes; sym_hashes++)
   1759      1.1  christos     {
   1760      1.1  christos       struct elf_link_hash_entry *sym_hash = *sym_hashes;
   1761      1.1  christos 
   1762      1.1  christos       if ((sym_hash->root.type == bfd_link_hash_defined
   1763      1.1  christos 	   || sym_hash->root.type == bfd_link_hash_defweak)
   1764      1.1  christos 	  && sym_hash->root.u.def.section == sec)
   1765      1.1  christos 	{
   1766      1.1  christos 	  /* As above, adjust the value if needed.  */
   1767      1.1  christos 	  if (sym_hash->root.u.def.value > addr
   1768      1.1  christos 	      && sym_hash->root.u.def.value < toaddr)
   1769      1.1  christos 	    sym_hash->root.u.def.value -= count;
   1770      1.1  christos 
   1771      1.1  christos 	  /* As above, adjust the size if needed.  */
   1772      1.1  christos 	  if (sym_hash->root.u.def.value < addr
   1773  1.9.2.1  perseant 	      && sym_hash->root.u.def.value + sym_hash->size > addr
   1774      1.1  christos 	      && sym_hash->root.u.def.value + sym_hash->size < toaddr)
   1775      1.1  christos 	    sym_hash->size -= count;
   1776      1.1  christos 	}
   1777      1.1  christos     }
   1778      1.1  christos 
   1779      1.1  christos   return true;
   1780      1.1  christos }
   1781      1.1  christos 
   1782      1.1  christos /* Used to sort relocs by address.  If relocs have the same address,
   1783      1.1  christos    we maintain their relative order, except that R_RL78_RH_RELAX
   1784  1.9.2.1  perseant    alignment relocs must be the first reloc for any given address.  */
   1785  1.9.2.1  perseant 
   1786      1.1  christos static void
   1787      1.1  christos reloc_bubblesort (Elf_Internal_Rela * r, int count)
   1788      1.1  christos {
   1789      1.1  christos   int i;
   1790      1.1  christos   bool again;
   1791      1.1  christos   bool swappit;
   1792  1.9.2.1  perseant 
   1793      1.1  christos   /* This is almost a classic bubblesort.  It's the slowest sort, but
   1794      1.1  christos      we're taking advantage of the fact that the relocations are
   1795  1.9.2.1  perseant      mostly in order already (the assembler emits them that way) and
   1796      1.1  christos      we need relocs with the same address to remain in the same
   1797      1.1  christos      relative order.  */
   1798      1.1  christos   again = true;
   1799  1.9.2.1  perseant   while (again)
   1800      1.1  christos     {
   1801  1.9.2.1  perseant       again = false;
   1802      1.1  christos       for (i = 0; i < count - 1; i ++)
   1803      1.1  christos 	{
   1804  1.9.2.1  perseant 	  if (r[i].r_offset > r[i + 1].r_offset)
   1805      1.1  christos 	    swappit = true;
   1806      1.1  christos 	  else if (r[i].r_offset < r[i + 1].r_offset)
   1807      1.1  christos 	    swappit = false;
   1808      1.1  christos 	  else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
   1809  1.9.2.1  perseant 		   && (r[i + 1].r_addend & RL78_RELAXA_ALIGN))
   1810      1.1  christos 	    swappit = true;
   1811  1.9.2.1  perseant 	  else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
   1812      1.1  christos 		   && (r[i + 1].r_addend & RL78_RELAXA_ELIGN)
   1813      1.1  christos 		   && !(ELF32_R_TYPE (r[i].r_info) == R_RL78_RH_RELAX
   1814      1.1  christos 			&& (r[i].r_addend & RL78_RELAXA_ALIGN)))
   1815      1.1  christos 	    swappit = true;
   1816      1.1  christos 	  else
   1817      1.1  christos 	    swappit = false;
   1818      1.1  christos 
   1819      1.1  christos 	  if (swappit)
   1820      1.1  christos 	    {
   1821      1.1  christos 	      Elf_Internal_Rela tmp;
   1822      1.1  christos 
   1823      1.1  christos 	      tmp = r[i];
   1824      1.1  christos 	      r[i] = r[i + 1];
   1825  1.9.2.1  perseant 	      r[i + 1] = tmp;
   1826      1.1  christos 	      /* If we do move a reloc back, re-scan to see if it
   1827      1.1  christos 		 needs to be moved even further back.  This avoids
   1828      1.1  christos 		 most of the O(n^2) behavior for our cases.  */
   1829      1.1  christos 	      if (i > 0)
   1830      1.1  christos 		i -= 2;
   1831      1.1  christos 	      again = true;
   1832      1.1  christos 	    }
   1833      1.1  christos 	}
   1834      1.5  christos     }
   1835      1.1  christos }
   1836      1.1  christos 
   1837      1.8  christos 
   1838      1.8  christos #define OFFSET_FOR_RELOC(rel, lrel, scale) \
   1839      1.8  christos   rl78_offset_for_reloc (abfd, rel + 1, symtab_hdr, shndx_buf, intsyms, \
   1840      1.9  christos 			 lrel, abfd, sec, link_info, scale)
   1841      1.8  christos 
   1842      1.8  christos static bfd_vma
   1843      1.8  christos rl78_offset_for_reloc (bfd *			abfd,
   1844      1.8  christos 		       Elf_Internal_Rela *	rel,
   1845      1.8  christos 		       Elf_Internal_Shdr *	symtab_hdr,
   1846      1.8  christos 		       bfd_byte *		shndx_buf ATTRIBUTE_UNUSED,
   1847      1.1  christos 		       Elf_Internal_Sym *	intsyms,
   1848      1.1  christos 		       Elf_Internal_Rela **	lrel,
   1849      1.1  christos 		       bfd *			input_bfd,
   1850      1.1  christos 		       asection *		input_section,
   1851      1.1  christos 		       struct bfd_link_info *	info,
   1852      1.1  christos 		       int *			scale)
   1853      1.1  christos {
   1854      1.1  christos   bfd_vma symval;
   1855      1.1  christos 
   1856      1.1  christos   *scale = 1;
   1857      1.5  christos 
   1858      1.1  christos   /* REL is the first of 1..N relocations.  We compute the symbol
   1859      1.1  christos      value for each relocation, then combine them if needed.  LREL
   1860      1.1  christos      gets a pointer to the last relocation used.  */
   1861      1.1  christos   while (1)
   1862      1.1  christos     {
   1863      1.1  christos       unsigned long r_type;
   1864      1.1  christos 
   1865      1.1  christos       /* Get the value of the symbol referred to by the reloc.  */
   1866      1.1  christos       if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
   1867      1.1  christos 	{
   1868      1.1  christos 	  /* A local symbol.  */
   1869      1.1  christos 	  Elf_Internal_Sym *isym;
   1870      1.1  christos 	  asection *ssec;
   1871      1.1  christos 
   1872      1.1  christos 	  isym = intsyms + ELF32_R_SYM (rel->r_info);
   1873      1.1  christos 
   1874      1.1  christos 	  if (isym->st_shndx == SHN_UNDEF)
   1875      1.1  christos 	    ssec = bfd_und_section_ptr;
   1876      1.1  christos 	  else if (isym->st_shndx == SHN_ABS)
   1877      1.1  christos 	    ssec = bfd_abs_section_ptr;
   1878      1.1  christos 	  else if (isym->st_shndx == SHN_COMMON)
   1879      1.1  christos 	    ssec = bfd_com_section_ptr;
   1880      1.1  christos 	  else
   1881      1.1  christos 	    ssec = bfd_section_from_elf_index (abfd,
   1882      1.1  christos 					       isym->st_shndx);
   1883      1.1  christos 
   1884      1.1  christos 	  /* Initial symbol value.  */
   1885      1.1  christos 	  symval = isym->st_value;
   1886      1.1  christos 
   1887      1.1  christos 	  /* GAS may have made this symbol relative to a section, in
   1888      1.1  christos 	     which case, we have to add the addend to find the
   1889      1.1  christos 	     symbol.  */
   1890      1.1  christos 	  if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
   1891      1.1  christos 	    symval += rel->r_addend;
   1892      1.1  christos 
   1893      1.1  christos 	  if (ssec)
   1894      1.1  christos 	    {
   1895      1.1  christos 	      if ((ssec->flags & SEC_MERGE)
   1896      1.1  christos 		  && ssec->sec_info_type == SEC_INFO_TYPE_MERGE)
   1897      1.1  christos 		symval = _bfd_merged_section_offset (abfd, & ssec,
   1898      1.1  christos 						     elf_section_data (ssec)->sec_info,
   1899      1.1  christos 						     symval);
   1900      1.1  christos 	    }
   1901      1.1  christos 
   1902      1.1  christos 	  /* Now make the offset relative to where the linker is putting it.  */
   1903      1.1  christos 	  if (ssec)
   1904      1.1  christos 	    symval +=
   1905      1.1  christos 	      ssec->output_section->vma + ssec->output_offset;
   1906      1.1  christos 
   1907      1.1  christos 	  symval += rel->r_addend;
   1908      1.1  christos 	}
   1909      1.1  christos       else
   1910      1.1  christos 	{
   1911      1.1  christos 	  unsigned long indx;
   1912      1.1  christos 	  struct elf_link_hash_entry * h;
   1913      1.1  christos 
   1914      1.1  christos 	  /* An external symbol.  */
   1915      1.1  christos 	  indx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
   1916      1.1  christos 	  h = elf_sym_hashes (abfd)[indx];
   1917      1.1  christos 	  BFD_ASSERT (h != NULL);
   1918      1.1  christos 
   1919      1.1  christos 	  if (h->root.type != bfd_link_hash_defined
   1920      1.1  christos 	      && h->root.type != bfd_link_hash_defweak)
   1921      1.1  christos 	    {
   1922      1.1  christos 	      /* This appears to be a reference to an undefined
   1923      1.1  christos 		 symbol.  Just ignore it--it will be caught by the
   1924      1.1  christos 		 regular reloc processing.  */
   1925      1.1  christos 	      if (lrel)
   1926      1.1  christos 		*lrel = rel;
   1927      1.1  christos 	      return 0;
   1928      1.1  christos 	    }
   1929      1.1  christos 
   1930      1.1  christos 	  symval = (h->root.u.def.value
   1931      1.5  christos 		    + h->root.u.def.section->output_section->vma
   1932      1.5  christos 		    + h->root.u.def.section->output_offset);
   1933      1.1  christos 
   1934      1.1  christos 	  symval += rel->r_addend;
   1935  1.9.2.1  perseant 	}
   1936  1.9.2.1  perseant 
   1937      1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   1938      1.1  christos       switch (r_type)
   1939      1.5  christos 	{
   1940      1.6  christos 	case R_RL78_SYM:
   1941  1.9.2.1  perseant 	  (void) rl78_compute_complex_reloc (r_type, symval, input_section,
   1942  1.9.2.1  perseant 					     NULL, NULL);
   1943      1.1  christos 	  break;
   1944      1.1  christos 
   1945      1.5  christos 	case R_RL78_OPromtop:
   1946      1.6  christos 	  symval = get_romstart (info, input_bfd, input_section, rel->r_offset);
   1947  1.9.2.1  perseant 	  (void) rl78_compute_complex_reloc (r_type, symval, input_section,
   1948  1.9.2.1  perseant 					     NULL, NULL);
   1949      1.1  christos 	  break;
   1950      1.1  christos 
   1951      1.5  christos 	case R_RL78_OPramtop:
   1952      1.5  christos 	  symval = get_ramstart (info, input_bfd, input_section, rel->r_offset);
   1953      1.1  christos 	  (void) rl78_compute_complex_reloc (r_type, symval, input_section,
   1954      1.1  christos 					     NULL, NULL);
   1955      1.1  christos 	  break;
   1956      1.1  christos 
   1957      1.1  christos 	case R_RL78_OPneg:
   1958      1.1  christos 	case R_RL78_OPadd:
   1959      1.1  christos 	case R_RL78_OPsub:
   1960      1.1  christos 	case R_RL78_OPmul:
   1961      1.1  christos 	case R_RL78_OPdiv:
   1962      1.1  christos 	case R_RL78_OPshla:
   1963      1.1  christos 	case R_RL78_OPshra:
   1964      1.1  christos 	case R_RL78_OPsctsize:
   1965  1.9.2.1  perseant 	case R_RL78_OPscttop:
   1966  1.9.2.1  perseant 	case R_RL78_OPand:
   1967      1.1  christos 	case R_RL78_OPor:
   1968      1.1  christos 	case R_RL78_OPxor:
   1969      1.1  christos 	case R_RL78_OPnot:
   1970      1.1  christos 	case R_RL78_OPmod:
   1971      1.1  christos 	  (void) rl78_compute_complex_reloc (r_type, 0, input_section,
   1972      1.1  christos 					     NULL, NULL);
   1973      1.1  christos 	  break;
   1974      1.5  christos 
   1975      1.1  christos 	case R_RL78_DIR16UL:
   1976      1.1  christos 	case R_RL78_DIR8UL:
   1977      1.1  christos 	case R_RL78_ABS16UL:
   1978      1.1  christos 	case R_RL78_ABS8UL:
   1979      1.1  christos 	  *scale = 4;
   1980      1.1  christos 	  goto reloc_computes_value;
   1981      1.5  christos 
   1982      1.6  christos 	case R_RL78_DIR16UW:
   1983      1.1  christos 	case R_RL78_DIR8UW:
   1984      1.5  christos 	case R_RL78_ABS16UW:
   1985  1.9.2.1  perseant 	case R_RL78_ABS8UW:
   1986  1.9.2.1  perseant 	  *scale = 2;
   1987      1.7  christos 	  goto reloc_computes_value;
   1988      1.6  christos 
   1989      1.6  christos 	default:
   1990      1.6  christos 	reloc_computes_value:
   1991      1.6  christos 	  symval = rl78_compute_complex_reloc (r_type, symval, input_section,
   1992      1.6  christos 					       NULL, NULL);
   1993      1.6  christos 	  /* Fall through.  */
   1994      1.6  christos 	case R_RL78_DIR32:
   1995      1.6  christos 	case R_RL78_DIR24S:
   1996      1.1  christos 	case R_RL78_DIR16:
   1997      1.1  christos 	case R_RL78_DIR16U:
   1998      1.1  christos 	case R_RL78_DIR16S:
   1999      1.1  christos 	case R_RL78_DIR24S_PCREL:
   2000      1.1  christos 	case R_RL78_DIR16S_PCREL:
   2001      1.1  christos 	case R_RL78_DIR8S_PCREL:
   2002      1.1  christos 	  if (lrel)
   2003      1.1  christos 	    *lrel = rel;
   2004      1.1  christos 	  return symval;
   2005  1.9.2.1  perseant 	}
   2006      1.1  christos 
   2007      1.1  christos       rel ++;
   2008      1.1  christos     }
   2009      1.1  christos }
   2010      1.1  christos 
   2011      1.1  christos const struct {
   2012      1.1  christos   int prefix;		/* or -1 for "no prefix" */
   2013      1.1  christos   int insn;		/* or -1 for "end of list" */
   2014      1.1  christos   int insn_for_saddr;	/* or -1 for "no alternative" */
   2015      1.1  christos   int insn_for_sfr;	/* or -1 for "no alternative" */
   2016      1.1  christos } relax_addr16[] = {
   2017      1.1  christos   { -1, 0x02, 0x06, -1 },	/* ADDW	AX, !addr16 */
   2018      1.1  christos   { -1, 0x22, 0x26, -1 },	/* SUBW	AX, !addr16 */
   2019      1.1  christos   { -1, 0x42, 0x46, -1 },	/* CMPW	AX, !addr16 */
   2020      1.1  christos   { -1, 0x40, 0x4a, -1 },	/* CMP	!addr16, #byte */
   2021      1.1  christos 
   2022      1.1  christos   { -1, 0x0f, 0x0b, -1 },	/* ADD	A, !addr16 */
   2023      1.1  christos   { -1, 0x1f, 0x1b, -1 },	/* ADDC	A, !addr16 */
   2024      1.1  christos   { -1, 0x2f, 0x2b, -1 },	/* SUB	A, !addr16 */
   2025      1.1  christos   { -1, 0x3f, 0x3b, -1 },	/* SUBC	A, !addr16 */
   2026      1.1  christos   { -1, 0x4f, 0x4b, -1 },	/* CMP	A, !addr16 */
   2027      1.1  christos   { -1, 0x5f, 0x5b, -1 },	/* AND	A, !addr16 */
   2028      1.1  christos   { -1, 0x6f, 0x6b, -1 },	/* OR	A, !addr16 */
   2029      1.1  christos   { -1, 0x7f, 0x7b, -1 },	/* XOR	A, !addr16 */
   2030      1.1  christos 
   2031      1.1  christos   { -1, 0x8f, 0x8d, 0x8e },	/* MOV	A, !addr16 */
   2032      1.1  christos   { -1, 0x9f, 0x9d, 0x9e },	/* MOV	!addr16, A */
   2033      1.1  christos   { -1, 0xaf, 0xad, 0xae },	/* MOVW	AX, !addr16 */
   2034      1.1  christos   { -1, 0xbf, 0xbd, 0xbe },	/* MOVW	!addr16, AX */
   2035      1.1  christos   { -1, 0xcf, 0xcd, 0xce },	/* MOVW	!addr16, #word */
   2036      1.1  christos 
   2037      1.1  christos   { -1, 0xa0, 0xa4, -1 },	/* INC	!addr16 */
   2038      1.1  christos   { -1, 0xa2, 0xa6, -1 },	/* INCW	!addr16 */
   2039      1.1  christos   { -1, 0xb0, 0xb4, -1 },	/* DEC	!addr16 */
   2040      1.1  christos   { -1, 0xb2, 0xb6, -1 },	/* DECW	!addr16 */
   2041      1.1  christos 
   2042      1.1  christos   { -1, 0xd5, 0xd4, -1 },	/* CMP0	!addr16 */
   2043      1.1  christos   { -1, 0xe5, 0xe4, -1 },	/* ONEB	!addr16 */
   2044      1.1  christos   { -1, 0xf5, 0xf4, -1 },	/* CLRB	!addr16 */
   2045      1.1  christos 
   2046      1.1  christos   { -1, 0xd9, 0xd8, -1 },	/* MOV	X, !addr16 */
   2047      1.1  christos   { -1, 0xe9, 0xe8, -1 },	/* MOV	B, !addr16 */
   2048      1.1  christos   { -1, 0xf9, 0xf8, -1 },	/* MOV	C, !addr16 */
   2049      1.1  christos   { -1, 0xdb, 0xda, -1 },	/* MOVW	BC, !addr16 */
   2050      1.1  christos   { -1, 0xeb, 0xea, -1 },	/* MOVW	DE, !addr16 */
   2051      1.1  christos   { -1, 0xfb, 0xfa, -1 },	/* MOVW	HL, !addr16 */
   2052      1.1  christos 
   2053      1.1  christos   { 0x61, 0xaa, 0xa8, -1 },	/* XCH	A, !addr16 */
   2054      1.1  christos 
   2055      1.1  christos   { 0x71, 0x00, 0x02, 0x0a },	/* SET1	!addr16.0 */
   2056      1.1  christos   { 0x71, 0x10, 0x12, 0x1a },	/* SET1	!addr16.0 */
   2057      1.1  christos   { 0x71, 0x20, 0x22, 0x2a },	/* SET1	!addr16.0 */
   2058      1.1  christos   { 0x71, 0x30, 0x32, 0x3a },	/* SET1	!addr16.0 */
   2059      1.1  christos   { 0x71, 0x40, 0x42, 0x4a },	/* SET1	!addr16.0 */
   2060      1.1  christos   { 0x71, 0x50, 0x52, 0x5a },	/* SET1	!addr16.0 */
   2061      1.1  christos   { 0x71, 0x60, 0x62, 0x6a },	/* SET1	!addr16.0 */
   2062      1.1  christos   { 0x71, 0x70, 0x72, 0x7a },	/* SET1	!addr16.0 */
   2063      1.1  christos 
   2064      1.1  christos   { 0x71, 0x08, 0x03, 0x0b },	/* CLR1	!addr16.0 */
   2065      1.1  christos   { 0x71, 0x18, 0x13, 0x1b },	/* CLR1	!addr16.0 */
   2066      1.1  christos   { 0x71, 0x28, 0x23, 0x2b },	/* CLR1	!addr16.0 */
   2067      1.1  christos   { 0x71, 0x38, 0x33, 0x3b },	/* CLR1	!addr16.0 */
   2068      1.1  christos   { 0x71, 0x48, 0x43, 0x4b },	/* CLR1	!addr16.0 */
   2069      1.1  christos   { 0x71, 0x58, 0x53, 0x5b },	/* CLR1	!addr16.0 */
   2070      1.1  christos   { 0x71, 0x68, 0x63, 0x6b },	/* CLR1	!addr16.0 */
   2071      1.1  christos   { 0x71, 0x78, 0x73, 0x7b },	/* CLR1	!addr16.0 */
   2072  1.9.2.1  perseant 
   2073  1.9.2.1  perseant   { -1, -1, -1, -1 }
   2074  1.9.2.1  perseant };
   2075  1.9.2.1  perseant 
   2076  1.9.2.1  perseant /* Relax one section.  */
   2077      1.1  christos 
   2078      1.1  christos static bool
   2079      1.1  christos rl78_elf_relax_section (bfd *abfd,
   2080      1.1  christos 			asection *sec,
   2081      1.1  christos 			struct bfd_link_info *link_info,
   2082      1.1  christos 			bool *again)
   2083      1.1  christos {
   2084      1.1  christos   Elf_Internal_Shdr * symtab_hdr;
   2085      1.1  christos   Elf_Internal_Shdr * shndx_hdr;
   2086      1.8  christos   Elf_Internal_Rela * internal_relocs;
   2087      1.8  christos   Elf_Internal_Rela * free_relocs = NULL;
   2088      1.1  christos   Elf_Internal_Rela * irel;
   2089      1.1  christos   Elf_Internal_Rela * srel;
   2090      1.9  christos   Elf_Internal_Rela * irelend;
   2091      1.1  christos   Elf_Internal_Rela * next_alignment;
   2092      1.1  christos   bfd_byte *	      contents = NULL;
   2093      1.1  christos   bfd_byte *	      free_contents = NULL;
   2094      1.1  christos   Elf_Internal_Sym *  intsyms = NULL;
   2095      1.1  christos   Elf_Internal_Sym *  free_intsyms = NULL;
   2096      1.1  christos   bfd_byte *	      shndx_buf = NULL;
   2097      1.1  christos   bfd_vma pc;
   2098      1.1  christos   bfd_vma symval ATTRIBUTE_UNUSED = 0;
   2099      1.1  christos   int pcrel ATTRIBUTE_UNUSED = 0;
   2100      1.1  christos   int code ATTRIBUTE_UNUSED = 0;
   2101      1.1  christos   int section_alignment_glue;
   2102      1.1  christos   int scale;
   2103  1.9.2.1  perseant 
   2104      1.1  christos   if (abfd == elf_hash_table (link_info)->dynobj
   2105      1.1  christos       && strcmp (sec->name, ".plt") == 0)
   2106      1.1  christos     return rl78_elf_relax_plt_section (abfd, sec, link_info, again);
   2107      1.1  christos 
   2108      1.6  christos   /* Assume nothing changes.  */
   2109      1.1  christos   *again = false;
   2110      1.1  christos 
   2111      1.1  christos   /* We don't have to do anything for a relocatable link, if
   2112  1.9.2.1  perseant      this section does not have relocs, or if this is not a
   2113      1.1  christos      code section.  */
   2114      1.6  christos   if (bfd_link_relocatable (link_info)
   2115      1.6  christos       || (sec->flags & SEC_RELOC) == 0
   2116      1.6  christos       || sec->reloc_count == 0
   2117      1.6  christos       || (sec->flags & SEC_CODE) == 0)
   2118      1.6  christos     return true;
   2119      1.1  christos 
   2120      1.1  christos   symtab_hdr = & elf_symtab_hdr (abfd);
   2121      1.1  christos   if (elf_symtab_shndx_list (abfd))
   2122      1.1  christos     shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
   2123      1.1  christos   else
   2124      1.1  christos     shndx_hdr = NULL;
   2125      1.1  christos 
   2126      1.1  christos   /* Get the section contents.  */
   2127      1.1  christos   if (elf_section_data (sec)->this_hdr.contents != NULL)
   2128      1.1  christos     contents = elf_section_data (sec)->this_hdr.contents;
   2129      1.1  christos   /* Go get them off disk.  */
   2130      1.1  christos   else
   2131      1.1  christos     {
   2132      1.1  christos       if (! bfd_malloc_and_get_section (abfd, sec, &contents))
   2133      1.1  christos 	goto error_return;
   2134      1.1  christos       elf_section_data (sec)->this_hdr.contents = contents;
   2135      1.1  christos     }
   2136      1.1  christos 
   2137      1.1  christos   /* Read this BFD's symbols.  */
   2138      1.1  christos   /* Get cached copy if it exists.  */
   2139      1.1  christos   if (symtab_hdr->contents != NULL)
   2140      1.1  christos     intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
   2141      1.6  christos   else
   2142      1.1  christos     {
   2143      1.9  christos       intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
   2144      1.1  christos       symtab_hdr->contents = (bfd_byte *) intsyms;
   2145      1.9  christos     }
   2146      1.9  christos 
   2147      1.9  christos   if (shndx_hdr && shndx_hdr->sh_size != 0)
   2148      1.9  christos     {
   2149      1.9  christos       size_t amt;
   2150      1.9  christos 
   2151      1.9  christos       if (_bfd_mul_overflow (symtab_hdr->sh_info,
   2152      1.9  christos 			     sizeof (Elf_External_Sym_Shndx), &amt))
   2153      1.9  christos 	{
   2154      1.1  christos 	  bfd_set_error (bfd_error_no_memory);
   2155      1.1  christos 	  goto error_return;
   2156      1.9  christos 	}
   2157      1.1  christos       if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0)
   2158      1.1  christos 	goto error_return;
   2159      1.1  christos       shndx_buf = _bfd_malloc_and_read (abfd, amt, amt);
   2160      1.1  christos       if (shndx_buf == NULL)
   2161      1.1  christos 	goto error_return;
   2162      1.1  christos       shndx_hdr->contents = shndx_buf;
   2163      1.1  christos     }
   2164      1.1  christos 
   2165      1.1  christos   /* Get a copy of the native relocations.  */
   2166      1.1  christos   internal_relocs = (_bfd_elf_link_read_relocs
   2167      1.1  christos 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
   2168      1.1  christos 		      link_info->keep_memory));
   2169      1.1  christos   if (internal_relocs == NULL)
   2170      1.1  christos     goto error_return;
   2171      1.1  christos   if (! link_info->keep_memory)
   2172      1.1  christos     free_relocs = internal_relocs;
   2173      1.1  christos 
   2174      1.1  christos   /* The RL_ relocs must be just before the operand relocs they go
   2175      1.1  christos      with, so we must sort them to guarantee this.  We use bubblesort
   2176      1.1  christos      instead of qsort so we can guarantee that relocs with the same
   2177      1.1  christos      address remain in the same relative order.  */
   2178      1.1  christos   reloc_bubblesort (internal_relocs, sec->reloc_count);
   2179      1.1  christos 
   2180      1.1  christos   /* Walk through them looking for relaxing opportunities.  */
   2181      1.1  christos   irelend = internal_relocs + sec->reloc_count;
   2182      1.1  christos 
   2183      1.1  christos 
   2184      1.1  christos   /* This will either be NULL or a pointer to the next alignment
   2185      1.1  christos      relocation.  */
   2186      1.1  christos   next_alignment = internal_relocs;
   2187      1.1  christos 
   2188      1.1  christos   /* We calculate worst case shrinkage caused by alignment directives.
   2189      1.1  christos      No fool-proof, but better than either ignoring the problem or
   2190      1.1  christos      doing heavy duty analysis of all the alignment markers in all
   2191      1.1  christos      input sections.  */
   2192      1.1  christos   section_alignment_glue = 0;
   2193      1.1  christos   for (irel = internal_relocs; irel < irelend; irel++)
   2194      1.1  christos       if (ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
   2195      1.1  christos 	  && irel->r_addend & RL78_RELAXA_ALIGN)
   2196      1.1  christos 	{
   2197      1.1  christos 	  int this_glue = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
   2198      1.1  christos 
   2199      1.1  christos 	  if (section_alignment_glue < this_glue)
   2200      1.1  christos 	    section_alignment_glue = this_glue;
   2201      1.1  christos 	}
   2202      1.1  christos   /* Worst case is all 0..N alignments, in order, causing 2*N-1 byte
   2203      1.1  christos      shrinkage.  */
   2204      1.1  christos   section_alignment_glue *= 2;
   2205      1.1  christos 
   2206      1.1  christos   for (irel = internal_relocs; irel < irelend; irel++)
   2207      1.1  christos     {
   2208      1.1  christos       unsigned char *insn;
   2209      1.1  christos       int nrelocs;
   2210      1.1  christos 
   2211      1.1  christos       /* The insns we care about are all marked with one of these.  */
   2212      1.1  christos       if (ELF32_R_TYPE (irel->r_info) != R_RL78_RH_RELAX)
   2213      1.1  christos 	continue;
   2214      1.1  christos 
   2215      1.1  christos       if (irel->r_addend & RL78_RELAXA_ALIGN
   2216      1.1  christos 	  || next_alignment == internal_relocs)
   2217      1.1  christos 	{
   2218      1.1  christos 	  /* When we delete bytes, we need to maintain all the alignments
   2219      1.1  christos 	     indicated.  In addition, we need to be careful about relaxing
   2220      1.1  christos 	     jumps across alignment boundaries - these displacements
   2221      1.1  christos 	     *grow* when we delete bytes.  For now, don't shrink
   2222      1.1  christos 	     displacements across an alignment boundary, just in case.
   2223      1.1  christos 	     Note that this only affects relocations to the same
   2224      1.1  christos 	     section.  */
   2225      1.1  christos 	  next_alignment += 2;
   2226      1.1  christos 	  while (next_alignment < irelend
   2227      1.1  christos 		 && (ELF32_R_TYPE (next_alignment->r_info) != R_RL78_RH_RELAX
   2228      1.1  christos 		     || !(next_alignment->r_addend & RL78_RELAXA_ELIGN)))
   2229      1.1  christos 	    next_alignment ++;
   2230      1.1  christos 	  if (next_alignment >= irelend || next_alignment->r_offset == 0)
   2231      1.1  christos 	    next_alignment = NULL;
   2232      1.1  christos 	}
   2233      1.1  christos 
   2234      1.1  christos       /* When we hit alignment markers, see if we've shrunk enough
   2235      1.1  christos 	 before them to reduce the gap without violating the alignment
   2236      1.1  christos 	 requirements.  */
   2237      1.1  christos       if (irel->r_addend & RL78_RELAXA_ALIGN)
   2238      1.1  christos 	{
   2239      1.1  christos 	  /* At this point, the next relocation *should* be the ELIGN
   2240      1.1  christos 	     end marker.  */
   2241      1.1  christos 	  Elf_Internal_Rela *erel = irel + 1;
   2242      1.1  christos 	  unsigned int alignment, nbytes;
   2243      1.1  christos 
   2244      1.1  christos 	  if (ELF32_R_TYPE (erel->r_info) != R_RL78_RH_RELAX)
   2245      1.1  christos 	    continue;
   2246      1.1  christos 	  if (!(erel->r_addend & RL78_RELAXA_ELIGN))
   2247      1.1  christos 	    continue;
   2248      1.1  christos 
   2249      1.1  christos 	  alignment = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
   2250      1.1  christos 
   2251      1.1  christos 	  if (erel->r_offset - irel->r_offset < alignment)
   2252      1.5  christos 	    continue;
   2253      1.5  christos 
   2254  1.9.2.1  perseant 	  nbytes = erel->r_offset - irel->r_offset;
   2255      1.1  christos 	  nbytes /= alignment;
   2256      1.1  christos 	  nbytes *= alignment;
   2257      1.1  christos 
   2258      1.1  christos 	  elf32_rl78_relax_delete_bytes (abfd, sec, erel->r_offset - nbytes, nbytes,
   2259      1.1  christos 					 next_alignment, erel->r_offset == sec->size);
   2260      1.1  christos 	  *again = true;
   2261      1.1  christos 
   2262      1.1  christos 	  continue;
   2263      1.1  christos 	}
   2264      1.1  christos 
   2265      1.1  christos       if (irel->r_addend & RL78_RELAXA_ELIGN)
   2266      1.1  christos 	  continue;
   2267      1.1  christos 
   2268      1.1  christos       insn = contents + irel->r_offset;
   2269      1.1  christos 
   2270      1.1  christos       nrelocs = irel->r_addend & RL78_RELAXA_RNUM;
   2271      1.1  christos 
   2272      1.8  christos       /* At this point, we have an insn that is a candidate for linker
   2273      1.8  christos 	 relaxation.  There are NRELOCS relocs following that may be
   2274      1.8  christos 	 relaxed, although each reloc may be made of more than one
   2275      1.1  christos 	 reloc entry (such as gp-rel symbols).  */
   2276      1.1  christos 
   2277      1.1  christos       /* Get the value of the symbol referred to by the reloc.  Just
   2278      1.1  christos 	 in case this is the last reloc in the list, use the RL's
   2279      1.1  christos 	 addend to choose between this reloc (no addend) or the next
   2280      1.1  christos 	 (yes addend, which means at least one following reloc).  */
   2281      1.1  christos 
   2282      1.1  christos       /* srel points to the "current" reloction for this insn -
   2283      1.1  christos 	 actually the last reloc for a given operand, which is the one
   2284      1.1  christos 	 we need to update.  We check the relaxations in the same
   2285      1.1  christos 	 order that the relocations happen, so we'll just push it
   2286      1.5  christos 	 along as we go.  */
   2287      1.5  christos       srel = irel;
   2288      1.5  christos 
   2289      1.5  christos       pc = sec->output_section->vma + sec->output_offset
   2290      1.1  christos 	+ srel->r_offset;
   2291      1.1  christos 
   2292      1.1  christos #define GET_RELOC					\
   2293      1.1  christos       BFD_ASSERT (nrelocs > 0);				\
   2294      1.5  christos       symval = OFFSET_FOR_RELOC (srel, &srel, &scale);	\
   2295      1.5  christos       pcrel = symval - pc + srel->r_addend;		\
   2296      1.8  christos       nrelocs --;
   2297      1.1  christos 
   2298      1.1  christos #define SNIPNR(offset, nbytes) \
   2299      1.1  christos 	elf32_rl78_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0);
   2300      1.1  christos 
   2301      1.1  christos #define SNIP(offset, nbytes, newtype)					\
   2302      1.1  christos 	SNIPNR (offset, nbytes);					\
   2303      1.1  christos 	srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype)
   2304      1.1  christos 
   2305      1.1  christos       /* The order of these bit tests must match the order that the
   2306      1.1  christos 	 relocs appear in.  Since we sorted those by offset, we can
   2307      1.1  christos 	 predict them.  */
   2308      1.1  christos 
   2309      1.1  christos       /*----------------------------------------------------------------------*/
   2310      1.1  christos       /* EF ad		BR $rel8	pcrel
   2311      1.1  christos 	 ED al ah	BR !abs16	abs
   2312      1.1  christos 	 EE al ah	BR $!rel16	pcrel
   2313      1.1  christos 	 EC al ah as	BR !!abs20	abs
   2314      1.1  christos 
   2315      1.1  christos 	 FD al ah	CALL !abs16	abs
   2316      1.1  christos 	 FE al ah	CALL $!rel16	pcrel
   2317      1.1  christos 	 FC al ah as	CALL !!abs20	abs
   2318      1.1  christos 
   2319      1.1  christos 	 DC ad		BC  $rel8
   2320      1.1  christos 	 DE ad		BNC $rel8
   2321      1.1  christos 	 DD ad		BZ  $rel8
   2322      1.1  christos 	 DF ad		BNZ $rel8
   2323      1.1  christos 	 61 C3 ad	BH  $rel8
   2324      1.1  christos 	 61 D3 ad	BNH $rel8
   2325      1.1  christos 	 61 C8 EF ad	SKC  ; BR $rel8
   2326      1.1  christos 	 61 D8 EF ad	SKNC ; BR $rel8
   2327      1.3  christos 	 61 E8 EF ad	SKZ  ; BR $rel8
   2328      1.1  christos 	 61 F8 EF ad	SKNZ ; BR $rel8
   2329      1.1  christos 	 61 E3 EF ad	SKH  ; BR $rel8
   2330      1.1  christos 	 61 F3 EF ad	SKNH ; BR $rel8
   2331      1.1  christos        */
   2332      1.1  christos 
   2333      1.1  christos       if ((irel->r_addend & RL78_RELAXA_MASK) == RL78_RELAXA_BRA)
   2334      1.1  christos 	{
   2335      1.1  christos 	  /* SKIP opcodes that skip non-branches will have a relax tag
   2336      1.1  christos 	     but no corresponding symbol to relax against; we just
   2337      1.1  christos 	     skip those.  */
   2338      1.1  christos 	  if (irel->r_addend & RL78_RELAXA_RNUM)
   2339      1.6  christos 	    {
   2340      1.6  christos 	      GET_RELOC;
   2341      1.6  christos 	    }
   2342      1.6  christos 
   2343      1.6  christos 	  switch (insn[0])
   2344      1.6  christos 	    {
   2345      1.6  christos 	    case 0xdc: /* BC */
   2346      1.6  christos 	    case 0xdd: /* BZ */
   2347      1.6  christos 	    case 0xde: /* BNC */
   2348      1.6  christos 	    case 0xdf: /* BNZ */
   2349      1.6  christos 	      if (insn[1] == 0x03 && insn[2] == 0xee /* BR */
   2350      1.6  christos 		  && (srel->r_offset - irel->r_offset) > 1) /* a B<c> without its own reloc */
   2351      1.6  christos 		{
   2352      1.6  christos 		  /* This is a "long" conditional as generated by gas:
   2353      1.6  christos 		     DC 03 EE ad.dr  */
   2354      1.6  christos 		  if (pcrel < 127
   2355  1.9.2.1  perseant 		      && pcrel > -127)
   2356      1.6  christos 		    {
   2357      1.6  christos 		      insn[0] ^= 0x02; /* invert conditional */
   2358      1.6  christos 		      SNIPNR (4, 1);
   2359      1.6  christos 		      SNIP (1, 2, R_RL78_DIR8S_PCREL);
   2360      1.1  christos 		      insn[1] = pcrel;
   2361      1.1  christos 		      *again = true;
   2362      1.1  christos 		    }
   2363      1.1  christos 		}
   2364      1.1  christos 	      break;
   2365      1.1  christos 
   2366      1.1  christos 	    case 0xec: /* BR !!abs20 */
   2367      1.1  christos 
   2368  1.9.2.1  perseant 	      if (pcrel < 127
   2369      1.1  christos 		  && pcrel > -127)
   2370      1.1  christos 		{
   2371      1.1  christos 		  insn[0] = 0xef;
   2372      1.1  christos 		  insn[1] = pcrel;
   2373      1.1  christos 		  SNIP (2, 2, R_RL78_DIR8S_PCREL);
   2374      1.1  christos 		  *again = true;
   2375      1.6  christos 		}
   2376  1.9.2.1  perseant 	      else if (symval < 65536)
   2377      1.1  christos 		{
   2378      1.1  christos 		  insn[0] = 0xed;
   2379      1.1  christos 		  insn[1] = symval & 0xff;
   2380      1.1  christos 		  insn[2] = symval >> 8;
   2381      1.1  christos 		  SNIP (2, 1, R_RL78_DIR16U);
   2382      1.1  christos 		  *again = true;
   2383      1.1  christos 		}
   2384      1.1  christos 	      else if (pcrel < 32767
   2385  1.9.2.1  perseant 		       && pcrel > -32767)
   2386      1.1  christos 		{
   2387      1.1  christos 		  insn[0] = 0xee;
   2388      1.1  christos 		  insn[1] = pcrel & 0xff;
   2389      1.1  christos 		  insn[2] = pcrel >> 8;
   2390      1.1  christos 		  SNIP (2, 1, R_RL78_DIR16S_PCREL);
   2391      1.1  christos 		  *again = true;
   2392      1.1  christos 		}
   2393      1.1  christos 	      break;
   2394      1.1  christos 
   2395      1.1  christos 	    case 0xee: /* BR $!pcrel16 */
   2396      1.1  christos 	    case 0xed: /* BR $!abs16 */
   2397  1.9.2.1  perseant 	      if (pcrel < 127
   2398      1.1  christos 		  && pcrel > -127)
   2399      1.1  christos 		{
   2400      1.1  christos 		  insn[0] = 0xef;
   2401      1.1  christos 		  insn[1] = pcrel;
   2402      1.1  christos 		  SNIP (2, 1, R_RL78_DIR8S_PCREL);
   2403      1.1  christos 		  *again = true;
   2404      1.1  christos 		}
   2405      1.1  christos 	      break;
   2406      1.1  christos 
   2407      1.6  christos 	    case 0xfc: /* CALL !!abs20 */
   2408  1.9.2.1  perseant 	      if (symval < 65536)
   2409      1.1  christos 		{
   2410      1.1  christos 		  insn[0] = 0xfd;
   2411      1.1  christos 		  insn[1] = symval & 0xff;
   2412      1.1  christos 		  insn[2] = symval >> 8;
   2413      1.1  christos 		  SNIP (2, 1, R_RL78_DIR16U);
   2414      1.1  christos 		  *again = true;
   2415      1.1  christos 		}
   2416      1.1  christos 	      else if (pcrel < 32767
   2417  1.9.2.1  perseant 		       && pcrel > -32767)
   2418      1.1  christos 		{
   2419      1.1  christos 		  insn[0] = 0xfe;
   2420      1.1  christos 		  insn[1] = pcrel & 0xff;
   2421      1.1  christos 		  insn[2] = pcrel >> 8;
   2422      1.1  christos 		  SNIP (2, 1, R_RL78_DIR16S_PCREL);
   2423      1.1  christos 		  *again = true;
   2424      1.1  christos 		}
   2425      1.1  christos 	      break;
   2426      1.1  christos 
   2427      1.1  christos 	    case 0x61: /* PREFIX */
   2428      1.1  christos 	      /* For SKIP/BR, we change the BR opcode and delete the
   2429      1.1  christos 		 SKIP.  That way, we don't have to find and change the
   2430      1.6  christos 		 relocation for the BR.  */
   2431      1.6  christos 	      /* Note that, for the case where we're skipping some
   2432      1.6  christos 		 other insn, we have no "other" reloc but that's safe
   2433      1.6  christos 		 here anyway. */
   2434      1.6  christos 	      switch (insn[1])
   2435      1.6  christos 		{
   2436      1.6  christos 		case 0xd3: /* BNH */
   2437      1.6  christos 		case 0xc3: /* BH */
   2438      1.6  christos 		  if (insn[2] == 0x03 && insn[3] == 0xee
   2439      1.6  christos 		      && (srel->r_offset - irel->r_offset) > 2) /* a B<c> without its own reloc */
   2440      1.6  christos 		    {
   2441      1.6  christos 		      /* Another long branch by gas:
   2442      1.6  christos 			 61 D3 03 EE ad.dr  */
   2443      1.6  christos 		      if (pcrel < 127
   2444  1.9.2.1  perseant 			  && pcrel > -127)
   2445      1.6  christos 			{
   2446      1.6  christos 			  insn[1] ^= 0x10; /* invert conditional */
   2447      1.6  christos 			  SNIPNR (5, 1);
   2448      1.6  christos 			  SNIP (2, 2, R_RL78_DIR8S_PCREL);
   2449      1.1  christos 			  insn[2] = pcrel;
   2450      1.1  christos 			  *again = true;
   2451      1.1  christos 			}
   2452      1.1  christos 		    }
   2453      1.1  christos 		  break;
   2454      1.1  christos 
   2455      1.1  christos 		case 0xc8: /* SKC */
   2456      1.1  christos 		  if (insn[2] == 0xef)
   2457      1.1  christos 		    {
   2458      1.1  christos 		      insn[2] = 0xde; /* BNC */
   2459      1.1  christos 		      SNIPNR (0, 2);
   2460      1.1  christos 		    }
   2461      1.1  christos 		  break;
   2462      1.1  christos 
   2463      1.1  christos 		case 0xd8: /* SKNC */
   2464      1.1  christos 		  if (insn[2] == 0xef)
   2465      1.1  christos 		    {
   2466      1.1  christos 		      insn[2] = 0xdc; /* BC */
   2467      1.1  christos 		      SNIPNR (0, 2);
   2468      1.1  christos 		    }
   2469      1.1  christos 		  break;
   2470      1.1  christos 
   2471      1.1  christos 		case 0xe8: /* SKZ */
   2472      1.1  christos 		  if (insn[2] == 0xef)
   2473      1.1  christos 		    {
   2474      1.1  christos 		      insn[2] = 0xdf; /* BNZ */
   2475      1.1  christos 		      SNIPNR (0, 2);
   2476      1.1  christos 		    }
   2477      1.1  christos 		  break;
   2478      1.1  christos 
   2479      1.1  christos 		case 0xf8: /* SKNZ */
   2480      1.1  christos 		  if (insn[2] == 0xef)
   2481      1.1  christos 		    {
   2482      1.1  christos 		      insn[2] = 0xdd; /* BZ */
   2483      1.1  christos 		      SNIPNR (0, 2);
   2484      1.1  christos 		    }
   2485      1.1  christos 		  break;
   2486      1.1  christos 
   2487      1.1  christos 		case 0xe3: /* SKH */
   2488      1.1  christos 		  if (insn[2] == 0xef)
   2489      1.1  christos 		    {
   2490      1.1  christos 		      insn[2] = 0xd3; /* BNH */
   2491      1.1  christos 		      SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
   2492      1.1  christos 		    }
   2493      1.1  christos 		  break;
   2494      1.1  christos 
   2495      1.1  christos 		case 0xf3: /* SKNH */
   2496      1.1  christos 		  if (insn[2] == 0xef)
   2497      1.1  christos 		    {
   2498      1.1  christos 		      insn[2] = 0xc3; /* BH */
   2499      1.1  christos 		      SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
   2500      1.1  christos 		    }
   2501      1.5  christos 		  break;
   2502      1.8  christos 		}
   2503      1.1  christos 	      break;
   2504      1.1  christos 	    }
   2505      1.1  christos 	}
   2506      1.1  christos 
   2507      1.1  christos       if ((irel->r_addend &  RL78_RELAXA_MASK) == RL78_RELAXA_ADDR16
   2508      1.1  christos 	  && nrelocs > 0)
   2509      1.1  christos 	{
   2510      1.8  christos 	  /*----------------------------------------------------------------------*/
   2511      1.1  christos 	  /* Some insns have both a 16-bit address operand and an 8-bit
   2512      1.1  christos 	     variant if the address is within a special range:
   2513      1.1  christos 
   2514      1.1  christos 	     Address		16-bit operand	SADDR range	SFR range
   2515      1.1  christos 	     FFF00-FFFFF	0xff00-0xffff	0x00-0xff
   2516      1.1  christos 	     FFE20-FFF1F	0xfe20-0xff1f			0x00-0xff
   2517      1.1  christos 
   2518      1.1  christos 	     The RELAX_ADDR16[] array has the insn encodings for the
   2519      1.1  christos 	     16-bit operand version, as well as the SFR and SADDR
   2520      1.1  christos 	     variants.  We only need to replace the encodings and
   2521      1.1  christos 	     adjust the operand.
   2522      1.1  christos 
   2523      1.1  christos 	     Note: we intentionally do not attempt to decode and skip
   2524      1.1  christos 	     any ES: prefix, as adding ES: means the addr16 (likely)
   2525      1.1  christos 	     no longer points to saddr/sfr space.
   2526      1.1  christos 	  */
   2527      1.1  christos 
   2528      1.1  christos 	  int is_sfr;
   2529      1.1  christos 	  int is_saddr;
   2530      1.1  christos 	  int idx;
   2531      1.1  christos 	  int poff;
   2532      1.1  christos 
   2533      1.1  christos 	  GET_RELOC;
   2534      1.1  christos 
   2535      1.1  christos 	  if (0xffe20 <= symval && symval <= 0xfffff)
   2536      1.1  christos 	    {
   2537      1.1  christos 
   2538      1.1  christos 	      is_saddr = (0xffe20 <= symval && symval <= 0xfff1f);
   2539      1.1  christos 	      is_sfr   = (0xfff00 <= symval && symval <= 0xfffff);
   2540      1.1  christos 
   2541      1.1  christos 	      for (idx = 0; relax_addr16[idx].insn != -1; idx ++)
   2542      1.1  christos 		{
   2543      1.1  christos 		  if (relax_addr16[idx].prefix != -1
   2544      1.1  christos 		      && insn[0] == relax_addr16[idx].prefix
   2545      1.1  christos 		      && insn[1] == relax_addr16[idx].insn)
   2546      1.1  christos 		    {
   2547      1.1  christos 		      poff = 1;
   2548      1.1  christos 		    }
   2549      1.1  christos 		  else if (relax_addr16[idx].prefix == -1
   2550      1.1  christos 			   && insn[0] == relax_addr16[idx].insn)
   2551      1.1  christos 		    {
   2552      1.1  christos 		      poff = 0;
   2553      1.1  christos 		    }
   2554      1.1  christos 		  else
   2555      1.1  christos 		    continue;
   2556      1.1  christos 
   2557      1.1  christos 		  /* We have a matched insn, and poff is 0 or 1 depending
   2558      1.1  christos 		     on the base pattern size.  */
   2559      1.1  christos 
   2560      1.1  christos 		  if (is_sfr && relax_addr16[idx].insn_for_sfr != -1)
   2561      1.1  christos 		    {
   2562      1.1  christos 		      insn[poff] = relax_addr16[idx].insn_for_sfr;
   2563      1.1  christos 		      SNIP (poff+2, 1, R_RL78_RH_SFR);
   2564      1.1  christos 		    }
   2565      1.1  christos 
   2566      1.1  christos 		  else if  (is_saddr && relax_addr16[idx].insn_for_saddr != -1)
   2567      1.1  christos 		    {
   2568      1.1  christos 		      insn[poff] = relax_addr16[idx].insn_for_saddr;
   2569      1.1  christos 		      SNIP (poff+2, 1, R_RL78_RH_SADDR);
   2570      1.1  christos 		    }
   2571  1.9.2.1  perseant 		}
   2572      1.1  christos 	    }
   2573      1.1  christos 	}
   2574      1.9  christos       /*----------------------------------------------------------------------*/
   2575      1.9  christos     }
   2576      1.1  christos 
   2577      1.1  christos   return true;
   2578      1.1  christos 
   2579      1.1  christos  error_return:
   2580      1.1  christos   free (free_relocs);
   2581      1.1  christos   free (free_contents);
   2582      1.1  christos 
   2583      1.9  christos   if (shndx_buf != NULL)
   2584      1.1  christos     {
   2585  1.9.2.1  perseant       shndx_hdr->contents = NULL;
   2586      1.1  christos       free (shndx_buf);
   2587      1.1  christos     }
   2588      1.1  christos 
   2589      1.1  christos   free (free_intsyms);
   2590      1.1  christos 
   2591      1.1  christos   return true;
   2592      1.1  christos }
   2593      1.1  christos 
   2594      1.3  christos 
   2595      1.1  christos 
   2597      1.1  christos #define ELF_ARCH		bfd_arch_rl78
   2598      1.1  christos #define ELF_MACHINE_CODE	EM_RL78
   2599      1.1  christos #define ELF_MAXPAGESIZE		0x1000
   2600      1.1  christos 
   2601      1.8  christos #define TARGET_LITTLE_SYM	rl78_elf32_vec
   2602      1.1  christos #define TARGET_LITTLE_NAME	"elf32-rl78"
   2603      1.1  christos 
   2604      1.1  christos #define elf_info_to_howto_rel			NULL
   2605      1.1  christos #define elf_info_to_howto			rl78_info_to_howto_rela
   2606      1.1  christos #define elf_backend_object_p			rl78_elf_object_p
   2607      1.1  christos #define elf_backend_relocate_section		rl78_elf_relocate_section
   2608      1.1  christos #define elf_symbol_leading_char			('_')
   2609      1.1  christos #define elf_backend_can_gc_sections		1
   2610      1.1  christos 
   2611      1.8  christos #define bfd_elf32_bfd_reloc_type_lookup		rl78_reloc_type_lookup
   2612      1.1  christos #define bfd_elf32_bfd_reloc_name_lookup		rl78_reloc_name_lookup
   2613      1.1  christos #define bfd_elf32_bfd_set_private_flags		rl78_elf_set_private_flags
   2614      1.1  christos #define bfd_elf32_bfd_merge_private_bfd_data	rl78_elf_merge_private_bfd_data
   2615      1.1  christos #define bfd_elf32_bfd_print_private_bfd_data	rl78_elf_print_private_bfd_data
   2616      1.1  christos 
   2617      1.1  christos #define bfd_elf32_bfd_relax_section		rl78_elf_relax_section
   2618                    #define elf_backend_check_relocs		rl78_elf_check_relocs
   2619                    #define elf_backend_always_size_sections \
   2620                      rl78_elf_always_size_sections
   2621                    #define elf_backend_finish_dynamic_sections \
   2622                      rl78_elf_finish_dynamic_sections
   2623                    
   2624                    #include "elf32-target.h"
   2625