OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-rl78.c] - Blame information for rev 163

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 163 khays
/* Renesas RL78 specific support for 32-bit ELF.
2
   Copyright (C) 2011
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "bfd_stdint.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/rl78.h"
27
#include "libiberty.h"
28
 
29
#define valid_16bit_address(v) ((v) <= 0x0ffff || (v) >= 0xf0000)
30
 
31
#define RL78REL(n,sz,bit,shift,complain,pcrel)                               \
32
  HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
33
         bfd_elf_generic_reloc, "R_RL78_" #n, FALSE, 0, ~0, FALSE)
34
 
35
/* Note that the relocations around 0x7f are internal to this file;
36
   feel free to move them as needed to avoid conflicts with published
37
   relocation numbers.  */
38
 
39
static reloc_howto_type rl78_elf_howto_table [] =
40
{
41
  RL78REL (NONE,         0,  0, 0, dont,     FALSE),
42
  RL78REL (DIR32,        2, 32, 0, signed,   FALSE),
43
  RL78REL (DIR24S,       2, 24, 0, signed,   FALSE),
44
  RL78REL (DIR16,        1, 16, 0, dont,     FALSE),
45
  RL78REL (DIR16U,       1, 16, 0, unsigned, FALSE),
46
  RL78REL (DIR16S,       1, 16, 0, signed,   FALSE),
47
  RL78REL (DIR8,         0,  8, 0, dont,     FALSE),
48
  RL78REL (DIR8U,        0,  8, 0, unsigned, FALSE),
49
  RL78REL (DIR8S,        0,  8, 0, signed,   FALSE),
50
  RL78REL (DIR24S_PCREL, 2, 24, 0, signed,   TRUE),
51
  RL78REL (DIR16S_PCREL, 1, 16, 0, signed,   TRUE),
52
  RL78REL (DIR8S_PCREL,  0,  8, 0, signed,   TRUE),
53
  RL78REL (DIR16UL,      1, 16, 2, unsigned, FALSE),
54
  RL78REL (DIR16UW,      1, 16, 1, unsigned, FALSE),
55
  RL78REL (DIR8UL,       0,  8, 2, unsigned, FALSE),
56
  RL78REL (DIR8UW,       0,  8, 1, unsigned, FALSE),
57
  RL78REL (DIR32_REV,    1, 16, 0, dont,     FALSE),
58
  RL78REL (DIR16_REV,    1, 16, 0, dont,     FALSE),
59
  RL78REL (DIR3U_PCREL,  0,  3, 0, dont,     TRUE),
60
 
61
  EMPTY_HOWTO (0x13),
62
  EMPTY_HOWTO (0x14),
63
  EMPTY_HOWTO (0x15),
64
  EMPTY_HOWTO (0x16),
65
  EMPTY_HOWTO (0x17),
66
  EMPTY_HOWTO (0x18),
67
  EMPTY_HOWTO (0x19),
68
  EMPTY_HOWTO (0x1a),
69
  EMPTY_HOWTO (0x1b),
70
  EMPTY_HOWTO (0x1c),
71
  EMPTY_HOWTO (0x1d),
72
  EMPTY_HOWTO (0x1e),
73
  EMPTY_HOWTO (0x1f),
74
 
75
  EMPTY_HOWTO (0x20),
76
  EMPTY_HOWTO (0x21),
77
  EMPTY_HOWTO (0x22),
78
  EMPTY_HOWTO (0x23),
79
  EMPTY_HOWTO (0x24),
80
  EMPTY_HOWTO (0x25),
81
  EMPTY_HOWTO (0x26),
82
  EMPTY_HOWTO (0x27),
83
  EMPTY_HOWTO (0x28),
84
  EMPTY_HOWTO (0x29),
85
  EMPTY_HOWTO (0x2a),
86
  EMPTY_HOWTO (0x2b),
87
  EMPTY_HOWTO (0x2c),
88
  EMPTY_HOWTO (0x2d),
89
 
90
  EMPTY_HOWTO (0x2e),
91
  EMPTY_HOWTO (0x2f),
92
  EMPTY_HOWTO (0x30),
93
  EMPTY_HOWTO (0x31),
94
  EMPTY_HOWTO (0x32),
95
  EMPTY_HOWTO (0x33),
96
  EMPTY_HOWTO (0x34),
97
  EMPTY_HOWTO (0x35),
98
  EMPTY_HOWTO (0x36),
99
  EMPTY_HOWTO (0x37),
100
  EMPTY_HOWTO (0x38),
101
  EMPTY_HOWTO (0x39),
102
  EMPTY_HOWTO (0x3a),
103
  EMPTY_HOWTO (0x3b),
104
  EMPTY_HOWTO (0x3c),
105
  EMPTY_HOWTO (0x3d),
106
  EMPTY_HOWTO (0x3e),
107
  EMPTY_HOWTO (0x3f),
108
  EMPTY_HOWTO (0x40),
109
 
110
  RL78REL (ABS32,        2, 32, 0, dont,     FALSE),
111
  RL78REL (ABS24S,       2, 24, 0, signed,   FALSE),
112
  RL78REL (ABS16,        1, 16, 0, dont,     FALSE),
113
  RL78REL (ABS16U,       1, 16, 0, unsigned, FALSE),
114
  RL78REL (ABS16S,       1, 16, 0, signed,   FALSE),
115
  RL78REL (ABS8,         0,  8, 0, dont,     FALSE),
116
  RL78REL (ABS8U,        0,  8, 0, unsigned, FALSE),
117
  RL78REL (ABS8S,        0,  8, 0, signed,   FALSE),
118
  RL78REL (ABS24S_PCREL, 2, 24, 0, signed,   TRUE),
119
  RL78REL (ABS16S_PCREL, 1, 16, 0, signed,   TRUE),
120
  RL78REL (ABS8S_PCREL,  0,  8, 0, signed,   TRUE),
121
  RL78REL (ABS16UL,      1, 16, 0, unsigned, FALSE),
122
  RL78REL (ABS16UW,      1, 16, 0, unsigned, FALSE),
123
  RL78REL (ABS8UL,       0,  8, 0, unsigned, FALSE),
124
  RL78REL (ABS8UW,       0,  8, 0, unsigned, FALSE),
125
  RL78REL (ABS32_REV,    2, 32, 0, dont,     FALSE),
126
  RL78REL (ABS16_REV,    1, 16, 0, dont,     FALSE),
127
 
128
#define STACK_REL_P(x) ((x) <= R_RL78_ABS16_REV && (x) >= R_RL78_ABS32)
129
 
130
  EMPTY_HOWTO (0x52),
131
  EMPTY_HOWTO (0x53),
132
  EMPTY_HOWTO (0x54),
133
  EMPTY_HOWTO (0x55),
134
  EMPTY_HOWTO (0x56),
135
  EMPTY_HOWTO (0x57),
136
  EMPTY_HOWTO (0x58),
137
  EMPTY_HOWTO (0x59),
138
  EMPTY_HOWTO (0x5a),
139
  EMPTY_HOWTO (0x5b),
140
  EMPTY_HOWTO (0x5c),
141
  EMPTY_HOWTO (0x5d),
142
  EMPTY_HOWTO (0x5e),
143
  EMPTY_HOWTO (0x5f),
144
  EMPTY_HOWTO (0x60),
145
  EMPTY_HOWTO (0x61),
146
  EMPTY_HOWTO (0x62),
147
  EMPTY_HOWTO (0x63),
148
  EMPTY_HOWTO (0x64),
149
  EMPTY_HOWTO (0x65),
150
  EMPTY_HOWTO (0x66),
151
  EMPTY_HOWTO (0x67),
152
  EMPTY_HOWTO (0x68),
153
  EMPTY_HOWTO (0x69),
154
  EMPTY_HOWTO (0x6a),
155
  EMPTY_HOWTO (0x6b),
156
  EMPTY_HOWTO (0x6c),
157
  EMPTY_HOWTO (0x6d),
158
  EMPTY_HOWTO (0x6e),
159
  EMPTY_HOWTO (0x6f),
160
  EMPTY_HOWTO (0x70),
161
  EMPTY_HOWTO (0x71),
162
  EMPTY_HOWTO (0x72),
163
  EMPTY_HOWTO (0x73),
164
  EMPTY_HOWTO (0x74),
165
  EMPTY_HOWTO (0x75),
166
  EMPTY_HOWTO (0x76),
167
  EMPTY_HOWTO (0x77),
168
 
169
  EMPTY_HOWTO (0x78),
170
  EMPTY_HOWTO (0x79),
171
  EMPTY_HOWTO (0x7a),
172
  EMPTY_HOWTO (0x7b),
173
  EMPTY_HOWTO (0x7c),
174
  EMPTY_HOWTO (0x7d),
175
  EMPTY_HOWTO (0x7e),
176
  EMPTY_HOWTO (0x7f),
177
 
178
  RL78REL (SYM,       2, 32, 0, dont, FALSE),
179
  RL78REL (OPneg,     2, 32, 0, dont, FALSE),
180
  RL78REL (OPadd,     2, 32, 0, dont, FALSE),
181
  RL78REL (OPsub,     2, 32, 0, dont, FALSE),
182
  RL78REL (OPmul,     2, 32, 0, dont, FALSE),
183
  RL78REL (OPdiv,     2, 32, 0, dont, FALSE),
184
  RL78REL (OPshla,    2, 32, 0, dont, FALSE),
185
  RL78REL (OPshra,    2, 32, 0, dont, FALSE),
186
  RL78REL (OPsctsize, 2, 32, 0, dont, FALSE),
187
  EMPTY_HOWTO (0x89),
188
  EMPTY_HOWTO (0x8a),
189
  EMPTY_HOWTO (0x8b),
190
  EMPTY_HOWTO (0x8c),
191
  RL78REL (OPscttop,  2, 32, 0, dont, FALSE),
192
  EMPTY_HOWTO (0x8e),
193
  EMPTY_HOWTO (0x8f),
194
  RL78REL (OPand,     2, 32, 0, dont, FALSE),
195
  RL78REL (OPor,      2, 32, 0, dont, FALSE),
196
  RL78REL (OPxor,     2, 32, 0, dont, FALSE),
197
  RL78REL (OPnot,     2, 32, 0, dont, FALSE),
198
  RL78REL (OPmod,     2, 32, 0, dont, FALSE),
199
  RL78REL (OPromtop,  2, 32, 0, dont, FALSE),
200
  RL78REL (OPramtop,  2, 32, 0, dont, FALSE)
201
};
202
 
