* Makefile.am (ALL_64_EMULATION_SOURCES): Add powerpc64-*-freebsd
[binutils.git] / bfd / elf32-rl78.c
blob92c01b075d245189c1efa3a138cd5eea4bdc523b
1 /* Renesas RL78 specific support for 32-bit ELF.
2 Copyright (C) 2011
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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"
29 #define valid_16bit_address(v) ((v) <= 0x0ffff || (v) >= 0xf0000)
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)
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. */
39 static reloc_howto_type rl78_elf_howto_table [] =
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),
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),
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),
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),
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),
128 #define STACK_REL_P(x) ((x) <= R_RL78_ABS16_REV && (x) >= R_RL78_ABS32)
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),
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),
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)
203 /* Map BFD reloc types to RL78 ELF reloc types. */
205 struct rl78_reloc_map
207 bfd_reloc_code_real_type bfd_reloc_val;
208 unsigned int rl78_reloc_val;
211 static const struct rl78_reloc_map rl78_reloc_map [] =
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 }
240 static reloc_howto_type *
241 rl78_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
242 bfd_reloc_code_real_type code)
244 unsigned int i;
246 if (code == BFD_RELOC_RL78_32_OP)
247 return rl78_elf_howto_table + R_RL78_DIR32;
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;
253 return NULL;
256 static reloc_howto_type *
257 rl78_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name)
259 unsigned int i;
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;
266 return NULL;
269 /* Set the howto pointer for an RL78 ELF reloc. */
271 static void
272 rl78_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
273 arelent * cache_ptr,
274 Elf_Internal_Rela * dst)
276 unsigned int r_type;
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;
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)
291 bfd_vma value = 0;
292 struct bfd_link_hash_entry * h;
294 h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
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);
306 return value;
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)
316 static bfd_boolean cached = FALSE;
317 static bfd_vma cached_value = 0;
319 if (!cached)
321 cached_value = get_symbol_value ("_start", status, info, abfd, sec, offset);
322 cached = TRUE;
324 return cached_value;
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)
334 static bfd_boolean cached = FALSE;
335 static bfd_vma cached_value = 0;
337 if (!cached)
339 cached_value = get_symbol_value ("__datastart", status, info, abfd, sec, offset);
340 cached = TRUE;
342 return cached_value;
345 #define NUM_STACK_ENTRIES 16
346 static int32_t rl78_stack [ NUM_STACK_ENTRIES ];
347 static unsigned int rl78_stack_top;
349 #define RL78_STACK_PUSH(val) \
350 do \
352 if (rl78_stack_top < NUM_STACK_ENTRIES) \
353 rl78_stack [rl78_stack_top ++] = (val); \
354 else \
355 r = bfd_reloc_dangerous; \
357 while (0)
359 #define RL78_STACK_POP(dest) \
360 do \
362 if (rl78_stack_top > 0) \
363 (dest) = rl78_stack [-- rl78_stack_top]; \
364 else \
365 (dest) = 0, r = bfd_reloc_dangerous; \
367 while (0)
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.
374 The RELOCATE_SECTION function is called by the new ELF backend linker
375 to handle the relocations for a section.
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.
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.
385 This function does not have to worry about setting the reloc
386 address or the reloc symbol index.
388 LOCAL_SYMS is a pointer to the swapped in local symbols.
390 LOCAL_SECTIONS is an array giving the section in the input file
391 corresponding to the st_shndx field of each local symbol.
393 The global hash table entry for the global symbols can be found
394 via elf_sym_hashes (input_bfd).
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. */
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)
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;
420 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
421 sym_hashes = elf_sym_hashes (input_bfd);
422 relend = relocs + input_section->reloc_count;
424 dynobj = elf_hash_table (info)->dynobj;
425 splt = NULL;
426 if (dynobj != NULL)
427 splt = bfd_get_section_by_name (dynobj, ".plt");
429 for (rel = relocs; rel < relend; rel ++)
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;
442 r_type = ELF32_R_TYPE (rel->r_info);
443 r_symndx = ELF32_R_SYM (rel->r_info);
445 howto = rl78_elf_howto_table + ELF32_R_TYPE (rel->r_info);
446 h = NULL;
447 sym = NULL;
448 sec = NULL;
449 relocation = 0;
451 if (r_symndx < symtab_hdr->sh_info)
453 sym = local_syms + r_symndx;
454 sec = local_sections [r_symndx];
455 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
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;
461 else
463 bfd_boolean warned;
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);
470 name = h->root.root.string;
473 if (sec != NULL && elf_discarded_section (sec))
474 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
475 rel, relend, howto, contents);
477 if (info->relocatable)
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;
488 switch (ELF32_R_TYPE (rel->r_info))
490 case R_RL78_DIR16S:
492 bfd_vma *plt_offset;
494 if (h != NULL)
495 plt_offset = &h->plt.offset;
496 else
497 plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
499 /* printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
500 relocation, *plt_offset);*/
501 if (valid_16bit_address (relocation))
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);
507 else
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);
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)
517 unsigned int x;
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;
525 relocation = (splt->output_section->vma
526 + splt->output_offset
527 + (*plt_offset & -2));
528 if (name)
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),
546 break;
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
555 if (howto->pc_relative)
557 relocation -= (input_section->output_section->vma
558 + input_section->output_offset
559 + rel->r_offset);
560 relocation -= bfd_get_reloc_size (howto);
563 relocation += rel->r_addend;
566 r = bfd_reloc_ok;
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)])
572 /* Opcode relocs are always big endian. Data relocs are bi-endian. */
573 switch (r_type)
575 case R_RL78_NONE:
576 break;
578 case R_RL78_DIR8S_PCREL:
579 RANGE (-128, 127);
580 OP (0) = relocation;
581 break;
583 case R_RL78_DIR8S:
584 RANGE (-128, 255);
585 OP (0) = relocation;
586 break;
588 case R_RL78_DIR8U:
589 RANGE (0, 255);
590 OP (0) = relocation;
591 break;
593 case R_RL78_DIR16S_PCREL:
594 RANGE (-32768, 32767);
595 OP (0) = relocation;
596 OP (1) = relocation >> 8;
597 break;
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;
607 case R_RL78_DIR16U:
608 RANGE (0, 65536);
609 OP (0) = relocation;
610 OP (1) = relocation >> 8;
611 break;
613 case R_RL78_DIR16:
614 RANGE (-32768, 65536);
615 OP (0) = relocation;
616 OP (1) = relocation >> 8;
617 break;
619 case R_RL78_DIR16_REV:
620 RANGE (-32768, 65536);
621 OP (1) = relocation;
622 OP (0) = relocation >> 8;
623 break;
625 case R_RL78_DIR3U_PCREL:
626 RANGE (3, 10);
627 OP (0) &= 0xf8;
628 OP (0) |= relocation & 0x07;
629 break;
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;
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;
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;
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;
659 /* Complex reloc handling: */
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;
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;
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;
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;
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;
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;
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;
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;
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;
731 case R_RL78_ABS8:
732 RL78_STACK_POP (relocation);
733 RANGE (-128, 255);
734 OP (0) = relocation;
735 break;
737 case R_RL78_ABS8U:
738 RL78_STACK_POP (relocation);
739 RANGE (0, 255);
740 OP (0) = relocation;
741 break;
743 case R_RL78_ABS8UL:
744 RL78_STACK_POP (relocation);
745 relocation >>= 2;
746 RANGE (0, 255);
747 OP (0) = relocation;
748 break;
750 case R_RL78_ABS8UW:
751 RL78_STACK_POP (relocation);
752 relocation >>= 1;
753 RANGE (0, 255);
754 OP (0) = relocation;
755 break;
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;
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
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"));
782 break;
784 case R_RL78_OPneg:
786 int32_t tmp;
788 RL78_STACK_POP (tmp);
789 tmp = - tmp;
790 RL78_STACK_PUSH (tmp);
792 break;
794 case R_RL78_OPadd:
796 int32_t tmp1, tmp2;
798 RL78_STACK_POP (tmp2);
799 RL78_STACK_POP (tmp1);
800 tmp1 += tmp2;
801 RL78_STACK_PUSH (tmp1);
803 break;
805 case R_RL78_OPsub:
807 int32_t tmp1, tmp2;
809 RL78_STACK_POP (tmp2);
810 RL78_STACK_POP (tmp1);
811 tmp2 -= tmp1;
812 RL78_STACK_PUSH (tmp2);
814 break;
816 case R_RL78_OPmul:
818 int32_t tmp1, tmp2;
820 RL78_STACK_POP (tmp2);
821 RL78_STACK_POP (tmp1);
822 tmp1 *= tmp2;
823 RL78_STACK_PUSH (tmp1);
825 break;
827 case R_RL78_OPdiv:
829 int32_t tmp1, tmp2;
831 RL78_STACK_POP (tmp2);
832 RL78_STACK_POP (tmp1);
833 tmp1 /= tmp2;
834 RL78_STACK_PUSH (tmp1);
836 break;
838 case R_RL78_OPshla:
840 int32_t tmp1, tmp2;
842 RL78_STACK_POP (tmp2);
843 RL78_STACK_POP (tmp1);
844 tmp1 <<= tmp2;
845 RL78_STACK_PUSH (tmp1);
847 break;
849 case R_RL78_OPshra:
851 int32_t tmp1, tmp2;
853 RL78_STACK_POP (tmp2);
854 RL78_STACK_POP (tmp1);
855 tmp1 >>= tmp2;
856 RL78_STACK_PUSH (tmp1);
858 break;
860 case R_RL78_OPsctsize:
861 RL78_STACK_PUSH (input_section->size);
862 break;
864 case R_RL78_OPscttop:
865 RL78_STACK_PUSH (input_section->output_section->vma);
866 break;
868 case R_RL78_OPand:
870 int32_t tmp1, tmp2;
872 RL78_STACK_POP (tmp2);
873 RL78_STACK_POP (tmp1);
874 tmp1 &= tmp2;
875 RL78_STACK_PUSH (tmp1);
877 break;
879 case R_RL78_OPor:
881 int32_t tmp1, tmp2;
883 RL78_STACK_POP (tmp2);
884 RL78_STACK_POP (tmp1);
885 tmp1 |= tmp2;
886 RL78_STACK_PUSH (tmp1);
888 break;
890 case R_RL78_OPxor:
892 int32_t tmp1, tmp2;
894 RL78_STACK_POP (tmp2);
895 RL78_STACK_POP (tmp1);
896 tmp1 ^= tmp2;
897 RL78_STACK_PUSH (tmp1);
899 break;
901 case R_RL78_OPnot:
903 int32_t tmp;
905 RL78_STACK_POP (tmp);
906 tmp = ~ tmp;
907 RL78_STACK_PUSH (tmp);
909 break;
911 case R_RL78_OPmod:
913 int32_t tmp1, tmp2;
915 RL78_STACK_POP (tmp2);
916 RL78_STACK_POP (tmp1);
917 tmp1 %= tmp2;
918 RL78_STACK_PUSH (tmp1);
920 break;
922 case R_RL78_OPromtop:
923 RL78_STACK_PUSH (get_romstart (&r, info, input_bfd, input_section, rel->r_offset));
924 break;
926 case R_RL78_OPramtop:
927 RL78_STACK_PUSH (get_ramstart (&r, info, input_bfd, input_section, rel->r_offset));
928 break;
930 default:
931 r = bfd_reloc_notsupported;
932 break;
935 if (r != bfd_reloc_ok)
937 const char * msg = NULL;
939 switch (r)
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;
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;
958 case bfd_reloc_other:
959 msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
960 break;
962 case bfd_reloc_outofrange:
963 msg = _("%B(%A): internal error: out of range error");
964 break;
966 case bfd_reloc_notsupported:
967 msg = _("%B(%A): internal error: unsupported relocation error");
968 break;
970 case bfd_reloc_dangerous:
971 msg = _("%B(%A): internal error: dangerous relocation");
972 break;
974 default:
975 msg = _("%B(%A): internal error: unknown error");
976 break;
979 if (msg)
980 _bfd_error_handler (msg, input_bfd, input_section, name);
982 if (! r)
983 return FALSE;
987 return TRUE;
990 /* Function to set the ELF flag bits. */
992 static bfd_boolean
993 rl78_elf_set_private_flags (bfd * abfd, flagword flags)
995 elf_elfheader (abfd)->e_flags = flags;
996 elf_flags_init (abfd) = TRUE;
997 return TRUE;
1000 static bfd_boolean no_warn_mismatch = FALSE;
1002 void bfd_elf32_rl78_set_target_flags (bfd_boolean);
1004 void
1005 bfd_elf32_rl78_set_target_flags (bfd_boolean user_no_warn_mismatch)
1007 no_warn_mismatch = user_no_warn_mismatch;
1010 /* Merge backend specific data from an object file to the output
1011 object file when linking. */
1013 static bfd_boolean
1014 rl78_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1016 flagword new_flags;
1017 bfd_boolean error = FALSE;
1019 new_flags = elf_elfheader (ibfd)->e_flags;
1021 if (!elf_flags_init (obfd))
1023 /* First call, no flags set. */
1024 elf_flags_init (obfd) = TRUE;
1025 elf_elfheader (obfd)->e_flags = new_flags;
1028 return !error;
1031 static bfd_boolean
1032 rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
1034 FILE * file = (FILE *) ptr;
1035 flagword flags;
1037 BFD_ASSERT (abfd != NULL && ptr != NULL);
1039 /* Print normal ELF private data. */
1040 _bfd_elf_print_private_bfd_data (abfd, ptr);
1042 flags = elf_elfheader (abfd)->e_flags;
1043 fprintf (file, _("private flags = 0x%lx:"), (long) flags);
1045 fputc ('\n', file);
1046 return TRUE;
1049 /* Return the MACH for an e_flags value. */
1051 static int
1052 elf32_rl78_machine (bfd * abfd)
1054 if ((elf_elfheader (abfd)->e_flags & EF_RL78_CPU_MASK) == EF_RL78_CPU_RL78)
1055 return bfd_mach_rl78;
1057 return 0;
1060 static bfd_boolean
1061 rl78_elf_object_p (bfd * abfd)
1063 bfd_default_set_arch_mach (abfd, bfd_arch_rl78,
1064 elf32_rl78_machine (abfd));
1065 return TRUE;
1068 #ifdef DEBUG
1069 void
1070 rl78_dump_symtab (bfd * abfd, void * internal_syms, void * external_syms)
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;
1083 if (! internal_syms)
1085 internal_syms = bfd_malloc (1000);
1086 free_internal = 1;
1088 if (! external_syms)
1090 external_syms = bfd_malloc (1000);
1091 free_external = 1;
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;
1104 for (isym = isymbuf ; isym < isymend ; isym++)
1106 switch (ELF_ST_TYPE (isym->st_info))
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 = "";
1115 switch (ELF_ST_BIND (isym->st_info))
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 = "";
1121 switch (ELF_ST_VISIBILITY (isym->st_other))
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 = "";
1128 switch (isym->st_shndx)
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 = "";
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);
1148 if (free_internal)
1149 free (internal_syms);
1150 if (free_external)
1151 free (external_syms);
1154 char *
1155 rl78_get_reloc (long reloc)
1157 if (0 <= reloc && reloc < R_RL78_max)
1158 return rl78_elf_howto_table[reloc].name;
1159 return "";
1161 #endif /* DEBUG */
1164 /* support PLT for 16-bit references to 24-bit functions. */
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. */
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)
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;
1184 if (info->relocatable)
1185 return TRUE;
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;
1193 rel_end = relocs + sec->reloc_count;
1194 for (rel = relocs; rel < rel_end; rel++)
1196 struct elf_link_hash_entry *h;
1197 unsigned long r_symndx;
1198 bfd_vma *offset;
1200 r_symndx = ELF32_R_SYM (rel->r_info);
1201 if (r_symndx < symtab_hdr->sh_info)
1202 h = NULL;
1203 else
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;
1211 switch (ELF32_R_TYPE (rel->r_info))
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)
1221 splt = bfd_get_section_by_name (dynobj, ".plt");
1222 if (splt == NULL)
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;
1234 if (h != NULL)
1235 offset = &h->plt.offset;
1236 else
1238 if (local_plt_offsets == NULL)
1240 size_t size;
1241 unsigned int i;
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;
1249 for (i = 0; i < symtab_hdr->sh_info; i++)
1250 local_plt_offsets[i] = (bfd_vma) -1;
1252 offset = &local_plt_offsets[r_symndx];
1255 if (*offset == (bfd_vma) -1)
1257 *offset = splt->size;
1258 splt->size += 4;
1260 break;
1264 return TRUE;
1267 /* This must exist if dynobj is ever set. */
1269 static bfd_boolean
1270 rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
1271 struct bfd_link_info *info)
1273 bfd *dynobj;
1274 asection *splt;
1276 /* As an extra sanity check, verify that all plt entries have
1277 been filled in. */
1279 if ((dynobj = elf_hash_table (info)->dynobj) != NULL
1280 && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
1282 bfd_byte *contents = splt->contents;
1283 unsigned int i, size = splt->size;
1284 for (i = 0; i < size; i += 4)
1286 unsigned int x = bfd_get_32 (dynobj, contents + i);
1287 BFD_ASSERT (x != 0);
1291 return TRUE;
1294 static bfd_boolean
1295 rl78_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
1296 struct bfd_link_info *info)
1298 bfd *dynobj;
1299 asection *splt;
1301 if (info->relocatable)
1302 return TRUE;
1304 dynobj = elf_hash_table (info)->dynobj;
1305 if (dynobj == NULL)
1306 return TRUE;
1308 splt = bfd_get_section_by_name (dynobj, ".plt");
1309 BFD_ASSERT (splt != NULL);
1311 splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
1312 if (splt->contents == NULL)
1313 return FALSE;
1315 return TRUE;
1320 /* Handle relaxing. */
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. */
1325 struct relax_plt_data
1327 asection *splt;
1328 bfd_boolean *again;
1331 static bfd_boolean
1332 rl78_relax_plt_check (struct elf_link_hash_entry *h,
1333 PTR xdata)
1335 struct relax_plt_data *data = (struct relax_plt_data *) xdata;
1337 if (h->plt.offset != (bfd_vma) -1)
1339 bfd_vma address;
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);
1349 if (valid_16bit_address (address))
1351 h->plt.offset = -1;
1352 data->splt->size -= 4;
1353 *data->again = TRUE;
1357 return TRUE;
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. */
1363 static bfd_boolean
1364 rl78_relax_plt_realloc (struct elf_link_hash_entry *h,
1365 PTR xdata)
1367 bfd_vma *entry = (bfd_vma *) xdata;
1369 if (h->plt.offset != (bfd_vma) -1)
1371 h->plt.offset = *entry;
1372 *entry += 4;
1375 return TRUE;
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)
1384 struct relax_plt_data relax_plt_data;
1385 bfd *ibfd;
1387 /* Assume nothing changes. */
1388 *again = FALSE;
1390 if (info->relocatable)
1391 return TRUE;
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;
1398 /* Quick check for an empty plt. */
1399 if (splt->size == 0)
1400 return TRUE;
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);
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)
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;
1418 if (! local_plt_offsets)
1419 continue;
1421 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1422 if (symtab_hdr->sh_info != 0)
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;
1433 for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1435 Elf_Internal_Sym *isym;
1436 asection *tsec;
1437 bfd_vma address;
1439 if (local_plt_offsets[idx] == (bfd_vma) -1)
1440 continue;
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);
1452 address = (tsec->output_section->vma
1453 + tsec->output_offset
1454 + isym->st_value);
1455 if (valid_16bit_address (address))
1457 local_plt_offsets[idx] = -1;
1458 splt->size -= 4;
1459 *again = TRUE;
1463 if (isymbuf != NULL
1464 && symtab_hdr->contents != (unsigned char *) isymbuf)
1466 if (! info->keep_memory)
1467 free (isymbuf);
1468 else
1470 /* Cache the symbols for elf_link_input_bfd. */
1471 symtab_hdr->contents = (unsigned char *) isymbuf;
1476 /* If we changed anything, walk the symbols again to reallocate
1477 .plt entry addresses. */
1478 if (*again && splt->size > 0)
1480 bfd_vma entry = 0;
1482 elf_link_hash_traverse (elf_hash_table (info),
1483 rl78_relax_plt_realloc, &entry);
1485 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
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;
1491 if (! local_plt_offsets)
1492 continue;
1494 for (idx = 0; idx < nlocals; ++idx)
1495 if (local_plt_offsets[idx] != (bfd_vma) -1)
1497 local_plt_offsets[idx] = entry;
1498 entry += 4;
1503 return TRUE;
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)
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);
1517 /* Assume nothing changes. */
1518 *again = FALSE;
1519 return TRUE;
1524 #define ELF_ARCH bfd_arch_rl78
1525 #define ELF_MACHINE_CODE EM_RL78
1526 #define ELF_MAXPAGESIZE 0x1000
1528 #define TARGET_LITTLE_SYM bfd_elf32_rl78_vec
1529 #define TARGET_LITTLE_NAME "elf32-rl78"
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
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
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
1551 #include "elf32-target.h"