OSDN Git Service

2011-12-13 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
[pf3gnuchains/pf3gnuchains4x.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"