203
/* Map BFD reloc types to RL78 ELF reloc types.  */
204
 
205
struct rl78_reloc_map
206
{
207
  bfd_reloc_code_real_type  bfd_reloc_val;
208
  unsigned int              rl78_reloc_val;
209
};
210
 
211
static const struct rl78_reloc_map rl78_reloc_map [] =
212
{
213
  { BFD_RELOC_NONE,             R_RL78_NONE },
214
  { BFD_RELOC_8,                R_RL78_DIR8S },
215
  { BFD_RELOC_16,               R_RL78_DIR16S },
216
  { BFD_RELOC_24,               R_RL78_DIR24S },
217
  { BFD_RELOC_32,               R_RL78_DIR32 },
218
  { BFD_RELOC_RL78_16_OP,       R_RL78_DIR16 },
219
  { BFD_RELOC_RL78_DIR3U_PCREL, R_RL78_DIR3U_PCREL },
220
  { BFD_RELOC_8_PCREL,          R_RL78_DIR8S_PCREL },
221
  { BFD_RELOC_16_PCREL,         R_RL78_DIR16S_PCREL },
222
  { BFD_RELOC_24_PCREL,         R_RL78_DIR24S_PCREL },
223
  { BFD_RELOC_RL78_8U,          R_RL78_DIR8U },
224
  { BFD_RELOC_RL78_16U,         R_RL78_DIR16U },
225
  { BFD_RELOC_RL78_SYM,         R_RL78_SYM },
226
  { BFD_RELOC_RL78_OP_SUBTRACT, R_RL78_OPsub },
227
  { BFD_RELOC_RL78_OP_NEG,      R_RL78_OPneg },
228
  { BFD_RELOC_RL78_OP_AND,      R_RL78_OPand },
229
  { BFD_RELOC_RL78_OP_SHRA,     R_RL78_OPshra },
230
  { BFD_RELOC_RL78_ABS8,        R_RL78_ABS8 },
231
  { BFD_RELOC_RL78_ABS16,       R_RL78_ABS16 },
232
  { BFD_RELOC_RL78_ABS16_REV,   R_RL78_ABS16_REV },
233
  { BFD_RELOC_RL78_ABS32,       R_RL78_ABS32 },
234
  { BFD_RELOC_RL78_ABS32_REV,   R_RL78_ABS32_REV },
235
  { BFD_RELOC_RL78_ABS16UL,     R_RL78_ABS16UL },
236
  { BFD_RELOC_RL78_ABS16UW,     R_RL78_ABS16UW },
237
  { BFD_RELOC_RL78_ABS16U,      R_RL78_ABS16U }
238
};
239
 
240
static reloc_howto_type *
241
rl78_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
242
                        bfd_reloc_code_real_type code)
243
{
244
  unsigned int i;
245
 
246
  if (code == BFD_RELOC_RL78_32_OP)
247
    return rl78_elf_howto_table + R_RL78_DIR32;
248
 
249
  for (i = ARRAY_SIZE (rl78_reloc_map); --i;)
250
    if (rl78_reloc_map [i].bfd_reloc_val == code)
251
      return rl78_elf_howto_table + rl78_reloc_map[i].rl78_reloc_val;
252
 
253
  return NULL;
254
}
255
 
256
static reloc_howto_type *
257
rl78_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name)
258
{
259
  unsigned int i;
260
 
261
  for (i = 0; i < ARRAY_SIZE (rl78_elf_howto_table); i++)
262
    if (rl78_elf_howto_table[i].name != NULL
263
        && strcasecmp (rl78_elf_howto_table[i].name, r_name) == 0)
264
      return rl78_elf_howto_table + i;
265
 
266
  return NULL;
267
}
268
 
269
/* Set the howto pointer for an RL78 ELF reloc.  */
270
 
271
static void
272
rl78_info_to_howto_rela (bfd *               abfd ATTRIBUTE_UNUSED,
273
                         arelent *           cache_ptr,
274
                         Elf_Internal_Rela * dst)
