xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/elf32-epiphany.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* Adapteva epiphany specific support for 32-bit ELF
2    Copyright (C) 2000-2022 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 bool 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 */ \
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,0, false, 0, complain_overflow_dont,	  "R_EPIPHANY_NONE",	    0,		0),
67 
68   /* 8 bit absolute (not likely) */
69   AHOW (R_EPIPHANY_8,	    0, 1, 8, false, 0, complain_overflow_bitfield, "R_EPIPHANY_8",	0x000000ff, 0x000000ff),
70   /* 16 bit absolute */
71   AHOW (R_EPIPHANY_16,	    0, 2,16, false, 0, complain_overflow_bitfield, "R_EPIPHANY_16",	0x0000ffff, 0x00ff1fe0),
72   /* A 32 bit absolute relocation.  */
73   AHOW (R_EPIPHANY_32,	    0, 4,32, false, 0, complain_overflow_dont,	   "R_EPIPHANY_32",	0xffffffff, 0xffffffff),
74 
75   /*  8 bit relative relocation */
76   HOWTO ( R_EPIPHANY_8_PCREL,  0, 1,  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, 2, 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, 4, 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, 1, 8,  true, 8, complain_overflow_signed,   "R_EPIPHANY_SIMM8",	 0x000000ff, 0x0000ff00),
84   /* 24 bit pc-relative relocation */
85   AHOW (R_EPIPHANY_SIMM24,  1, 4,24,  true, 8, complain_overflow_signed,   "R_EPIPHANY_SIMM24",	 0x00ffffff, 0xffffff00),
86 
87   /* %HIGH(EA) */
88   AHOW (R_EPIPHANY_HIGH,    0, 4,16, false, 0, complain_overflow_dont,	   "R_EPIPHANY_HIGH",	 0x0ff01fe0, 0x0ff01fe0),
89 
90   /* %LOW(EA) */
91   AHOW (R_EPIPHANY_LOW,	    0, 4,16, false, 0, complain_overflow_dont,	"R_EPIPHANY_LOW",     0x0ff01fe0, 0x0ff01fe0),
92 
93   /* simm11 */
94   AHOW (R_EPIPHANY_SIMM11,  0, 4,11, false, 0, complain_overflow_bitfield, "R_EPIPHANY_SIMM11",	 0x00ff0380, 0x00ff0380),
95   /* imm12 - sign-magnitude */
96   AHOW (R_EPIPHANY_IMM11,   0, 4,11, false, 0, complain_overflow_bitfield, "R_EPIPHANY_IMM12",	 0x00ff0380, 0x00ff0380),
97   /* imm8 */
98   AHOW (R_EPIPHANY_IMM8,    0, 2, 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 *
epiphany_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)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 *
epiphany_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)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 bool
epiphany_elf_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * link_info,bool * again)179 epiphany_elf_relax_section (bfd *abfd, asection *sec,
180 			    struct bfd_link_info *link_info,
181 			    bool *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 bool new_pass = false;
193   static bool 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 (bfd_link_relocatable (link_info)
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 (elf_section_data (sec)->relocs != internal_relocs)
345     free (internal_relocs);
346 
347   return true;
348 
349  error_return:
350   if (symtab_hdr->contents != (unsigned char *) isymbuf)
351     free (isymbuf);
352   if (elf_section_data (sec)->this_hdr.contents != contents)
353     free (contents);
354   if (elf_section_data (sec)->relocs != internal_relocs)
355     free (internal_relocs);
356   return false;
357 }
358 
359 /* Set the howto pointer for a EPIPHANY ELF reloc.  */
360 
361 static bool
epiphany_info_to_howto_rela(bfd * abfd,arelent * cache_ptr,Elf_Internal_Rela * dst)362 epiphany_info_to_howto_rela (bfd * abfd,
363 			     arelent * cache_ptr,
364 			     Elf_Internal_Rela * dst)
365 {
366   unsigned int r_type;
367 
368   r_type = ELF32_R_TYPE (dst->r_info);
369   if (r_type >= (unsigned int) R_EPIPHANY_max)
370     {
371       /* xgettext:c-format */
372       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
373 			  abfd, r_type);
374       bfd_set_error (bfd_error_bad_value);
375       return false;
376     }
377   cache_ptr->howto = & epiphany_elf_howto_table [r_type];
378   return true;
379 }
380 
381 /* Perform a single relocation.
382    By default we use the standard BFD routines.  */
383 
384 static bfd_reloc_status_type
epiphany_final_link_relocate(reloc_howto_type * howto,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * rel,bfd_vma relocation)385 epiphany_final_link_relocate (reloc_howto_type *  howto,
386 			      bfd *		  input_bfd,
387 			      asection *	  input_section,
388 			      bfd_byte *	  contents,
389 			      Elf_Internal_Rela * rel,
390 			      bfd_vma		  relocation)
391 {
392   switch (howto->type)
393     {
394       /* Handle 16 bit immediates.  */
395     case R_EPIPHANY_HIGH:
396       relocation += rel->r_addend;
397       relocation >>= 16;
398       goto common;
399 
400     case R_EPIPHANY_LOW:
401       relocation += rel->r_addend;
402     common:
403       relocation = ((relocation & 0xff00L) << 12)
404 	| ((relocation & 0x00ffL) << 5);
405       /* Sanity check the address.  */
406       if (rel->r_offset > bfd_get_section_limit (input_bfd, input_section))
407 	return bfd_reloc_outofrange;
408 
409       return _bfd_relocate_contents (howto, input_bfd, relocation,
410 				     contents + rel->r_offset);
411 
412     case R_EPIPHANY_SIMM11:
413       relocation += rel->r_addend;
414       /* Check signed overflow.  */
415       if ((int)relocation > 1023 || (int)relocation < -1024)
416 	return bfd_reloc_outofrange;
417       goto disp11;
418 
419     case R_EPIPHANY_IMM11:
420       relocation += rel->r_addend;
421       if ((unsigned int) relocation > 0x7ff)
422 	return bfd_reloc_outofrange;
423       /* Fall through.  */
424     disp11:
425       relocation = (((relocation & 7) << 5)
426 		    | ((relocation & 0x7f8 ) << 13));
427       return _bfd_relocate_contents (howto, input_bfd, relocation,
428 				     contents + rel->r_offset);
429 
430       /* Pass others through.  */
431     default:
432       break;
433     }
434 
435   /* Only install relocation if above tests did not disqualify it.  */
436   return _bfd_final_link_relocate (howto, input_bfd, input_section,
437 				   contents, rel->r_offset,
438 				   relocation, rel->r_addend);
439 }
440 
441 /* Relocate an EPIPHANY ELF section.
442 
443    The RELOCATE_SECTION function is called by the new ELF backend linker
444    to handle the relocations for a section.
445 
446    The relocs are always passed as Rela structures; if the section
447    actually uses Rel structures, the r_addend field will always be
448    zero.
449 
450    This function is responsible for adjusting the section contents as
451    necessary, and (if using Rela relocs and generating a relocatable
452    output file) adjusting the reloc addend as necessary.
453 
454    This function does not have to worry about setting the reloc
455    address or the reloc symbol index.
456 
457    LOCAL_SYMS is a pointer to the swapped in local symbols.
458 
459    LOCAL_SECTIONS is an array giving the section in the input file
460    corresponding to the st_shndx field of each local symbol.
461 
462    The global hash table entry for the global symbols can be found
463    via elf_sym_hashes (input_bfd).
464 
465    When generating relocatable output, this function must handle
466    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
467    going to be the section symbol corresponding to the output
468    section, which means that the addend must be adjusted
469    accordingly.  */
470 
471 static int
epiphany_elf_relocate_section(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)472 epiphany_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
473 			       struct bfd_link_info *info,
474 			       bfd *input_bfd,
475 			       asection *input_section,
476 			       bfd_byte *contents,
477 			       Elf_Internal_Rela *relocs,
478 			       Elf_Internal_Sym *local_syms,
479 			       asection **local_sections)
480 {
481   Elf_Internal_Shdr *symtab_hdr;
482   struct elf_link_hash_entry **sym_hashes;
483   Elf_Internal_Rela *rel;
484   Elf_Internal_Rela *relend;
485 
486   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
487   sym_hashes = elf_sym_hashes (input_bfd);
488   relend     = relocs + input_section->reloc_count;
489 
490   for (rel = relocs; rel < relend; rel ++)
491     {
492       reloc_howto_type *	   howto;
493       unsigned long		   r_symndx;
494       Elf_Internal_Sym *	   sym;
495       asection *		   sec;
496       struct elf_link_hash_entry * h;
497       bfd_vma			   relocation;
498       bfd_reloc_status_type	   r;
499       const char *		   name = NULL;
500       int			   r_type ATTRIBUTE_UNUSED;
501 
502       r_type = ELF32_R_TYPE (rel->r_info);
503       r_symndx = ELF32_R_SYM (rel->r_info);
504       howto  = epiphany_elf_howto_table + ELF32_R_TYPE (rel->r_info);
505       h      = NULL;
506       sym    = NULL;
507       sec    = NULL;
508 
509       if (r_symndx < symtab_hdr->sh_info)
510 	{
511 	  sym = local_syms + r_symndx;
512 	  sec = local_sections [r_symndx];
513 	  relocation = BASEADDR (sec) + sym->st_value;
514 
515 	  name = bfd_elf_string_from_elf_section
516 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
517 	  name = name == NULL ? bfd_section_name (sec) : name;
518 	}
519       else
520 	{
521 	  bool warned ATTRIBUTE_UNUSED;
522 	  bool unresolved_reloc ATTRIBUTE_UNUSED;
523 	  bool ignored ATTRIBUTE_UNUSED;
524 
525 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
526 				   r_symndx, symtab_hdr, sym_hashes,
527 				   h, sec, relocation,
528 				   unresolved_reloc, warned, ignored);
529 
530 	  name = h->root.root.string;
531 	}
532 
533       if (sec != NULL && discarded_section (sec))
534 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
535 					 rel, 1, relend, howto, 0, contents);
536 
537       if (bfd_link_relocatable (info))
538 	continue;
539 
540       /* Finally, the sole EPIPHANY-specific part.  */
541       r = epiphany_final_link_relocate (howto, input_bfd, input_section,
542 				     contents, rel, relocation);
543 
544       if (r != bfd_reloc_ok)
545 	{
546 	  const char * msg = NULL;
547 
548 	  switch (r)
549 	    {
550 	    case bfd_reloc_overflow:
551 	      (*info->callbacks->reloc_overflow)
552 		(info, (h ? &h->root : NULL), name, howto->name,
553 		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
554 	      break;
555 
556 	    case bfd_reloc_undefined:
557 	      (*info->callbacks->undefined_symbol)
558 		(info, name, input_bfd, input_section, rel->r_offset, true);
559 	      break;
560 
561 	    case bfd_reloc_outofrange:
562 	      msg = _("internal error: out of range error");
563 	      break;
564 
565 	      /* This is how epiphany_final_link_relocate tells us of a
566 		 non-kosher reference between insn & data address spaces.  */
567 	    case bfd_reloc_notsupported:
568 	      if (sym != NULL) /* Only if it's not an unresolved symbol.  */
569 		 msg = _("unsupported relocation between data/insn address spaces");
570 	      break;
571 
572 	    case bfd_reloc_dangerous:
573 	      msg = _("internal error: dangerous relocation");
574 	      break;
575 
576 	    default:
577 	      msg = _("internal error: unknown error");
578 	      break;
579 	    }
580 
581 	  if (msg)
582 	    (*info->callbacks->warning) (info, msg, name, input_bfd,
583 					 input_section, rel->r_offset);
584 	}
585     }
586 
587   return true;
588 }
589 
590 /* We only have a little-endian target.  */
591 #define TARGET_LITTLE_SYM	 epiphany_elf32_vec
592 #define TARGET_LITTLE_NAME  "elf32-epiphany"
593 
594 #define ELF_ARCH	 bfd_arch_epiphany
595 #define ELF_MACHINE_CODE EM_ADAPTEVA_EPIPHANY
596 
597 #define ELF_MAXPAGESIZE  0x8000 /* No pages on the EPIPHANY.  */
598 
599 #define elf_info_to_howto_rel			NULL
600 #define elf_info_to_howto			epiphany_info_to_howto_rela
601 
602 #define elf_backend_can_gc_sections		1
603 #define elf_backend_rela_normal			1
604 #define elf_backend_relocate_section		epiphany_elf_relocate_section
605 
606 #define elf_symbol_leading_char			'_'
607 #define bfd_elf32_bfd_reloc_type_lookup		epiphany_reloc_type_lookup
608 #define bfd_elf32_bfd_reloc_name_lookup		epiphany_reloc_name_lookup
609 #define bfd_elf32_bfd_relax_section		epiphany_elf_relax_section
610 
611 #include "elf32-target.h"
612