OSDN Git Service

daily update
[pf3gnuchains/pf3gnuchains4x.git] / bfd / elf32-epiphany.c
1 /* Adapteva epiphany specific support for 32-bit ELF
2    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2011
3    Free Software Foundation, Inc.
4    Contributed by Embecosm on behalf of Adapteva, Inc.
5
6    This file is part of BFD, the Binary File Descriptor library.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "elf/epiphany.h"
28 #include "libiberty.h"
29
30 /* Struct used to pass miscellaneous paramaters which
31    helps to avoid overly long parameter lists.  */
32 struct misc
33 {
34   Elf_Internal_Shdr *  symtab_hdr;
35   Elf_Internal_Rela *  irelbase;
36   bfd_byte *           contents;
37   Elf_Internal_Sym *   isymbuf;
38 };
39
40 struct epiphany_opcode
41 {
42   unsigned short opcode;
43   unsigned short mask;
44 };
45
46 static bfd_boolean epiphany_relaxed = FALSE;
47
48 /* Relocation tables.  */
49 static reloc_howto_type epiphany_elf_howto_table [] =
50 {
51 #define AHOW(t,rs,s,bs,pr,bp,co,name,sm,dm)     \
52     HOWTO(t,                    /* type */ \
53           rs,                   /* rightshift */ \
54           s,                    /* size (0 = byte, 1 = short, 2 = long) */ \
55           bs,                   /* bitsize */ \
56           pr,                   /* pc_relative */ \
57           bp,                   /* bitpos */ \
58           co,                   /* complain_on_overflow */             \
59           bfd_elf_generic_reloc,/* special_function */ \
60           name,                 /* name */ \
61           FALSE,                /* partial_inplace */ \
62           sm,                   /* src_mask */ \
63           dm,                   /* dst_mask */ \
64           pr)                   /* pcrel_offset */
65
66   /* This reloc does nothing.  */
67   AHOW (R_EPIPHANY_NONE,    0, 0,32, FALSE, 0, complain_overflow_dont,     "R_EPIPHANY_NONE",        0,          0),
68
69   /* 8 bit absolute (not likely) */
70   AHOW (R_EPIPHANY_8,       0, 0, 8, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_8",      0x000000ff, 0x000000ff),
71   /* 16 bit absolute */
72   AHOW (R_EPIPHANY_16,      0, 1,16, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_16",     0x0000ffff, 0x00ff1fe0),
73   /* A 32 bit absolute relocation.  */
74   AHOW (R_EPIPHANY_32,      0, 2,32, FALSE, 0, complain_overflow_dont,     "R_EPIPHANY_32",     0xffffffff, 0xffffffff),
75
76   /*  8 bit relative relocation */
77   HOWTO ( R_EPIPHANY_8_PCREL,  0, 0,  8, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_EPIPHANY_8_PCREL", FALSE, 0x000000ff, 0x000000ff, FALSE),
78   /* 16 bit relative relocation */
79   HOWTO ( R_EPIPHANY_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_EPIPHANY_8_PCREL", FALSE, 0x000000ff, 0x000000ff, FALSE),
80   /* 32 bit relative relocation */
81   HOWTO ( R_EPIPHANY_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_EPIPHANY_8_PCREL", FALSE, 0x000000ff, 0x000000ff, FALSE),
82
83   /* 8 bit pc-relative relocation */
84   AHOW (R_EPIPHANY_SIMM8,   1, 0, 8,  TRUE, 8, complain_overflow_signed,   "R_EPIPHANY_SIMM8",   0x000000ff, 0x0000ff00),
85   /* 24 bit pc-relative relocation */
86   AHOW (R_EPIPHANY_SIMM24,  1, 2,24,  TRUE, 8, complain_overflow_signed,   "R_EPIPHANY_SIMM24",  0x00ffffff, 0xffffff00),
87
88   /* %HIGH(EA) */
89   AHOW (R_EPIPHANY_HIGH,    0, 2,16, FALSE, 0, complain_overflow_dont,     "R_EPIPHANY_HIGH",    0x0ff01fe0, 0x0ff01fe0),
90
91   /* %LOW(EA) */
92   AHOW (R_EPIPHANY_LOW,     0, 2,16, FALSE, 0, complain_overflow_dont,  "R_EPIPHANY_LOW",     0x0ff01fe0, 0x0ff01fe0),
93
94   /* simm11 */
95   AHOW (R_EPIPHANY_SIMM11,  0, 2,11, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_SIMM11",  0x00ff0380, 0x00ff0380),
96   /* imm12 - sign-magnitude */
97   AHOW (R_EPIPHANY_IMM11,   0, 2,11, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_IMM12",   0x00ff0380, 0x00ff0380),
98   /* imm8 */
99   AHOW (R_EPIPHANY_IMM8,    0, 1, 8, FALSE, 8, complain_overflow_signed,   "R_EPIPHANY_IMM8",    0x0000ff00, 0x0000ff00)
100
101
102 };
103 #undef AHOW
104
105 /* Map BFD reloc types to EPIPHANY ELF reloc types.  */
106
107 static reloc_howto_type *
108 epiphany_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
109                             bfd_reloc_code_real_type code)
110 {
111   /* Note that the epiphany_elf_howto_table is indxed by the R_
112      constants.  Thus, the order that the howto records appear in the
113      table *must* match the order of the relocation types defined in
114      include/elf/epiphany.h.  */
115
116   switch (code)
117     {
118     case BFD_RELOC_NONE:
119       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_NONE];
120
121     case BFD_RELOC_EPIPHANY_SIMM8:
122       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_SIMM8];
123     case BFD_RELOC_EPIPHANY_SIMM24:
124       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_SIMM24];
125
126     case BFD_RELOC_8_PCREL:
127       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_8_PCREL];
128     case BFD_RELOC_16_PCREL:
129       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_16_PCREL];
130     case BFD_RELOC_32_PCREL:
131       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_32_PCREL];
132
133     case BFD_RELOC_8:
134       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_8];
135     case BFD_RELOC_16:
136       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_16];
137     case BFD_RELOC_32:
138       return &epiphany_elf_howto_table[ (int) R_EPIPHANY_32];
139
140     case BFD_RELOC_EPIPHANY_HIGH:
141       return & epiphany_elf_howto_table[ (int) R_EPIPHANY_HIGH];
142     case BFD_RELOC_EPIPHANY_LOW:
143       return & epiphany_elf_howto_table[ (int) R_EPIPHANY_LOW];
144
145     case BFD_RELOC_EPIPHANY_SIMM11:
146       return & epiphany_elf_howto_table[ (int) R_EPIPHANY_SIMM11];
147     case BFD_RELOC_EPIPHANY_IMM11:
148       return & epiphany_elf_howto_table[ (int) R_EPIPHANY_IMM11];
149
150     case BFD_RELOC_EPIPHANY_IMM8:
151       return & epiphany_elf_howto_table[ (int) R_EPIPHANY_IMM8];
152
153     default:
154       /* Pacify gcc -Wall.  */
155       return NULL;
156     }
157   return NULL;
158 }
159
160 static reloc_howto_type *
161 epiphany_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
162 {
163   unsigned int i;
164
165   for (i = 0; i < ARRAY_SIZE (epiphany_elf_howto_table); i++)
166     if (epiphany_elf_howto_table[i].name != NULL
167         && strcasecmp (epiphany_elf_howto_table[i].name, r_name) == 0)
168       return &epiphany_elf_howto_table[i];
169
170   return NULL;
171 }
172
173 #define PAGENO(ABSADDR) ((ABSADDR) & 0xFFFFC000)
174 #define BASEADDR(SEC)   ((SEC)->output_section->vma + (SEC)->output_offset)
175
176 /* This function handles relaxing for the epiphany.
177    Dummy placeholder for future optimizations.  */
178
179 static bfd_boolean
180 epiphany_elf_relax_section (bfd *abfd, asection *sec,
181                             struct bfd_link_info *link_info,
182                             bfd_boolean *again)
183 {
184   Elf_Internal_Shdr *symtab_hdr;
185   Elf_Internal_Rela *internal_relocs;
186   bfd_byte *contents = NULL;
187   Elf_Internal_Sym *isymbuf = NULL;
188   static asection * first_section = NULL;
189   static unsigned long search_addr;
190   static unsigned long page_start = 0;
191   static unsigned long page_end = 0;
192   static unsigned int pass = 0;
193   static bfd_boolean new_pass = FALSE;
194   static bfd_boolean changed = FALSE;
195   struct misc misc ATTRIBUTE_UNUSED;
196   asection *stab;
197
198   /* Assume nothing changes.  */
199   *again = FALSE;
200
201   if (first_section == NULL)
202     {
203       epiphany_relaxed = TRUE;
204       first_section = sec;
205     }
206
207   if (first_section == sec)
208     {
209       pass++;
210       new_pass = TRUE;
211     }
212
213   /* We don't have to do anything for a relocatable link,
214      if this section does not have relocs, or if this is
215      not a code section.  */
216   if (link_info->relocatable
217       || (sec->flags & SEC_RELOC) == 0
218       || sec->reloc_count == 0
219       || (sec->flags & SEC_CODE) == 0)
220     return TRUE;
221
222   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
223
224   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
225                                                link_info->keep_memory);
226   if (internal_relocs == NULL)
227     goto error_return;
228
229   /* Make sure the stac.rela stuff gets read in.  */
230   stab = bfd_get_section_by_name (abfd, ".stab");
231
232   if (stab)
233     {
234       /* So stab does exits.  */
235       Elf_Internal_Rela * irelbase ATTRIBUTE_UNUSED;
236
237       irelbase = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL,
238                                             link_info->keep_memory);
239     }
240
241   /* Get section contents cached copy if it exists.  */
242   if (contents == NULL)
243     {
244       /* Get cached copy if it exists.  */
245       if (elf_section_data (sec)->this_hdr.contents != NULL)
246         contents = elf_section_data (sec)->this_hdr.contents;
247       else
248         {
249           /* Go get them off disk.  */
250           if (!bfd_malloc_and_get_section (abfd, sec, &contents))
251             goto error_return;
252         }
253     }
254
255   /* Read this BFD's symbols cached copy if it exists.  */
256   if (isymbuf == NULL && symtab_hdr->sh_info != 0)
257     {
258       isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
259       if (isymbuf == NULL)
260         isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
261                                         symtab_hdr->sh_info, 0,
262                                         NULL, NULL, NULL);
263       if (isymbuf == NULL)
264         goto error_return;
265     }
266
267   misc.symtab_hdr = symtab_hdr;
268   misc.isymbuf = isymbuf;
269   misc.irelbase = internal_relocs;
270   misc.contents = contents;
271
272   /* This is where all the relaxation actually get done.  */
273   if ((pass == 1) || (new_pass && !changed))
274     {
275       /* On the first pass we simply search for the lowest page that
276          we havn't relaxed yet. Note that the pass count is reset
277          each time a page is complete in order to move on to the next page.
278          If we can't find any more pages then we are finished.  */
279       if (new_pass)
280         {
281           pass = 1;
282           new_pass = FALSE;
283           changed = TRUE; /* Pre-initialize to break out of pass 1.  */
284           search_addr = 0xFFFFFFFF;
285         }
286
287       if ((BASEADDR (sec) + sec->size < search_addr)
288           && (BASEADDR (sec) + sec->size > page_end))
289         {
290           if (BASEADDR (sec) <= page_end)
291             search_addr = page_end + 1;
292           else
293             search_addr = BASEADDR (sec);
294
295           /* Found a page => more work to do.  */
296           *again = TRUE;
297         }
298     }
299   else
300     {
301       if (new_pass)
302         {
303           new_pass = FALSE;
304           changed = FALSE;
305           page_start = PAGENO (search_addr);
306           page_end = page_start | 0x00003FFF;
307         }
308
309       /* Only process sections in range.  */
310       if ((BASEADDR (sec) + sec->size >= page_start)
311           && (BASEADDR (sec) <= page_end))
312         {
313 #if 0
314           if (!epiphany_elf_relax_section_page (abfd, sec, &changed, &misc,
315                                                 page_start, page_end))
316 #endif
317             return FALSE;
318         }
319       *again = TRUE;
320     }
321
322   /* Perform some house keeping after relaxing the section.  */
323
324   if (isymbuf != NULL
325       && symtab_hdr->contents != (unsigned char *) isymbuf)
326     {
327       if (! link_info->keep_memory)
328         free (isymbuf);
329       else
330         symtab_hdr->contents = (unsigned char *) isymbuf;
331     }
332
333   if (contents != NULL
334       && elf_section_data (sec)->this_hdr.contents != contents)
335     {
336       if (! link_info->keep_memory)
337         free (contents);
338       else
339         {
340           /* Cache the section contents for elf_link_input_bfd.  */
341           elf_section_data (sec)->this_hdr.contents = contents;
342         }
343     }
344
345   if (internal_relocs != NULL
346       && elf_section_data (sec)->relocs != internal_relocs)
347     free (internal_relocs);
348
349   return TRUE;
350
351  error_return:
352   if (isymbuf != NULL
353       && symtab_hdr->contents != (unsigned char *) isymbuf)
354     free (isymbuf);
355   if (contents != NULL
356       && elf_section_data (sec)->this_hdr.contents != contents)
357     free (contents);
358   if (internal_relocs != NULL
359       && elf_section_data (sec)->relocs != internal_relocs)
360     free (internal_relocs);
361   return FALSE;
362 }
363
364 /* Set the howto pointer for a EPIPHANY ELF reloc.  */
365
366 static void
367 epiphany_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
368                              arelent * cache_ptr,
369                              Elf_Internal_Rela * dst)
370 {
371   unsigned int r_type;
372
373   r_type = ELF32_R_TYPE (dst->r_info);
374   cache_ptr->howto = & epiphany_elf_howto_table [r_type];
375 }
376
377 /* Perform a single relocation.
378    By default we use the standard BFD routines.  */
379
380 static bfd_reloc_status_type
381 epiphany_final_link_relocate (reloc_howto_type *  howto,
382                               bfd *               input_bfd,
383                               asection *          input_section,
384                               bfd_byte *          contents,
385                               Elf_Internal_Rela * rel,
386                               bfd_vma             relocation)
387 {
388   switch (howto->type)
389     {
390       /* Handle 16 bit immediates.  */
391     case R_EPIPHANY_HIGH:
392       relocation += rel->r_addend;
393       relocation >>= 16;
394       goto common;
395
396     case R_EPIPHANY_LOW:
397       relocation += rel->r_addend;
398     common:
399       relocation = ((relocation & 0xff00L) << 12)
400         | ((relocation & 0x00ffL) << 5);
401       /* Sanity check the address.  */
402       if (rel->r_offset > bfd_get_section_limit (input_bfd, input_section))
403         return bfd_reloc_outofrange;
404
405       return _bfd_relocate_contents (howto, input_bfd, relocation,
406                                      contents + rel->r_offset);
407
408     case R_EPIPHANY_SIMM11:
409       relocation += rel->r_addend;
410       /* Check signed overflow.  */
411       if ((int)relocation > 1023 || (int)relocation < -1024)
412         return bfd_reloc_outofrange;
413       goto disp11;
414
415     case R_EPIPHANY_IMM11:
416       relocation += rel->r_addend;
417       if ((unsigned int) relocation > 0x7ff)
418         return bfd_reloc_outofrange;
419     disp11:
420       relocation = ((relocation & 7) << 5)
421         || ((relocation & 0x7f8 )  << 13);
422       return _bfd_relocate_contents (howto, input_bfd, relocation,
423                                      contents + rel->r_offset);
424
425       /* Pass others through.  */
426     default:
427       break;
428     }
429
430   /* Only install relocation if above tests did not disqualify it.  */
431   return _bfd_final_link_relocate (howto, input_bfd, input_section,
432                                    contents, rel->r_offset,
433                                    relocation, rel->r_addend);
434 }
435
436 /* Relocate an EPIPHANY ELF section.
437
438    The RELOCATE_SECTION function is called by the new ELF backend linker
439    to handle the relocations for a section.
440
441    The relocs are always passed as Rela structures; if the section
442    actually uses Rel structures, the r_addend field will always be
443    zero.
444
445    This function is responsible for adjusting the section contents as
446    necessary, and (if using Rela relocs and generating a relocatable
447    output file) adjusting the reloc addend as necessary.
448
449    This function does not have to worry about setting the reloc
450    address or the reloc symbol index.
451
452    LOCAL_SYMS is a pointer to the swapped in local symbols.
453
454    LOCAL_SECTIONS is an array giving the section in the input file
455    corresponding to the st_shndx field of each local symbol.
456
457    The global hash table entry for the global symbols can be found
458    via elf_sym_hashes (input_bfd).
459
460    When generating relocatable output, this function must handle
461    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
462    going to be the section symbol corresponding to the output
463    section, which means that the addend must be adjusted
464    accordingly.  */
465
466 static bfd_boolean
467 epiphany_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
468                                struct bfd_link_info *info,
469                                bfd *input_bfd,
470                                asection *input_section,
471                                bfd_byte *contents,
472                                Elf_Internal_Rela *relocs,
473                                Elf_Internal_Sym *local_syms,
474                                asection **local_sections)
475 {
476   Elf_Internal_Shdr *symtab_hdr;
477   struct elf_link_hash_entry **sym_hashes;
478   Elf_Internal_Rela *rel;
479   Elf_Internal_Rela *relend;
480
481   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
482   sym_hashes = elf_sym_hashes (input_bfd);
483   relend     = relocs + input_section->reloc_count;
484
485   for (rel = relocs; rel < relend; rel ++)
486     {
487       reloc_howto_type *           howto;
488       unsigned long                r_symndx;
489       Elf_Internal_Sym *           sym;
490       asection *                   sec;
491       struct elf_link_hash_entry * h;
492       bfd_vma                      relocation;
493       bfd_reloc_status_type        r;
494       const char *                 name = NULL;
495       int                          r_type ATTRIBUTE_UNUSED;
496
497       r_type = ELF32_R_TYPE (rel->r_info);
498       r_symndx = ELF32_R_SYM (rel->r_info);
499       howto  = epiphany_elf_howto_table + ELF32_R_TYPE (rel->r_info);
500       h      = NULL;
501       sym    = NULL;
502       sec    = NULL;
503
504       if (r_symndx < symtab_hdr->sh_info)
505         {
506           sym = local_syms + r_symndx;
507           sec = local_sections [r_symndx];
508           relocation = BASEADDR (sec) + sym->st_value;
509
510           name = bfd_elf_string_from_elf_section
511             (input_bfd, symtab_hdr->sh_link, sym->st_name);
512           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
513         }
514       else
515         {
516           bfd_boolean warned ATTRIBUTE_UNUSED;
517           bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED;
518
519           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
520                                    r_symndx, symtab_hdr, sym_hashes,
521                                    h, sec, relocation,
522                                    unresolved_reloc, warned);
523
524           name = h->root.root.string;
525         }
526
527       if (sec != NULL && elf_discarded_section (sec))
528         RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
529                                          rel, relend, howto, contents);
530
531       if (info->relocatable)
532         continue;
533
534       /* Finally, the sole EPIPHANY-specific part.  */
535       r = epiphany_final_link_relocate (howto, input_bfd, input_section,
536                                      contents, rel, relocation);
537
538       if (r != bfd_reloc_ok)
539         {
540           const char * msg = NULL;
541
542           switch (r)
543             {
544             case bfd_reloc_overflow:
545               r = info->callbacks->reloc_overflow
546                 (info, (h ? &h->root : NULL), name, howto->name,
547                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
548               break;
549
550             case bfd_reloc_undefined:
551               r = info->callbacks->undefined_symbol
552                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
553               break;
554
555             case bfd_reloc_outofrange:
556               msg = _("internal error: out of range error");
557               break;
558
559               /* This is how epiphany_final_link_relocate tells us of a
560                  non-kosher reference between insn & data address spaces.  */
561             case bfd_reloc_notsupported:
562               if (sym != NULL) /* Only if it's not an unresolved symbol.  */
563                  msg = _("unsupported relocation between data/insn address spaces");
564               break;
565
566             case bfd_reloc_dangerous:
567               msg = _("internal error: dangerous relocation");
568               break;
569
570             default:
571               msg = _("internal error: unknown error");
572               break;
573             }
574
575           if (msg)
576             r = info->callbacks->warning
577               (info, msg, name, input_bfd, input_section, rel->r_offset);
578
579           if (! r)
580             return FALSE;
581         }
582     }
583
584   return TRUE;
585 }
586
587 /* We only have a little-endian target.  */
588 #define TARGET_LITTLE_SYM        bfd_elf32_epiphany_vec
589 #define TARGET_LITTLE_NAME  "elf32-epiphany"
590
591 #define ELF_ARCH         bfd_arch_epiphany
592 #define ELF_MACHINE_CODE EM_ADAPTEVA_EPIPHANY
593
594 #define ELF_MAXPAGESIZE  0x8000 /* No pages on the EPIPHANY.  */
595
596 #define elf_info_to_howto_rel                   NULL
597 #define elf_info_to_howto                       epiphany_info_to_howto_rela
598
599 #define elf_backend_can_gc_sections             1
600 #define elf_backend_rela_normal                 1
601 #define elf_backend_relocate_section            epiphany_elf_relocate_section
602
603 #define elf_symbol_leading_char                 '_'
604 #define bfd_elf32_bfd_reloc_type_lookup         epiphany_reloc_type_lookup
605 #define bfd_elf32_bfd_reloc_name_lookup         epiphany_reloc_name_lookup
606 #define bfd_elf32_bfd_relax_section             epiphany_elf_relax_section
607
608 #include "elf32-target.h"