275
{
276
  unsigned int r_type;
277
 
278
  r_type = ELF32_R_TYPE (dst->r_info);
279
  BFD_ASSERT (r_type < (unsigned int) R_RL78_max);
280
  cache_ptr->howto = rl78_elf_howto_table + r_type;
281
}
282
 
283
static bfd_vma
284
get_symbol_value (const char *            name,
285
                  bfd_reloc_status_type * status,
286
                  struct bfd_link_info *  info,
287
                  bfd *                   input_bfd,
288
                  asection *              input_section,
289
                  int                     offset)
290
{
291
  bfd_vma value = 0;
292
  struct bfd_link_hash_entry * h;
293
 
294
  h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
295
 
296
  if (h == NULL
297
      || (h->type != bfd_link_hash_defined
298
          && h->type != bfd_link_hash_defweak))
299
    * status = info->callbacks->undefined_symbol
300
      (info, name, input_bfd, input_section, offset, TRUE);
301
  else
302
    value = (h->u.def.value
303
             + h->u.def.section->output_section->vma
304
             + h->u.def.section->output_offset);
305
 
306
  return value;
307
}
308
 
309
static bfd_vma
310
get_romstart (bfd_reloc_status_type * status,
311
              struct bfd_link_info *  info,
312
              bfd *                   abfd,
313
              asection *              sec,
314
              int                     offset)
315
{
316
  static bfd_boolean cached = FALSE;
317
  static bfd_vma     cached_value = 0;
318
 
319
  if (!cached)
320
    {
321
      cached_value = get_symbol_value ("_start", status, info, abfd, sec, offset);
322
      cached = TRUE;
323
    }
324
  return cached_value;
325
}
326
 
327
static bfd_vma
328
get_ramstart (bfd_reloc_status_type * status,
329
              struct bfd_link_info *  info,
330
              bfd *                   abfd,
331
              asection *              sec,
332
              int                     offset)
333
{
334
  static bfd_boolean cached = FALSE;
335
  static bfd_vma     cached_value = 0;
336
 
337
  if (!cached)
338
    {
339
      cached_value = get_symbol_value ("__datastart", status, info, abfd, sec, offset);
340
      cached = TRUE;
341
    }
342
  return cached_value;
343
}
344
 
345
#define NUM_STACK_ENTRIES 16
346
static int32_t rl78_stack [ NUM_STACK_ENTRIES ];
347
static unsigned int rl78_stack_top;
348
 
349
#define RL78_STACK_PUSH(val)                    \
350
  do                                            \
351
    {                                           \
352
      if (rl78_stack_top < NUM_STACK_ENTRIES)   \
353
        rl78_stack [rl78_stack_top ++] = (val); \
354
      else                                      \
355
        r = bfd_reloc_dangerous;                \
356
    }                                           \
357
  while (0)
358
 
359
#define RL78_STACK_POP(dest)                    \
360
  do                                            \
361
    {                                           \
362
      if (rl78_stack_top > 0)                    \
363
        (dest) = rl78_stack [-- rl78_stack_top];        \
364
      else                                      \
365
        (dest) = 0, r = bfd_reloc_dangerous;     \
366
    }                                           \
367
  while (0)
368
 
369
/* Relocate an RL78 ELF section.
370
   There is some attempt to make this function usable for many architectures,
371
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
372
   if only to serve as a learning tool.
373
 
374
   The RELOCATE_SECTION function is called by the new ELF backend linker
375
   to handle the relocations for a section.
376
 
377
   The relocs are always passed as Rela structures; if the section
378
   actually uses Rel structures, the r_addend field will always be
379
   zero.
380
 
381
   This function is responsible for adjusting the section contents as
382
   necessary, and (if using Rela relocs and generating a relocatable
383
   output file) adjusting the reloc addend as necessary.
384
 
385
   This function does not have to worry about setting the reloc
386
   address or the reloc symbol index.
387
 
388
   LOCAL_SYMS is a pointer to the swapped in local symbols.
389
 
390
   LOCAL_SECTIONS is an array giving the section in the input file
391
   corresponding to the st_shndx field of each local symbol.
392
 
393
   The global hash table entry for the global symbols can be found
394
   via elf_sym_hashes (input_bfd).
395
 
396
   When generating relocatable output, this function must handle
397
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
398
   going to be the section symbol corresponding to the output
399
   section, which means that the addend must be adjusted
400
   accordingly.  */
401
 
402
static bfd_boolean
403
rl78_elf_relocate_section
404
    (bfd *                   output_bfd,
405
     struct bfd_link_info *  info,
406
     bfd *                   input_bfd,
407
     asection *              input_section,
408
     bfd_byte *              contents,
409
     Elf_Internal_Rela *     relocs,
410
     Elf_Internal_Sym *      local_syms,
411
     asection **             local_sections)
412
{
413
  Elf_Internal_Shdr *           symtab_hdr;
414
  struct elf_link_hash_entry ** sym_hashes;
415
  Elf_Internal_Rela *           rel;
416
  Elf_Internal_Rela *           relend;
417
  bfd *dynobj;
418
  asection *splt;
419
 
420
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
421
  sym_hashes = elf_sym_hashes (input_bfd);
422
  relend     = relocs + input_section->reloc_count;
423
 
424
  dynobj = elf_hash_table (info)->dynobj;
425
  splt = NULL;
426
  if (dynobj != NULL)
427
    splt = bfd_get_section_by_name (dynobj, ".plt");
428
 
429
  for (rel = relocs; rel < relend; rel ++)
430
    {
431
      reloc_howto_type *           howto;
432
      unsigned long                r_symndx;
433
      Elf_Internal_Sym *           sym;
434
      asection *                   sec;
435
      struct elf_link_hash_entry * h;
436
      bfd_vma                      relocation;
437
      bfd_reloc_status_type        r;
438
      const char *                 name = NULL;
439
      bfd_boolean                  unresolved_reloc = TRUE;
440
      int                          r_type;
441
 
442
      r_type = ELF32_R_TYPE (rel->r_info);
443
      r_symndx = ELF32_R_SYM (rel->r_info);
444
 
445
      howto  = rl78_elf_howto_table + ELF32_R_TYPE (rel->r_info);
446
      h      = NULL;
447
      sym    = NULL;
448
      sec    = NULL;
449
      relocation = 0;
450
 
451
      if (r_symndx < symtab_hdr->sh_info)
452
        {
453
          sym = local_syms + r_symndx;
454
          sec = local_sections [r_symndx];
455
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
456
 
457
          name = bfd_elf_string_from_elf_section
458
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
459
          name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
460
        }
461
      else
462
        {
463
          bfd_boolean warned;
464
 
465
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
466
                                   r_symndx, symtab_hdr, sym_hashes, h,
467
                                   sec, relocation, unresolved_reloc,
468
                                   warned);
469
 
470
          name = h->root.root.string;
471
        }
472
 
473
      if (sec != NULL && elf_discarded_section (sec))
474
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
475
                                         rel, relend, howto, contents);
476
 
477
      if (info->relocatable)
478
        {
479
          /* This is a relocatable link.  We don't have to change
480
             anything, unless the reloc is against a section symbol,
481
             in which case we have to adjust according to where the
482
             section symbol winds up in the output section.  */
483
          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
484
            rel->r_addend += sec->output_offset;
485
          continue;
486
        }
487
 
488
      switch (ELF32_R_TYPE (rel->r_info))
