]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf32-rl78.c
[bfd]
[thirdparty/binutils-gdb.git] / bfd / elf32-rl78.c
1 /* 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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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"