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