489
        {
490
        case R_RL78_DIR16S:
491
          {
492
            bfd_vma *plt_offset;
493
 
494
            if (h != NULL)
495
              plt_offset = &h->plt.offset;
496
            else
497
              plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
498
 
499
            /*      printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
500
                    relocation, *plt_offset);*/
501
            if (valid_16bit_address (relocation))
502
              {
503
                /* If the symbol is in range for a 16-bit address, we should
504
                   have deallocated the plt entry in relax_section.  */
505
                BFD_ASSERT (*plt_offset == (bfd_vma) -1);
506
              }
507
            else
508
              {
509
                /* If the symbol is out of range for a 16-bit address,
510
                   we must have allocated a plt entry.  */
511
                BFD_ASSERT (*plt_offset != (bfd_vma) -1);
512
 
513
                /* If this is the first time we've processed this symbol,
514
                   fill in the plt entry with the correct symbol address.  */
515
                if ((*plt_offset & 1) == 0)
516
                  {
517
                    unsigned int x;
518
 
519
                    x = 0x000000ec;  /* br !!abs24 */
520
                    x |= (relocation << 8) & 0xffffff00;
521
                    bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
522
                    *plt_offset |= 1;
523
                  }
524
 
525
                relocation = (splt->output_section->vma
526
                              + splt->output_offset
527
                              + (*plt_offset & -2));
528
                if (name)
529
                {
530
                  char *newname = bfd_malloc (strlen(name)+5);
531
                  strcpy (newname, name);
532
                  strcat(newname, ".plt");
533
                  _bfd_generic_link_add_one_symbol (info,
534
                                                    input_bfd,
535
                                                    newname,
536
                                                    BSF_FUNCTION | BSF_WEAK,
537
                                                    splt,
538
                                                    (*plt_offset & -2),
539
                                                    0,
540
                                                    1,
541
                                                    0,
542
                                                    0);
543
                }
544
              }
545
          }
546
          break;
547
        }
548
 
549
      if (h != NULL && h->root.type == bfd_link_hash_undefweak)
550
        /* If the symbol is undefined and weak
551
           then the relocation resolves to zero.  */
552
        relocation = 0;
553
      else
554
        {
555
          if (howto->pc_relative)
556
            {
557
              relocation -= (input_section->output_section->vma
558
                             + input_section->output_offset
559
                             + rel->r_offset);
560
              relocation -= bfd_get_reloc_size (howto);
561
            }
562
 
563
          relocation += rel->r_addend;
564
        }
565
 
566
      r = bfd_reloc_ok;
567
 
568
#define RANGE(a,b) if (a > (long) relocation || (long) relocation > b) r = bfd_reloc_overflow
569
#define ALIGN(m)   if (relocation & m) r = bfd_reloc_other;
570
#define OP(i)      (contents[rel->r_offset + (i)])
571
 
572
      /* Opcode relocs are always big endian.  Data relocs are bi-endian.  */
573
      switch (r_type)
