[.]
[deliverable/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 old_flags;
1017 flagword new_flags;
1018 bfd_boolean error = FALSE;
1019
1020 new_flags = elf_elfheader (ibfd)->e_flags;
1021 old_flags = elf_elfheader (obfd)->e_flags;
1022
1023 if (!elf_flags_init (obfd))
1024 {
1025 /* First call, no flags set. */
1026 elf_flags_init (obfd) = TRUE;
1027 elf_elfheader (obfd)->e_flags = new_flags;
1028 }
1029
1030 return !error;
1031 }
1032 \f
1033 static bfd_boolean
1034 rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
1035 {
1036 FILE * file = (FILE *) ptr;
1037 flagword flags;
1038
1039 BFD_ASSERT (abfd != NULL && ptr != NULL);
1040
1041 /* Print normal ELF private data. */
1042 _bfd_elf_print_private_bfd_data (abfd, ptr);
1043
1044 flags = elf_elfheader (abfd)->e_flags;
1045 fprintf (file, _("private flags = 0x%lx:"), (long) flags);
1046
1047 fputc ('\n', file);
1048 return TRUE;
1049 }
1050
1051 /* Return the MACH for an e_flags value. */
1052
1053 static int
1054 elf32_rl78_machine (bfd * abfd)
1055 {
1056 if ((elf_elfheader (abfd)->e_flags & EF_RL78_CPU_MASK) == EF_RL78_CPU_RL78)
1057 return bfd_mach_rl78;
1058
1059 return 0;
1060 }
1061
1062 static bfd_boolean
1063 rl78_elf_object_p (bfd * abfd)
1064 {
1065 bfd_default_set_arch_mach (abfd, bfd_arch_rl78,
1066 elf32_rl78_machine (abfd));
1067 return TRUE;
1068 }
1069 \f
1070 #ifdef DEBUG
1071 void
1072 rl78_dump_symtab (bfd * abfd, void * internal_syms, void * external_syms)
1073 {
1074 size_t locsymcount;
1075 Elf_Internal_Sym * isymbuf;
1076 Elf_Internal_Sym * isymend;
1077 Elf_Internal_Sym * isym;
1078 Elf_Internal_Shdr * symtab_hdr;
1079 bfd_boolean free_internal = FALSE, free_external = FALSE;
1080 char * st_info_str;
1081 char * st_info_stb_str;
1082 char * st_other_str;
1083 char * st_shndx_str;
1084
1085 if (! internal_syms)
1086 {
1087 internal_syms = bfd_malloc (1000);
1088 free_internal = 1;
1089 }
1090 if (! external_syms)
1091 {
1092 external_syms = bfd_malloc (1000);
1093 free_external = 1;
1094 }
1095
1096 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1097 locsymcount = symtab_hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
1098 if (free_internal)
1099 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1100 symtab_hdr->sh_info, 0,
1101 internal_syms, external_syms, NULL);
1102 else
1103 isymbuf = internal_syms;
1104 isymend = isymbuf + locsymcount;
1105
1106 for (isym = isymbuf ; isym < isymend ; isym++)
1107 {
1108 switch (ELF_ST_TYPE (isym->st_info))
1109 {
1110 case STT_FUNC: st_info_str = "STT_FUNC";
1111 case STT_SECTION: st_info_str = "STT_SECTION";
1112 case STT_FILE: st_info_str = "STT_FILE";
1113 case STT_OBJECT: st_info_str = "STT_OBJECT";
1114 case STT_TLS: st_info_str = "STT_TLS";
1115 default: st_info_str = "";
1116 }
1117 switch (ELF_ST_BIND (isym->st_info))
1118 {
1119 case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
1120 case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
1121 default: st_info_stb_str = "";
1122 }
1123 switch (ELF_ST_VISIBILITY (isym->st_other))
1124 {
1125 case STV_DEFAULT: st_other_str = "STV_DEFAULT";
1126 case STV_INTERNAL: st_other_str = "STV_INTERNAL";
1127 case STV_PROTECTED: st_other_str = "STV_PROTECTED";
1128 default: st_other_str = "";
1129 }
1130 switch (isym->st_shndx)
1131 {
1132 case SHN_ABS: st_shndx_str = "SHN_ABS";
1133 case SHN_COMMON: st_shndx_str = "SHN_COMMON";
1134 case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
1135 default: st_shndx_str = "";
1136 }
1137
1138 printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
1139 "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
1140 isym,
1141 (unsigned long) isym->st_value,
1142 (unsigned long) isym->st_size,
1143 isym->st_name,
1144 bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
1145 isym->st_name),
1146 isym->st_info, st_info_str, st_info_stb_str,
1147 isym->st_other, st_other_str,
1148 isym->st_shndx, st_shndx_str);
1149 }
1150 if (free_internal)
1151 free (internal_syms);
1152 if (free_external)
1153 free (external_syms);
1154 }
1155
1156 char *
1157 rl78_get_reloc (long reloc)
1158 {
1159 if (0 <= reloc && reloc < R_RL78_max)
1160 return rl78_elf_howto_table[reloc].name;
1161 return "";
1162 }
1163 #endif /* DEBUG */
1164
1165 \f
1166 /* support PLT for 16-bit references to 24-bit functions. */
1167
1168 /* We support 16-bit pointers to code above 64k by generating a thunk
1169 below 64k containing a JMP instruction to the final address. */
1170
1171 static bfd_boolean
1172 rl78_elf_check_relocs
1173 (bfd * abfd,
1174 struct bfd_link_info * info,
1175 asection * sec,
1176 const Elf_Internal_Rela * relocs)
1177 {
1178 Elf_Internal_Shdr * symtab_hdr;
1179 struct elf_link_hash_entry ** sym_hashes;
1180 const Elf_Internal_Rela * rel;
1181 const Elf_Internal_Rela * rel_end;
1182 bfd_vma *local_plt_offsets;
1183 asection *splt;
1184 bfd *dynobj;
1185
1186 if (info->relocatable)
1187 return TRUE;
1188
1189 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1190 sym_hashes = elf_sym_hashes (abfd);
1191 local_plt_offsets = elf_local_got_offsets (abfd);
1192 splt = NULL;
1193 dynobj = elf_hash_table(info)->dynobj;
1194
1195 rel_end = relocs + sec->reloc_count;
1196 for (rel = relocs; rel < rel_end; rel++)
1197 {
1198 struct elf_link_hash_entry *h;
1199 unsigned long r_symndx;
1200 bfd_vma *offset;
1201
1202 r_symndx = ELF32_R_SYM (rel->r_info);
1203 if (r_symndx < symtab_hdr->sh_info)
1204 h = NULL;
1205 else
1206 {
1207 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1208 while (h->root.type == bfd_link_hash_indirect
1209 || h->root.type == bfd_link_hash_warning)
1210 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1211 }
1212
1213 switch (ELF32_R_TYPE (rel->r_info))
1214 {
1215 /* This relocation describes a 16-bit pointer to a function.
1216 We may need to allocate a thunk in low memory; reserve memory
1217 for it now. */
1218 case R_RL78_DIR16S:
1219 if (dynobj == NULL)
1220 elf_hash_table (info)->dynobj = dynobj = abfd;
1221 if (splt == NULL)
1222 {
1223 splt = bfd_get_section_by_name (dynobj, ".plt");
1224 if (splt == NULL)
1225 {
1226 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1227 | SEC_IN_MEMORY | SEC_LINKER_CREATED
1228 | SEC_READONLY | SEC_CODE);
1229 splt = bfd_make_section_with_flags (dynobj, ".plt", flags);
1230 if (splt == NULL
1231 || ! bfd_set_section_alignment (dynobj, splt, 1))
1232 return FALSE;
1233 }
1234 }
1235
1236 if (h != NULL)
1237 offset = &h->plt.offset;
1238 else
1239 {
1240 if (local_plt_offsets == NULL)
1241 {
1242 size_t size;
1243 unsigned int i;
1244
1245 size = symtab_hdr->sh_info * sizeof (bfd_vma);
1246 local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
1247 if (local_plt_offsets == NULL)
1248 return FALSE;
1249 elf_local_got_offsets (abfd) = local_plt_offsets;
1250
1251 for (i = 0; i < symtab_hdr->sh_info; i++)
1252 local_plt_offsets[i] = (bfd_vma) -1;
1253 }
1254 offset = &local_plt_offsets[r_symndx];
1255 }
1256
1257 if (*offset == (bfd_vma) -1)
1258 {
1259 *offset = splt->size;
1260 splt->size += 4;
1261 }
1262 break;
1263 }
1264 }
1265
1266 return TRUE;
1267 }
1268
1269 /* This must exist if dynobj is ever set. */
1270
1271 static bfd_boolean
1272 rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
1273 struct bfd_link_info *info)
1274 {
1275 bfd *dynobj;
1276 asection *splt;
1277
1278 /* As an extra sanity check, verify that all plt entries have
1279 been filled in. */
1280
1281 if ((dynobj = elf_hash_table (info)->dynobj) != NULL
1282 && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
1283 {
1284 bfd_byte *contents = splt->contents;
1285 unsigned int i, size = splt->size;
1286 for (i = 0; i < size; i += 4)
1287 {
1288 unsigned int x = bfd_get_32 (dynobj, contents + i);
1289 BFD_ASSERT (x != 0);
1290 }
1291 }
1292
1293 return TRUE;
1294 }
1295
1296 static bfd_boolean
1297 rl78_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
1298 struct bfd_link_info *info)
1299 {
1300 bfd *dynobj;
1301 asection *splt;
1302
1303 if (info->relocatable)
1304 return TRUE;
1305
1306 dynobj = elf_hash_table (info)->dynobj;
1307 if (dynobj == NULL)
1308 return TRUE;
1309
1310 splt = bfd_get_section_by_name (dynobj, ".plt");
1311 BFD_ASSERT (splt != NULL);
1312
1313 splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
1314 if (splt->contents == NULL)
1315 return FALSE;
1316
1317 return TRUE;
1318 }
1319
1320 \f
1321
1322 /* Handle relaxing. */
1323
1324 /* A subroutine of rl78_elf_relax_section. If the global symbol H
1325 is within the low 64k, remove any entry for it in the plt. */
1326
1327 struct relax_plt_data
1328 {
1329 asection *splt;
1330 bfd_boolean *again;
1331 };
1332
1333 static bfd_boolean
1334 rl78_relax_plt_check (struct elf_link_hash_entry *h,
1335 PTR xdata)
1336 {
1337 struct relax_plt_data *data = (struct relax_plt_data *) xdata;
1338
1339 if (h->plt.offset != (bfd_vma) -1)
1340 {
1341 bfd_vma address;
1342
1343 if (h->root.type == bfd_link_hash_undefined
1344 || h->root.type == bfd_link_hash_undefweak)
1345 address = 0;
1346 else
1347 address = (h->root.u.def.section->output_section->vma
1348 + h->root.u.def.section->output_offset
1349 + h->root.u.def.value);
1350
1351 if (valid_16bit_address (address))
1352 {
1353 h->plt.offset = -1;
1354 data->splt->size -= 4;
1355 *data->again = TRUE;
1356 }
1357 }
1358
1359 return TRUE;
1360 }
1361
1362 /* A subroutine of rl78_elf_relax_section. If the global symbol H
1363 previously had a plt entry, give it a new entry offset. */
1364
1365 static bfd_boolean
1366 rl78_relax_plt_realloc (struct elf_link_hash_entry *h,
1367 PTR xdata)
1368 {
1369 bfd_vma *entry = (bfd_vma *) xdata;
1370
1371 if (h->plt.offset != (bfd_vma) -1)
1372 {
1373 h->plt.offset = *entry;
1374 *entry += 4;
1375 }
1376
1377 return TRUE;
1378 }
1379
1380 static bfd_boolean
1381 rl78_elf_relax_plt_section (bfd *dynobj,
1382 asection *splt,
1383 struct bfd_link_info *info,
1384 bfd_boolean *again)
1385 {
1386 struct relax_plt_data relax_plt_data;
1387 bfd *ibfd;
1388
1389 /* Assume nothing changes. */
1390 *again = FALSE;
1391
1392 if (info->relocatable)
1393 return TRUE;
1394
1395 /* We only relax the .plt section at the moment. */
1396 if (dynobj != elf_hash_table (info)->dynobj
1397 || strcmp (splt->name, ".plt") != 0)
1398 return TRUE;
1399
1400 /* Quick check for an empty plt. */
1401 if (splt->size == 0)
1402 return TRUE;
1403
1404 /* Map across all global symbols; see which ones happen to
1405 fall in the low 64k. */
1406 relax_plt_data.splt = splt;
1407 relax_plt_data.again = again;
1408 elf_link_hash_traverse (elf_hash_table (info), rl78_relax_plt_check,
1409 &relax_plt_data);
1410
1411 /* Likewise for local symbols, though that's somewhat less convenient
1412 as we have to walk the list of input bfds and swap in symbol data. */
1413 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1414 {
1415 bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1416 Elf_Internal_Shdr *symtab_hdr;
1417 Elf_Internal_Sym *isymbuf = NULL;
1418 unsigned int idx;
1419
1420 if (! local_plt_offsets)
1421 continue;
1422
1423 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1424 if (symtab_hdr->sh_info != 0)
1425 {
1426 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1427 if (isymbuf == NULL)
1428 isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1429 symtab_hdr->sh_info, 0,
1430 NULL, NULL, NULL);
1431 if (isymbuf == NULL)
1432 return FALSE;
1433 }
1434
1435 for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1436 {
1437 Elf_Internal_Sym *isym;
1438 asection *tsec;
1439 bfd_vma address;
1440
1441 if (local_plt_offsets[idx] == (bfd_vma) -1)
1442 continue;
1443
1444 isym = &isymbuf[idx];
1445 if (isym->st_shndx == SHN_UNDEF)
1446 continue;
1447 else if (isym->st_shndx == SHN_ABS)
1448 tsec = bfd_abs_section_ptr;
1449 else if (isym->st_shndx == SHN_COMMON)
1450 tsec = bfd_com_section_ptr;
1451 else
1452 tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1453
1454 address = (tsec->output_section->vma
1455 + tsec->output_offset
1456 + isym->st_value);
1457 if (valid_16bit_address (address))
1458 {
1459 local_plt_offsets[idx] = -1;
1460 splt->size -= 4;
1461 *again = TRUE;
1462 }
1463 }
1464
1465 if (isymbuf != NULL
1466 && symtab_hdr->contents != (unsigned char *) isymbuf)
1467 {
1468 if (! info->keep_memory)
1469 free (isymbuf);
1470 else
1471 {
1472 /* Cache the symbols for elf_link_input_bfd. */
1473 symtab_hdr->contents = (unsigned char *) isymbuf;
1474 }
1475 }
1476 }
1477
1478 /* If we changed anything, walk the symbols again to reallocate
1479 .plt entry addresses. */
1480 if (*again && splt->size > 0)
1481 {
1482 bfd_vma entry = 0;
1483
1484 elf_link_hash_traverse (elf_hash_table (info),
1485 rl78_relax_plt_realloc, &entry);
1486
1487 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1488 {
1489 bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1490 unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1491 unsigned int idx;
1492
1493 if (! local_plt_offsets)
1494 continue;
1495
1496 for (idx = 0; idx < nlocals; ++idx)
1497 if (local_plt_offsets[idx] != (bfd_vma) -1)
1498 {
1499 local_plt_offsets[idx] = entry;
1500 entry += 4;
1501 }
1502 }
1503 }
1504
1505 return TRUE;
1506 }
1507
1508 static bfd_boolean
1509 rl78_elf_relax_section
1510 (bfd * abfd,
1511 asection * sec,
1512 struct bfd_link_info * link_info,
1513 bfd_boolean * again)
1514 {
1515 if (abfd == elf_hash_table (link_info)->dynobj
1516 && strcmp (sec->name, ".plt") == 0)
1517 return rl78_elf_relax_plt_section (abfd, sec, link_info, again);
1518
1519 /* Assume nothing changes. */
1520 *again = FALSE;
1521 return TRUE;
1522 }
1523
1524 \f
1525
1526 #define ELF_ARCH bfd_arch_rl78
1527 #define ELF_MACHINE_CODE EM_RL78
1528 #define ELF_MAXPAGESIZE 0x1000
1529
1530 #define TARGET_LITTLE_SYM bfd_elf32_rl78_vec
1531 #define TARGET_LITTLE_NAME "elf32-rl78"
1532
1533 #define elf_info_to_howto_rel NULL
1534 #define elf_info_to_howto rl78_info_to_howto_rela
1535 #define elf_backend_object_p rl78_elf_object_p
1536 #define elf_backend_relocate_section rl78_elf_relocate_section
1537 #define elf_symbol_leading_char ('_')
1538 #define elf_backend_can_gc_sections 1
1539
1540 #define bfd_elf32_bfd_reloc_type_lookup rl78_reloc_type_lookup
1541 #define bfd_elf32_bfd_reloc_name_lookup rl78_reloc_name_lookup
1542 #define bfd_elf32_bfd_set_private_flags rl78_elf_set_private_flags
1543 #define bfd_elf32_bfd_merge_private_bfd_data rl78_elf_merge_private_bfd_data
1544 #define bfd_elf32_bfd_print_private_bfd_data rl78_elf_print_private_bfd_data
1545
1546 #define bfd_elf32_bfd_relax_section rl78_elf_relax_section
1547 #define elf_backend_check_relocs rl78_elf_check_relocs
1548 #define elf_backend_always_size_sections \
1549 rl78_elf_always_size_sections
1550 #define elf_backend_finish_dynamic_sections \
1551 rl78_elf_finish_dynamic_sections
1552
1553 #include "elf32-target.h"
This page took 0.064281 seconds and 4 git commands to generate.