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