574
        {
575
        case R_RL78_NONE:
576
          break;
577
 
578
        case R_RL78_DIR8S_PCREL:
579
          RANGE (-128, 127);
580
          OP (0) = relocation;
581
          break;
582
 
583
        case R_RL78_DIR8S:
584
          RANGE (-128, 255);
585
          OP (0) = relocation;
586
          break;
587
 
588
        case R_RL78_DIR8U:
589
          RANGE (0, 255);
590
          OP (0) = relocation;
591
          break;
592
 
593
        case R_RL78_DIR16S_PCREL:
594
          RANGE (-32768, 32767);
595
          OP (0) = relocation;
596
          OP (1) = relocation >> 8;
597
          break;
598
 
599
        case R_RL78_DIR16S:
600
          if ((relocation & 0xf0000) == 0xf0000)
601
            relocation &= 0xffff;
602
          RANGE (-32768, 65535);
603
          OP (0) = relocation;
604
          OP (1) = relocation >> 8;
605
          break;
606
 
607
        case R_RL78_DIR16U:
608
          RANGE (0, 65536);
609
          OP (0) = relocation;
610
          OP (1) = relocation >> 8;
611
          break;
612
 
613
        case R_RL78_DIR16:
614
          RANGE (-32768, 65536);
615
          OP (0) = relocation;
616
          OP (1) = relocation >> 8;
617
          break;
618
 
619
        case R_RL78_DIR16_REV:
620
          RANGE (-32768, 65536);
621
          OP (1) = relocation;
622
          OP (0) = relocation >> 8;
623
          break;
624
 
625
        case R_RL78_DIR3U_PCREL:
626
          RANGE (3, 10);
627
          OP (0) &= 0xf8;
628
          OP (0) |= relocation & 0x07;
629
          break;
630
 
631
        case R_RL78_DIR24S_PCREL:
632
          RANGE (-0x800000, 0x7fffff);
633
          OP (0) = relocation;
634
          OP (1) = relocation >> 8;
635
          OP (2) = relocation >> 16;
636
          break;
637
 
638
        case R_RL78_DIR24S:
639
          RANGE (-0x800000, 0x7fffff);
640
          OP (0) = relocation;
641
          OP (1) = relocation >> 8;
642
          OP (2) = relocation >> 16;
643
          break;
644
 
645
        case R_RL78_DIR32:
646
          OP (0) = relocation;
647
          OP (1) = relocation >> 8;
648
          OP (2) = relocation >> 16;
649
          OP (3) = relocation >> 24;
650
          break;
651
 
652
        case R_RL78_DIR32_REV:
653
          OP (3) = relocation;
654
          OP (2) = relocation >> 8;
655
          OP (1) = relocation >> 16;
656
          OP (0) = relocation >> 24;
657
          break;
658
 
659
          /* Complex reloc handling:  */
660
 
661
        case R_RL78_ABS32:
662
          RL78_STACK_POP (relocation);
663
          OP (0) = relocation;
664
          OP (1) = relocation >> 8;
665
          OP (2) = relocation >> 16;
666
          OP (3) = relocation >> 24;
667
          break;
668
 
669
        case R_RL78_ABS32_REV:
670
          RL78_STACK_POP (relocation);
671
          OP (3) = relocation;
672
          OP (2) = relocation >> 8;
673
          OP (1) = relocation >> 16;
674
          OP (0) = relocation >> 24;
675
          break;
676
 
677
        case R_RL78_ABS24S_PCREL:
678
        case R_RL78_ABS24S:
679
          RL78_STACK_POP (relocation);
680
          RANGE (-0x800000, 0x7fffff);
681
          OP (0) = relocation;
682
          OP (1) = relocation >> 8;
683
          OP (2) = relocation >> 16;
684
          break;
685
 
686
        case R_RL78_ABS16:
687
          RL78_STACK_POP (relocation);
688
          RANGE (-32768, 65535);
689
          OP (0) = relocation;
690
          OP (1) = relocation >> 8;
691
          break;
692
 
693
        case R_RL78_ABS16_REV:
694
          RL78_STACK_POP (relocation);
695
          RANGE (-32768, 65535);
696
          OP (1) = relocation;
697
          OP (0) = relocation >> 8;
698
          break;
699
 
700
        case R_RL78_ABS16S_PCREL:
701
        case R_RL78_ABS16S:
702
          RL78_STACK_POP (relocation);
703
          RANGE (-32768, 32767);
704
          OP (0) = relocation;
705
          OP (1) = relocation >> 8;
706
          break;
707
 
708
        case R_RL78_ABS16U:
709
          RL78_STACK_POP (relocation);
710
          RANGE (0, 65536);
711
          OP (0) = relocation;
712
          OP (1) = relocation >> 8;
713
          break;
714
 
715
        case R_RL78_ABS16UL:
716
          RL78_STACK_POP (relocation);
717
          relocation >>= 2;
718
          RANGE (0, 65536);
719
          OP (0) = relocation;
720
          OP (1) = relocation >> 8;
721
          break;
722
 
723
        case R_RL78_ABS16UW:
724
          RL78_STACK_POP (relocation);
725
          relocation >>= 1;
726
          RANGE (0, 65536);
727
          OP (0) = relocation;
728
          OP (1) = relocation >> 8;
729
          break;
730
 
731
        case R_RL78_ABS8:
732
          RL78_STACK_POP (relocation);
733
          RANGE (-128, 255);
734
          OP (0) = relocation;
735
          break;
736
 
737
        case R_RL78_ABS8U:
738
          RL78_STACK_POP (relocation);
739
          RANGE (0, 255);
740
          OP (0) = relocation;
741
          break;
742
 
743
        case R_RL78_ABS8UL:
744
          RL78_STACK_POP (relocation);
745
          relocation >>= 2;
746
          RANGE (0, 255);
747
          OP (0) = relocation;
748
          break;
749
 
750
        case R_RL78_ABS8UW:
751
          RL78_STACK_POP (relocation);
752
          relocation >>= 1;
753
          RANGE (0, 255);
754
          OP (0) = relocation;
755
          break;
756
 
757
        case R_RL78_ABS8S_PCREL:
758
        case R_RL78_ABS8S:
759
          RL78_STACK_POP (relocation);
760
          RANGE (-128, 127);
761
          OP (0) = relocation;
762
          break;
763
 
764
        case R_RL78_SYM:
765
          if (r_symndx < symtab_hdr->sh_info)
766
            RL78_STACK_PUSH (sec->output_section->vma
767
                           + sec->output_offset
768
                           + sym->st_value
769
                           + rel->r_addend);
770
          else
771
            {
772
              if (h != NULL
773
                  && (h->root.type == bfd_link_hash_defined
774
                      || h->root.type == bfd_link_hash_defweak))
775
                RL78_STACK_PUSH (h->root.u.def.value
776
                               + sec->output_section->vma
777
                               + sec->output_offset
778
                               + rel->r_addend);
779
              else
780
                _bfd_error_handler (_("Warning: RL78_SYM reloc with an unknown symbol"));
781
            }
782
          break;
783
 
784
        case R_RL78_OPneg:
785
          {
786
            int32_t tmp;
787
 
788
            RL78_STACK_POP (tmp);
789
            tmp = - tmp;
790
            RL78_STACK_PUSH (tmp);
791
          }
792
          break;
793
 
794
        case R_RL78_OPadd:
795
          {
796
            int32_t tmp1, tmp2;
797
 
798
            RL78_STACK_POP (tmp2);
799
            RL78_STACK_POP (tmp1);
800
            tmp1 += tmp2;
801
            RL78_STACK_PUSH (tmp1);
802
          }
803
          break;
804
 
805
        case R_RL78_OPsub:
806
          {
807
            int32_t tmp1, tmp2;
808
 
809
            RL78_STACK_POP (tmp2);
810
            RL78_STACK_POP (tmp1);
811
            tmp2 -= tmp1;
812
            RL78_STACK_PUSH (tmp2);
813
          }
814
          break;
815
 
816
        case R_RL78_OPmul:
817
          {
818
            int32_t tmp1, tmp2;
819
 
820
            RL78_STACK_POP (tmp2);
821
            RL78_STACK_POP (tmp1);
822
            tmp1 *= tmp2;
823
            RL78_STACK_PUSH (tmp1);
824
          }
825
          break;
826
 
827
        case R_RL78_OPdiv:
828
          {
829
            int32_t tmp1, tmp2;
830
 
831
            RL78_STACK_POP (tmp2);
832
            RL78_STACK_POP (tmp1);
833
            tmp1 /= tmp2;
834
            RL78_STACK_PUSH (tmp1);
835
          }
836
          break;
837
 
838
        case R_RL78_OPshla:
839
          {
840
            int32_t tmp1, tmp2;
841
 
842
            RL78_STACK_POP (tmp2);
843
            RL78_STACK_POP (tmp1);
844
            tmp1 <<= tmp2;
845
            RL78_STACK_PUSH (tmp1);
846
          }
847
          break;
848
 
849
        case R_RL78_OPshra:
850
          {
851
            int32_t tmp1, tmp2;
852
 
853
            RL78_STACK_POP (tmp2);
854
            RL78_STACK_POP (tmp1);
855
            tmp1 >>= tmp2;
856
            RL78_STACK_PUSH (tmp1);
857
          }
858
          break;
859
 
860
        case R_RL78_OPsctsize:
861
          RL78_STACK_PUSH (input_section->size);
862
          break;
863
 
864
        case R_RL78_OPscttop:
865
          RL78_STACK_PUSH (input_section->output_section->vma);
866
          break;
867
 
868
        case R_RL78_OPand:
869
          {
870
            int32_t tmp1, tmp2;
871
 
872
            RL78_STACK_POP (tmp2);
873
            RL78_STACK_POP (tmp1);
874
            tmp1 &= tmp2;
875
            RL78_STACK_PUSH (tmp1);
876
          }
877
          break;
878
 
879
        case R_RL78_OPor:
880
          {
881
            int32_t tmp1, tmp2;
882
 
883
            RL78_STACK_POP (tmp2);
884
            RL78_STACK_POP (tmp1);
885
            tmp1 |= tmp2;
886
            RL78_STACK_PUSH (tmp1);
887
          }
888
          break;
889
 
890
        case R_RL78_OPxor:
891
          {
892
            int32_t tmp1, tmp2;
893
 
894
            RL78_STACK_POP (tmp2);
895
            RL78_STACK_POP (tmp1);
896
            tmp1 ^= tmp2;
897
            RL78_STACK_PUSH (tmp1);
898
          }
899
          break;
900
 
901
        case R_RL78_OPnot:
902
          {
903
            int32_t tmp;
904
 
905
            RL78_STACK_POP (tmp);
906
            tmp = ~ tmp;
907
            RL78_STACK_PUSH (tmp);
908
          }
909
          break;
910
 
911
        case R_RL78_OPmod:
912
          {
913
            int32_t tmp1, tmp2;
914
 
915
            RL78_STACK_POP (tmp2);
916
            RL78_STACK_POP (tmp1);
917
            tmp1 %= tmp2;
918
            RL78_STACK_PUSH (tmp1);
919
          }
920
          break;
921
 
922
        case R_RL78_OPromtop:
923
          RL78_STACK_PUSH (get_romstart (&r, info, input_bfd, input_section, rel->r_offset));
924
          break;
925
 
926
        case R_RL78_OPramtop:
927
          RL78_STACK_PUSH (get_ramstart (&r, info, input_bfd, input_section, rel->r_offset));
928
          break;
929
 
930
        default:
931
          r = bfd_reloc_notsupported;
932
          break;
933
        }
934
 
935
      if (r != bfd_reloc_ok)
936
        {
937
          const char * msg = NULL;
938
 
939
          switch (r)
940
            {
941
            case bfd_reloc_overflow:
942
              /* Catch the case of a missing function declaration
943
                 and emit a more helpful error message.  */
944
              if (r_type == R_RL78_DIR24S_PCREL)
945
                msg = _("%B(%A): error: call to undefined function '%s'");
946
              else
947
                r = info->callbacks->reloc_overflow
948
                  (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
949
                   input_bfd, input_section, rel->r_offset);
950
              break;
951
 
952
            case bfd_reloc_undefined:
953
              r = info->callbacks->undefined_symbol
954
                (info, name, input_bfd, input_section, rel->r_offset,
955
                 TRUE);
956
              break;
957
 
958
            case bfd_reloc_other:
959
              msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
960
              break;
961
 
962
            case bfd_reloc_outofrange:
963
              msg = _("%B(%A): internal error: out of range error");
964
              break;
965
 
966
            case bfd_reloc_notsupported:
967
              msg = _("%B(%A): internal error: unsupported relocation error");
968
              break;
969
 
970
            case bfd_reloc_dangerous:
971
              msg = _("%B(%A): internal error: dangerous relocation");
972
              break;
973
 
974
            default:
975
              msg = _("%B(%A): internal error: unknown error");
976
              break;
977
            }
978
 
979
          if (msg)
980
            _bfd_error_handler (msg, input_bfd, input_section, name);
981
 
982
          if (! r)
983
            return FALSE;
984
        }
985
    }
986
 
987
  return TRUE;
988
}
989
 
990
/* Function to set the ELF flag bits.  */
991
 
992
static bfd_boolean
993
rl78_elf_set_private_flags (bfd * abfd, flagword flags)
994
{
995
  elf_elfheader (abfd)->e_flags = flags;
996
  elf_flags_init (abfd) = TRUE;
997
  return TRUE;
998
}
999
 
1000
static bfd_boolean no_warn_mismatch = FALSE;
1001
 
1002
void bfd_elf32_rl78_set_target_flags (bfd_boolean);
1003
 
1004
void
1005
bfd_elf32_rl78_set_target_flags (bfd_boolean user_no_warn_mismatch)
1006
{
1007
  no_warn_mismatch = user_no_warn_mismatch;
1008
}
1009
 
1010
/* Merge backend specific data from an object file to the output
1011
   object file when linking.  */
1012
 
1013
static bfd_boolean
1014
rl78_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1015
{
1016
  flagword new_flags;
1017
  bfd_boolean error = FALSE;
1018
 
1019
  new_flags = elf_elfheader (ibfd)->e_flags;
1020
 
1021
  if (!elf_flags_init (obfd))
1022
    {
1023
      /* First call, no flags set.  */
1024
      elf_flags_init (obfd) = TRUE;
1025
      elf_elfheader (obfd)->e_flags = new_flags;
1026
    }
1027
 
1028
  return !error;
1029
}
1030
 
1031
static bfd_boolean
1032
rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
1033
{
1034
  FILE * file = (FILE *) ptr;
1035
  flagword flags;
1036
 
1037
  BFD_ASSERT (abfd != NULL && ptr != NULL);
1038
 
1039
  /* Print normal ELF private data.  */
1040
  _bfd_elf_print_private_bfd_data (abfd, ptr);
1041
 
1042
  flags = elf_elfheader (abfd)->e_flags;
1043
  fprintf (file, _("private flags = 0x%lx:"), (long) flags);
1044
 
1045
  fputc ('\n', file);
1046
  return TRUE;
1047
}
1048
 
1049
/* Return the MACH for an e_flags value.  */
1050
 
1051
static int
1052
elf32_rl78_machine (bfd * abfd)
1053
{
1054
  if ((elf_elfheader (abfd)->e_flags & EF_RL78_CPU_MASK) == EF_RL78_CPU_RL78)
1055
    return bfd_mach_rl78;
1056
 
1057
  return 0;
1058
}
1059
 
1060
static bfd_boolean
1061
rl78_elf_object_p (bfd * abfd)
1062
{
1063
  bfd_default_set_arch_mach (abfd, bfd_arch_rl78,
1064
                             elf32_rl78_machine (abfd));
1065
  return TRUE;
1066
}
1067
 
1068
#ifdef DEBUG
1069
void
1070
rl78_dump_symtab (bfd * abfd, void * internal_syms, void * external_syms)
1071
{
1072
  size_t locsymcount;
1073
  Elf_Internal_Sym * isymbuf;
1074
  Elf_Internal_Sym * isymend;
1075
  Elf_Internal_Sym * isym;
1076
  Elf_Internal_Shdr * symtab_hdr;
1077
  bfd_boolean free_internal = FALSE, free_external = FALSE;
1078
  char * st_info_str;
1079
  char * st_info_stb_str;
1080
  char * st_other_str;
1081
  char * st_shndx_str;
1082
 
1083
  if (! internal_syms)
1084
    {
1085
      internal_syms = bfd_malloc (1000);
1086
      free_internal = 1;
1087
    }
1088
  if (! external_syms)
1089
    {
1090
      external_syms = bfd_malloc (1000);
1091
      free_external = 1;
1092
    }
1093
 
1094
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1095
  locsymcount = symtab_hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
1096
  if (free_internal)
1097
    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1098
                                    symtab_hdr->sh_info, 0,
1099
                                    internal_syms, external_syms, NULL);
1100
  else
1101
    isymbuf = internal_syms;
1102
  isymend = isymbuf + locsymcount;
1103
 
1104
  for (isym = isymbuf ; isym < isymend ; isym++)
1105
    {
1106
      switch (ELF_ST_TYPE (isym->st_info))
1107
        {
1108
        case STT_FUNC: st_info_str = "STT_FUNC";
1109
        case STT_SECTION: st_info_str = "STT_SECTION";
1110
        case STT_FILE: st_info_str = "STT_FILE";
1111
        case STT_OBJECT: st_info_str = "STT_OBJECT";
1112
        case STT_TLS: st_info_str = "STT_TLS";
1113
        default: st_info_str = "";
1114
        }
1115
      switch (ELF_ST_BIND (isym->st_info))
1116
        {
1117
        case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
1118
        case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
1119
        default: st_info_stb_str = "";
1120
        }
1121
      switch (ELF_ST_VISIBILITY (isym->st_other))
1122
        {
1123
        case STV_DEFAULT: st_other_str = "STV_DEFAULT";
1124
        case STV_INTERNAL: st_other_str = "STV_INTERNAL";
1125
        case STV_PROTECTED: st_other_str = "STV_PROTECTED";
1126
        default: st_other_str = "";
1127
        }
1128
      switch (isym->st_shndx)
1129
        {
1130
        case SHN_ABS: st_shndx_str = "SHN_ABS";
1131
        case SHN_COMMON: st_shndx_str = "SHN_COMMON";
1132
        case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
1133
        default: st_shndx_str = "";
1134
        }
1135
 
1136
      printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
1137
              "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
1138
              isym,
1139
              (unsigned long) isym->st_value,
1140
              (unsigned long) isym->st_size,
1141
              isym->st_name,
1142
              bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
1143
                                               isym->st_name),
1144
              isym->st_info, st_info_str, st_info_stb_str,
1145
              isym->st_other, st_other_str,
1146
              isym->st_shndx, st_shndx_str);
1147
    }
1148
  if (free_internal)
1149
    free (internal_syms);
1150
  if (free_external)
1151
    free (external_syms);
1152
}
1153
 
1154
char *
1155
rl78_get_reloc (long reloc)
1156
{
1157
  if (0 <= reloc && reloc < R_RL78_max)
1158
    return rl78_elf_howto_table[reloc].name;
1159
  return "";
1160
}
1161
#endif /* DEBUG */
1162
 
1163
 
1164
/* support PLT for 16-bit references to 24-bit functions.  */
1165
 
1166
/* We support 16-bit pointers to code above 64k by generating a thunk
1167
   below 64k containing a JMP instruction to the final address.  */
1168
 
1169
static bfd_boolean
1170
rl78_elf_check_relocs
1171
    (bfd *                     abfd,
1172
     struct bfd_link_info *    info,
1173
     asection *                sec,
1174
     const Elf_Internal_Rela * relocs)
1175
{
1176
  Elf_Internal_Shdr *           symtab_hdr;
1177
  struct elf_link_hash_entry ** sym_hashes;
1178
  const Elf_Internal_Rela *     rel;
1179
  const Elf_Internal_Rela *     rel_end;
1180
  bfd_vma *local_plt_offsets;
1181
  asection *splt;
1182
  bfd *dynobj;
1183
 
1184
  if (info->relocatable)
1185
    return TRUE;
1186
 
1187
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1188
  sym_hashes = elf_sym_hashes (abfd);
1189
  local_plt_offsets = elf_local_got_offsets (abfd);
1190
  splt = NULL;
1191
  dynobj = elf_hash_table(info)->dynobj;
1192
 
1193
  rel_end = relocs + sec->reloc_count;
1194
  for (rel = relocs; rel < rel_end; rel++)
1195
    {
1196
      struct elf_link_hash_entry *h;
1197
      unsigned long r_symndx;
1198
      bfd_vma *offset;
1199
 
1200
      r_symndx = ELF32_R_SYM (rel->r_info);
1201
      if (r_symndx < symtab_hdr->sh_info)
1202
        h = NULL;
1203
      else
1204
        {
1205
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1206
          while (h->root.type == bfd_link_hash_indirect
1207
                 || h->root.type == bfd_link_hash_warning)
1208
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
1209
        }
1210
 
1211
      switch (ELF32_R_TYPE (rel->r_info))
1212
        {
1213
          /* This relocation describes a 16-bit pointer to a function.
1214
             We may need to allocate a thunk in low memory; reserve memory
1215
             for it now.  */
1216
        case R_RL78_DIR16S:
1217
          if (dynobj == NULL)
1218
            elf_hash_table (info)->dynobj = dynobj = abfd;
1219
          if (splt == NULL)
1220
            {
1221
              splt = bfd_get_section_by_name (dynobj, ".plt");
1222
              if (splt == NULL)
1223
                {
1224
                  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1225
                                    | SEC_IN_MEMORY | SEC_LINKER_CREATED
1226
                                    | SEC_READONLY | SEC_CODE);
1227
                  splt = bfd_make_section_with_flags (dynobj, ".plt", flags);
1228
                  if (splt == NULL
1229
                      || ! bfd_set_section_alignment (dynobj, splt, 1))
1230
                    return FALSE;
1231
                }
1232
            }
1233
 
1234
          if (h != NULL)
1235
            offset = &h->plt.offset;
1236
          else
1237
            {
1238
              if (local_plt_offsets == NULL)
1239
                {
1240
                  size_t size;
1241
                  unsigned int i;
1242
 
1243
                  size = symtab_hdr->sh_info * sizeof (bfd_vma);
1244
                  local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
1245
                  if (local_plt_offsets == NULL)
1246
                    return FALSE;
1247
                  elf_local_got_offsets (abfd) = local_plt_offsets;
1248
 
1249
                  for (i = 0; i < symtab_hdr->sh_info; i++)
1250
                    local_plt_offsets[i] = (bfd_vma) -1;
1251
                }
1252
              offset = &local_plt_offsets[r_symndx];
1253
            }
1254
 
1255
          if (*offset == (bfd_vma) -1)
1256
            {
1257
              *offset = splt->size;
1258
              splt->size += 4;
1259
            }
1260
          break;
1261
        }
1262
    }
1263
 
1264
  return TRUE;
1265
}
1266
 
1267
/* This must exist if dynobj is ever set.  */
1268
 
1269
static bfd_boolean
1270
rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
1271
                                  struct bfd_link_info *info)
1272
{
1273
  bfd *dynobj;
1274
  asection *splt;
1275
 
1276
  /* As an extra sanity check, verify that all plt entries have
1277
     been filled in.  */
1278
 
1279
  if ((dynobj = elf_hash_table (info)->dynobj) != NULL
1280
      && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
1281
    {
1282
      bfd_byte *contents = splt->contents;
1283
      unsigned int i, size = splt->size;
1284
      for (i = 0; i < size; i += 4)
1285
        {
1286
          unsigned int x = bfd_get_32 (dynobj, contents + i);
1287
          BFD_ASSERT (x != 0);
1288
        }
1289
    }
1290
 
1291
  return TRUE;
1292
}
1293
 
1294
static bfd_boolean
1295
rl78_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
1296
                               struct bfd_link_info *info)
1297
{
1298
  bfd *dynobj;
1299
  asection *splt;
1300
 
1301
  if (info->relocatable)
1302
    return TRUE;
1303
 
1304
  dynobj = elf_hash_table (info)->dynobj;
1305
  if (dynobj == NULL)
1306
    return TRUE;
1307
 
1308
  splt = bfd_get_section_by_name (dynobj, ".plt");
1309
  BFD_ASSERT (splt != NULL);
1310
 
1311
  splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
1312
  if (splt->contents == NULL)
1313
    return FALSE;
1314
 
1315
  return TRUE;
1316
}
1317
 
1318
 
1319
 
1320
/* Handle relaxing.  */
1321
 
1322
/* A subroutine of rl78_elf_relax_section.  If the global symbol H
1323
   is within the low 64k, remove any entry for it in the plt.  */
1324
 
1325
struct relax_plt_data
1326
{
1327
  asection *splt;
1328
  bfd_boolean *again;
1329
};
1330
 
1331
static bfd_boolean
1332
rl78_relax_plt_check (struct elf_link_hash_entry *h,
1333
                      PTR xdata)
1334
{
1335
  struct relax_plt_data *data = (struct relax_plt_data *) xdata;
1336
 
1337
  if (h->plt.offset != (bfd_vma) -1)
1338
    {
1339
      bfd_vma address;
1340
 
1341
      if (h->root.type == bfd_link_hash_undefined
1342
          || h->root.type == bfd_link_hash_undefweak)
1343
        address = 0;
1344
      else
1345
        address = (h->root.u.def.section->output_section->vma
1346
                   + h->root.u.def.section->output_offset
1347
                   + h->root.u.def.value);
1348
 
1349
      if (valid_16bit_address (address))
1350
        {
1351
          h->plt.offset = -1;
1352
          data->splt->size -= 4;
1353
          *data->again = TRUE;
1354
        }
1355
    }
1356
 
1357
  return TRUE;
1358
}
1359
 
1360
/* A subroutine of rl78_elf_relax_section.  If the global symbol H
1361
   previously had a plt entry, give it a new entry offset.  */
1362
 
1363
static bfd_boolean
1364
rl78_relax_plt_realloc (struct elf_link_hash_entry *h,
1365
                        PTR xdata)
1366
{
1367
  bfd_vma *entry = (bfd_vma *) xdata;
1368
 
1369
  if (h->plt.offset != (bfd_vma) -1)
1370
    {
1371
      h->plt.offset = *entry;
1372
      *entry += 4;
1373
    }
1374
 
1375
  return TRUE;
1376
}
1377
 
1378
static bfd_boolean
1379
rl78_elf_relax_plt_section (bfd *dynobj,
1380
                            asection *splt,
1381
                            struct bfd_link_info *info,
1382
                            bfd_boolean *again)
1383
{
1384
  struct relax_plt_data relax_plt_data;
1385
  bfd *ibfd;
1386
 
1387
  /* Assume nothing changes.  */
1388
  *again = FALSE;
1389
 
1390
  if (info->relocatable)
1391
    return TRUE;
1392
 
1393
  /* We only relax the .plt section at the moment.  */
1394
  if (dynobj != elf_hash_table (info)->dynobj
1395
      || strcmp (splt->name, ".plt") != 0)
1396
    return TRUE;
1397
 
1398
  /* Quick check for an empty plt.  */
1399
  if (splt->size == 0)
1400
    return TRUE;
1401
 
1402
  /* Map across all global symbols; see which ones happen to
1403
     fall in the low 64k.  */
1404
  relax_plt_data.splt = splt;
1405
  relax_plt_data.again = again;
1406
  elf_link_hash_traverse (elf_hash_table (info), rl78_relax_plt_check,
1407
                          &relax_plt_data);
1408
 
1409
  /* Likewise for local symbols, though that's somewhat less convenient
1410
     as we have to walk the list of input bfds and swap in symbol data.  */
1411
  for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1412
    {
1413
      bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1414
      Elf_Internal_Shdr *symtab_hdr;
1415
      Elf_Internal_Sym *isymbuf = NULL;
1416
      unsigned int idx;
1417
 
1418
      if (! local_plt_offsets)
1419
        continue;
1420
 
1421
      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1422
      if (symtab_hdr->sh_info != 0)
1423
        {
1424
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1425
          if (isymbuf == NULL)
1426
            isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1427
                                            symtab_hdr->sh_info, 0,
1428
                                            NULL, NULL, NULL);
1429
          if (isymbuf == NULL)
1430
            return FALSE;
1431
        }
1432
 
1433
      for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1434
        {
1435
          Elf_Internal_Sym *isym;
1436
          asection *tsec;
1437
          bfd_vma address;
1438
 
1439
          if (local_plt_offsets[idx] == (bfd_vma) -1)
1440
            continue;
1441
 
1442
          isym = &isymbuf[idx];
1443
          if (isym->st_shndx == SHN_UNDEF)
1444
            continue;
1445
          else if (isym->st_shndx == SHN_ABS)
1446
            tsec = bfd_abs_section_ptr;
1447
          else if (isym->st_shndx == SHN_COMMON)
1448
            tsec = bfd_com_section_ptr;
1449
          else
1450
            tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1451
 
1452
          address = (tsec->output_section->vma
1453
                     + tsec->output_offset
1454
                     + isym->st_value);
1455
          if (valid_16bit_address (address))
1456
            {
1457
              local_plt_offsets[idx] = -1;
1458
              splt->size -= 4;
1459
              *again = TRUE;
1460
            }
1461
        }
1462
 
1463
      if (isymbuf != NULL
1464
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1465
        {
1466
          if (! info->keep_memory)
1467
            free (isymbuf);
1468
          else
1469
            {
1470
              /* Cache the symbols for elf_link_input_bfd.  */
1471
              symtab_hdr->contents = (unsigned char *) isymbuf;
1472
            }
1473
        }
1474
    }
1475
 
1476
  /* If we changed anything, walk the symbols again to reallocate
1477
     .plt entry addresses.  */
1478
  if (*again && splt->size > 0)
1479
    {
1480
      bfd_vma entry = 0;
1481
 
1482
      elf_link_hash_traverse (elf_hash_table (info),
1483
                              rl78_relax_plt_realloc, &entry);
1484
 
1485
      for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1486
        {
1487
          bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1488
          unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1489
          unsigned int idx;
1490
 
1491
          if (! local_plt_offsets)
1492
            continue;
1493
 
1494
          for (idx = 0; idx < nlocals; ++idx)
1495
            if (local_plt_offsets[idx] != (bfd_vma) -1)
1496
              {
1497
                local_plt_offsets[idx] = entry;
1498
                entry += 4;
1499
              }
1500
        }
1501
    }
1502
 
1503
  return TRUE;
1504
}
1505
 
1506
static bfd_boolean
1507
rl78_elf_relax_section
1508
    (bfd *                  abfd,
1509
     asection *             sec,
1510
     struct bfd_link_info * link_info,
1511
     bfd_boolean *          again)
1512
{
1513
  if (abfd == elf_hash_table (link_info)->dynobj
1514
      && strcmp (sec->name, ".plt") == 0)
1515
    return rl78_elf_relax_plt_section (abfd, sec, link_info, again);
1516
 
1517
  /* Assume nothing changes.  */
1518
  *again = FALSE;
1519
  return TRUE;
1520
}
1521
 
1522
 
1523
 
1524
#define ELF_ARCH                bfd_arch_rl78
1525
#define ELF_MACHINE_CODE        EM_RL78
1526
#define ELF_MAXPAGESIZE         0x1000
1527
 
1528
#define TARGET_LITTLE_SYM       bfd_elf32_rl78_vec
1529
#define TARGET_LITTLE_NAME      "elf32-rl78"
1530
 
1531
#define elf_info_to_howto_rel                   NULL
1532
#define elf_info_to_howto                       rl78_info_to_howto_rela
1533
#define elf_backend_object_p                    rl78_elf_object_p
1534
#define elf_backend_relocate_section            rl78_elf_relocate_section
1535
#define elf_symbol_leading_char                 ('_')
1536
#define elf_backend_can_gc_sections             1
1537
 
1538
#define bfd_elf32_bfd_reloc_type_lookup         rl78_reloc_type_lookup
1539
#define bfd_elf32_bfd_reloc_name_lookup         rl78_reloc_name_lookup
1540
#define bfd_elf32_bfd_set_private_flags         rl78_elf_set_private_flags
1541
#define bfd_elf32_bfd_merge_private_bfd_data    rl78_elf_merge_private_bfd_data
1542
#define bfd_elf32_bfd_print_private_bfd_data    rl78_elf_print_private_bfd_data
1543
 
1544
#define bfd_elf32_bfd_relax_section             rl78_elf_relax_section
1545
#define elf_backend_check_relocs                rl78_elf_check_relocs
1546
#define elf_backend_always_size_sections \
1547
  rl78_elf_always_size_sections
1548
#define elf_backend_finish_dynamic_sections \
1549
  rl78_elf_finish_dynamic_sections
1550
 
1551
#include "elf32-target.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.