OSDN Git Service

Switch sources over to use the GPL version 3
[pf3gnuchains/pf3gnuchains3x.git] / bfd / elf32-mep.c
1 /* MeP-specific support for 32-bit ELF.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
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., 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/mep.h"
27 #include "libiberty.h"
28
29 /* Forward declarations.  */
30
31 /* Private relocation functions.  */
32 \f
33 #define MEPREL(type, size, bits, right, left, pcrel, overflow, mask) \
34   {(unsigned)type, right, size, bits, pcrel, left, overflow, mep_reloc, #type, FALSE, 0, mask, 0 }
35
36 #define N complain_overflow_dont
37 #define S complain_overflow_signed
38 #define U complain_overflow_unsigned
39
40 static bfd_reloc_status_type mep_reloc (bfd *, arelent *, struct bfd_symbol *,
41                                         void *, asection *, bfd *, char **);
42
43 static reloc_howto_type mep_elf_howto_table [] =
44 {
45   /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask.  */
46   MEPREL (R_MEP_NONE,     0,  0, 0, 0, 0, N, 0),
47   MEPREL (R_RELC,         0,  0, 0, 0, 0, N, 0),
48   /* MEPRELOC:HOWTO */
49     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
50   MEPREL (R_MEP_8,        0,  8, 0, 0, 0, U, 0xff),
51   MEPREL (R_MEP_16,       1, 16, 0, 0, 0, U, 0xffff),
52   MEPREL (R_MEP_32,       2, 32, 0, 0, 0, U, 0xffffffff),
53   MEPREL (R_MEP_PCREL8A2, 1,  8, 1, 1, 1, S, 0x00fe),
54   MEPREL (R_MEP_PCREL12A2,1, 12, 1, 1, 1, S, 0x0ffe),
55   MEPREL (R_MEP_PCREL17A2,2, 17, 0, 1, 1, S, 0x0000ffff),
56   MEPREL (R_MEP_PCREL24A2,2, 24, 0, 1, 1, S, 0x07f0ffff),
57   MEPREL (R_MEP_PCABS24A2,2, 24, 0, 1, 0, U, 0x07f0ffff),
58   MEPREL (R_MEP_LOW16,    2, 16, 0, 0, 0, N, 0x0000ffff),
59   MEPREL (R_MEP_HI16U,    2, 32, 0,16, 0, N, 0x0000ffff),
60   MEPREL (R_MEP_HI16S,    2, 32, 0,16, 0, N, 0x0000ffff),
61   MEPREL (R_MEP_GPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
62   MEPREL (R_MEP_TPREL,    2, 16, 0, 0, 0, S, 0x0000ffff),
63   MEPREL (R_MEP_TPREL7,   1,  7, 0, 0, 0, U, 0x007f),
64   MEPREL (R_MEP_TPREL7A2, 1,  7, 1, 1, 0, U, 0x007e),
65   MEPREL (R_MEP_TPREL7A4, 1,  7, 2, 2, 0, U, 0x007c),
66   MEPREL (R_MEP_UIMM24,   2, 24, 0, 0, 0, U, 0x00ffffff),
67   MEPREL (R_MEP_ADDR24A4, 2, 24, 0, 2, 0, U, 0x00fcffff),
68   MEPREL (R_MEP_GNU_VTINHERIT,1,  0,16,32, 0, N, 0x0000),
69   MEPREL (R_MEP_GNU_VTENTRY,1,  0,16,32, 0, N, 0x0000),
70   /* MEPRELOC:END */
71 };
72
73 #define VALID_MEP_RELOC(N) ((N) >= 0 \
74   && (N) < ARRAY_SIZE (mep_elf_howto_table)
75
76 #undef N
77 #undef S
78 #undef U
79
80 static bfd_reloc_status_type
81 mep_reloc
82     (bfd *               abfd ATTRIBUTE_UNUSED,
83      arelent *           reloc_entry ATTRIBUTE_UNUSED,
84      struct bfd_symbol * symbol ATTRIBUTE_UNUSED,
85      void *              data ATTRIBUTE_UNUSED,
86      asection *          input_section ATTRIBUTE_UNUSED,
87      bfd *               output_bfd ATTRIBUTE_UNUSED,
88      char **             error_message ATTRIBUTE_UNUSED)
89 {
90   return bfd_reloc_ok;
91 }
92
93 \f
94
95 #define BFD_RELOC_MEP_NONE BFD_RELOC_NONE
96 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
97 #define MAP(n) case BFD_RELOC_MEP_##n: type = R_MEP_##n; break
98 #else
99 #define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break
100 #endif
101
102 static reloc_howto_type *
103 mep_reloc_type_lookup
104     (bfd * abfd ATTRIBUTE_UNUSED,
105      bfd_reloc_code_real_type code)
106 {
107   unsigned int type = 0;
108
109   switch (code)
110     {
111     MAP(NONE);
112     case BFD_RELOC_8:
113       type = R_MEP_8;
114       break;
115     case BFD_RELOC_16:
116       type = R_MEP_16;
117       break;
118     case BFD_RELOC_32:
119       type = R_MEP_32;
120       break;
121     case BFD_RELOC_VTABLE_ENTRY:
122       type = R_MEP_GNU_VTENTRY;
123       break;
124     case BFD_RELOC_VTABLE_INHERIT:
125       type = R_MEP_GNU_VTINHERIT;
126       break;
127     case BFD_RELOC_RELC:
128       type = R_RELC;
129       break;
130
131     /* MEPRELOC:MAP */
132     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
133     MAP(8);
134     MAP(16);
135     MAP(32);
136     MAP(PCREL8A2);
137     MAP(PCREL12A2);
138     MAP(PCREL17A2);
139     MAP(PCREL24A2);
140     MAP(PCABS24A2);
141     MAP(LOW16);
142     MAP(HI16U);
143     MAP(HI16S);
144     MAP(GPREL);
145     MAP(TPREL);
146     MAP(TPREL7);
147     MAP(TPREL7A2);
148     MAP(TPREL7A4);
149     MAP(UIMM24);
150     MAP(ADDR24A4);
151     MAP(GNU_VTINHERIT);
152     MAP(GNU_VTENTRY);
153     /* MEPRELOC:END */
154
155     default:
156       /* Pacify gcc -Wall.  */
157       fprintf (stderr, "mep: no reloc for code %d\n", code);
158       return NULL;
159     }
160
161   if (mep_elf_howto_table[type].type != type)
162     {
163       fprintf (stderr, "MeP: howto %d has type %d\n", type, mep_elf_howto_table[type].type);
164       abort ();
165     }
166
167   return mep_elf_howto_table + type;
168 }
169
170 #undef MAP
171
172 static reloc_howto_type *
173 mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
174 {
175   unsigned int i;
176
177   for (i = 0;
178        i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
179        i++)
180     if (mep_elf_howto_table[i].name != NULL
181         && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
182       return &mep_elf_howto_table[i];
183
184   return NULL;
185 }
186 \f
187 /* Perform a single relocation.  */
188
189 static struct bfd_link_info *mep_info;
190 static int warn_tp = 0, warn_sda = 0;
191
192 static bfd_vma
193 mep_lookup_global
194     (char *    name,
195      bfd_vma   ofs,
196      bfd_vma * cache,
197      int *     warn)
198 {
199   struct bfd_link_hash_entry *h;
200
201   if (*cache || *warn)
202     return *cache;
203
204   h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
205   if (h == 0 || h->type != bfd_link_hash_defined)
206     {
207       *warn = ofs + 1;
208       return 0;
209     }
210   *cache = (h->u.def.value
211           + h->u.def.section->output_section->vma
212           + h->u.def.section->output_offset);
213   return *cache;
214 }
215
216 static bfd_vma
217 mep_tpoff_base (bfd_vma ofs)
218 {
219   static bfd_vma cache = 0;
220   return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
221 }
222
223 static bfd_vma
224 mep_sdaoff_base (bfd_vma ofs)
225 {
226   static bfd_vma cache = 0;
227   return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
228 }
229
230 static bfd_reloc_status_type
231 mep_final_link_relocate
232     (reloc_howto_type *  howto,
233      bfd *               input_bfd,
234      asection *          input_section,
235      bfd_byte *          contents,
236      Elf_Internal_Rela * rel,
237      bfd_vma             relocation)
238 {
239   unsigned long u;
240   long s;
241   unsigned char *byte;
242   bfd_vma pc;
243   bfd_reloc_status_type r = bfd_reloc_ok;
244   int e2, e4;
245
246   if (bfd_big_endian (input_bfd))
247     {
248       e2 = 0;
249       e4 = 0;
250     }
251   else
252     {
253       e2 = 1;
254       e4 = 3;
255     }
256
257   pc = (input_section->output_section->vma
258         + input_section->output_offset
259         + rel->r_offset);
260
261   s = relocation + rel->r_addend;
262
263   byte = (unsigned char *)contents + rel->r_offset;
264
265   if (howto->type == R_MEP_PCREL24A2
266       && s == 0
267       && pc >= 0x800000)
268     {
269       /* This is an unreachable branch to an undefined weak function.
270          Silently ignore it, since the opcode can't do that but should
271          never be executed anyway.  */
272       return bfd_reloc_ok;
273     }
274
275   if (howto->pc_relative)
276     s -= pc;
277
278   u = (unsigned long) s;
279
280   switch (howto->type)
281     {
282     /* MEPRELOC:APPLY */
283     /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h.  */
284     case R_MEP_8: /* 76543210 */
285       if (u > 255) r = bfd_reloc_overflow;
286       byte[0] = (u & 0xff);
287       break;
288     case R_MEP_16: /* fedcba9876543210 */
289       if (u > 65535) r = bfd_reloc_overflow;
290       byte[0^e2] = ((u >> 8) & 0xff);
291       byte[1^e2] = (u & 0xff);
292       break;
293     case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
294       byte[0^e4] = ((u >> 24) & 0xff);
295       byte[1^e4] = ((u >> 16) & 0xff);
296       byte[2^e4] = ((u >> 8) & 0xff);
297       byte[3^e4] = (u & 0xff);
298       break;
299     case R_MEP_PCREL8A2: /* --------7654321- */
300       if (-128 > s || s > 127) r = bfd_reloc_overflow;
301       byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
302       break;
303     case R_MEP_PCREL12A2: /* ----ba987654321- */
304       if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
305       byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
306       byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
307       break;
308     case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
309       if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
310       byte[2^e2] = ((s >> 9) & 0xff);
311       byte[3^e2] = ((s >> 1) & 0xff);
312       break;
313     case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
314       if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
315       byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
316       byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
317       byte[2^e2] = ((s >> 16) & 0xff);
318       byte[3^e2] = ((s >> 8) & 0xff);
319       break;
320     case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
321       if (u > 16777215) r = bfd_reloc_overflow;
322       byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
323       byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
324       byte[2^e2] = ((u >> 16) & 0xff);
325       byte[3^e2] = ((u >> 8) & 0xff);
326       break;
327     case R_MEP_LOW16: /* ----------------fedcba9876543210 */
328       byte[2^e2] = ((u >> 8) & 0xff);
329       byte[3^e2] = (u & 0xff);
330       break;
331     case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
332       byte[2^e2] = ((u >> 24) & 0xff);
333       byte[3^e2] = ((u >> 16) & 0xff);
334       break;
335     case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
336       byte[2^e2] = ((s >> 24) & 0xff);
337       byte[3^e2] = ((s >> 16) & 0xff);
338       break;
339     case R_MEP_GPREL: /* ----------------fedcba9876543210 */
340       s -= mep_sdaoff_base(rel->r_offset);
341       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
342       byte[2^e2] = ((s >> 8) & 0xff);
343       byte[3^e2] = (s & 0xff);
344       break;
345     case R_MEP_TPREL: /* ----------------fedcba9876543210 */
346       s -= mep_tpoff_base(rel->r_offset);
347       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
348       byte[2^e2] = ((s >> 8) & 0xff);
349       byte[3^e2] = (s & 0xff);
350       break;
351     case R_MEP_TPREL7: /* ---------6543210 */
352       u -= mep_tpoff_base(rel->r_offset);
353       if (u > 127) r = bfd_reloc_overflow;
354       byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
355       break;
356     case R_MEP_TPREL7A2: /* ---------654321- */
357       u -= mep_tpoff_base(rel->r_offset);
358       if (u > 127) r = bfd_reloc_overflow;
359       byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
360       break;
361     case R_MEP_TPREL7A4: /* ---------65432-- */
362       u -= mep_tpoff_base(rel->r_offset);
363       if (u > 127) r = bfd_reloc_overflow;
364       byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
365       break;
366     case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
367       if (u > 16777215) r = bfd_reloc_overflow;
368       byte[1^e2] = (u & 0xff);
369       byte[2^e2] = ((u >> 16) & 0xff);
370       byte[3^e2] = ((u >> 8) & 0xff);
371       break;
372     case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
373       if (u > 16777215) r = bfd_reloc_overflow;
374       byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
375       byte[2^e2] = ((u >> 16) & 0xff);
376       byte[3^e2] = ((u >> 8) & 0xff);
377       break;
378     case R_MEP_GNU_VTINHERIT: /* ---------------- */
379       break;
380     case R_MEP_GNU_VTENTRY: /* ---------------- */
381       break;
382     /* MEPRELOC:END */
383     default:
384       abort ();
385     }
386
387   return r;
388 }
389 \f
390 /* Set the howto pointer for a MEP ELF reloc.  */
391
392 static void
393 mep_info_to_howto_rela
394     (bfd *               abfd ATTRIBUTE_UNUSED,
395      arelent *           cache_ptr,
396      Elf_Internal_Rela * dst)
397 {
398   unsigned int r_type;
399
400   r_type = ELF32_R_TYPE (dst->r_info);
401   cache_ptr->howto = & mep_elf_howto_table [r_type];
402 }
403
404 /* Look through the relocs for a section during the first phase.
405    Since we don't do .gots or .plts, we just need to consider the
406    virtual table relocs for gc.  */
407
408 static bfd_boolean
409 mep_elf_check_relocs
410     (bfd *                     abfd,
411      struct bfd_link_info *    info,
412      asection *                sec,
413      const Elf_Internal_Rela * relocs)
414 {
415   Elf_Internal_Shdr *           symtab_hdr;
416   struct elf_link_hash_entry ** sym_hashes;
417   struct elf_link_hash_entry ** sym_hashes_end;
418   const Elf_Internal_Rela *     rel;
419   const Elf_Internal_Rela *     rel_end;
420
421   if (info->relocatable)
422     return TRUE;
423
424   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
425   sym_hashes = elf_sym_hashes (abfd);
426   sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
427   if (!elf_bad_symtab (abfd))
428     sym_hashes_end -= symtab_hdr->sh_info;
429
430   rel_end = relocs + sec->reloc_count;
431   for (rel = relocs; rel < rel_end; rel++)
432     {
433       struct elf_link_hash_entry *h;
434       unsigned long r_symndx;
435
436       r_symndx = ELF32_R_SYM (rel->r_info);
437       if (r_symndx < symtab_hdr->sh_info)
438         h = NULL;
439       else
440         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
441     }
442   return TRUE;
443 }
444
445 \f
446 /* Relocate a MEP ELF section.
447    There is some attempt to make this function usable for many architectures,
448    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
449    if only to serve as a learning tool.
450
451    The RELOCATE_SECTION function is called by the new ELF backend linker
452    to handle the relocations for a section.
453
454    The relocs are always passed as Rela structures; if the section
455    actually uses Rel structures, the r_addend field will always be
456    zero.
457
458    This function is responsible for adjusting the section contents as
459    necessary, and (if using Rela relocs and generating a relocatable
460    output file) adjusting the reloc addend as necessary.
461
462    This function does not have to worry about setting the reloc
463    address or the reloc symbol index.
464
465    LOCAL_SYMS is a pointer to the swapped in local symbols.
466
467    LOCAL_SECTIONS is an array giving the section in the input file
468    corresponding to the st_shndx field of each local symbol.
469
470    The global hash table entry for the global symbols can be found
471    via elf_sym_hashes (input_bfd).
472
473    When generating relocatable output, this function must handle
474    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
475    going to be the section symbol corresponding to the output
476    section, which means that the addend must be adjusted
477    accordingly.  */
478
479 static bfd_boolean
480 mep_elf_relocate_section
481     (bfd *                   output_bfd ATTRIBUTE_UNUSED,
482      struct bfd_link_info *  info,
483      bfd *                   input_bfd,
484      asection *              input_section,
485      bfd_byte *              contents,
486      Elf_Internal_Rela *     relocs,
487      Elf_Internal_Sym *      local_syms,
488      asection **             local_sections)
489 {
490   Elf_Internal_Shdr *           symtab_hdr;
491   struct elf_link_hash_entry ** sym_hashes;
492   Elf_Internal_Rela *           rel;
493   Elf_Internal_Rela *           relend;
494
495   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
496   sym_hashes = elf_sym_hashes (input_bfd);
497   relend     = relocs + input_section->reloc_count;
498
499   mep_info = info;
500
501   for (rel = relocs; rel < relend; rel ++)
502     {
503       reloc_howto_type *           howto;
504       unsigned long                r_symndx;
505       Elf_Internal_Sym *           sym;
506       asection *                   sec;
507       struct elf_link_hash_entry * h;
508       bfd_vma                      relocation;
509       bfd_reloc_status_type        r;
510       const char *                 name = NULL;
511       int                          r_type;
512
513       r_type = ELF32_R_TYPE (rel->r_info);
514
515       r_symndx = ELF32_R_SYM (rel->r_info);
516
517       /* Is this a complex relocation?  */
518       if (!info->relocatable && ELF32_R_TYPE (rel->r_info) == R_RELC)
519         {
520           bfd_elf_perform_complex_relocation (output_bfd, info,
521                                               input_bfd, input_section, contents,
522                                               rel, local_syms, local_sections);
523           continue;
524         }
525
526       howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
527       h      = NULL;
528       sym    = NULL;
529       sec    = NULL;
530
531       if (r_symndx < symtab_hdr->sh_info)
532         {
533           sym = local_syms + r_symndx;
534           sec = local_sections [r_symndx];
535           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
536
537           name = bfd_elf_string_from_elf_section
538             (input_bfd, symtab_hdr->sh_link, sym->st_name);
539           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
540 #if 0
541           fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
542                    sec->name, name, sym->st_name,
543                    sec->output_section->vma, sec->output_offset,
544                    sym->st_value, rel->r_addend);
545 #endif
546         }
547       else
548         {
549           relocation = 0;
550           h = sym_hashes [r_symndx];
551
552           while (h->root.type == bfd_link_hash_indirect
553                  || h->root.type == bfd_link_hash_warning)
554             h = (struct elf_link_hash_entry *) h->root.u.i.link;
555
556           name = h->root.root.string;
557
558           if (h->root.type == bfd_link_hash_defined
559               || h->root.type == bfd_link_hash_defweak)
560             {
561               sec = h->root.u.def.section;
562               relocation = (h->root.u.def.value
563                             + sec->output_section->vma
564                             + sec->output_offset);
565 #if 0
566               fprintf (stderr,
567                        "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
568                        sec->name, name, h->root.u.def.value,
569                        sec->output_section->vma, sec->output_offset, relocation);
570 #endif
571             }
572           else if (h->root.type == bfd_link_hash_undefweak)
573             {
574 #if 0
575               fprintf (stderr, "undefined: sec: %s, name: %s\n",
576                        sec->name, name);
577 #endif
578             }
579           else if (!info->relocatable)
580             {
581               if (! ((*info->callbacks->undefined_symbol)
582                      (info, h->root.root.string, input_bfd,
583                       input_section, rel->r_offset,
584                       (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR))))
585                 return FALSE;
586 #if 0
587               fprintf (stderr, "unknown: name: %s\n", name);
588 #endif
589             }
590         }
591
592       if (sec != NULL && elf_discarded_section (sec))
593         {
594           /* For relocs against symbols from removed linkonce sections,
595              or sections discarded by a linker script, we just want the
596              section contents zeroed.  Avoid any special processing.  */
597           _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
598           rel->r_info = 0;
599           rel->r_addend = 0;
600           continue;
601         }
602
603       if (info->relocatable)
604         {
605           /* This is a relocatable link.  We don't have to change
606              anything, unless the reloc is against a section symbol,
607              in which case we have to adjust according to where the
608              section symbol winds up in the output section.  */
609           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
610             rel->r_addend += sec->output_offset;
611           continue;
612         }
613
614       switch (r_type)
615         {
616         default:
617           r = mep_final_link_relocate (howto, input_bfd, input_section,
618                                          contents, rel, relocation);
619           break;
620         }
621
622       if (r != bfd_reloc_ok)
623         {
624           const char * msg = (const char *) NULL;
625
626           switch (r)
627             {
628             case bfd_reloc_overflow:
629               r = info->callbacks->reloc_overflow
630                 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
631                  input_bfd, input_section, rel->r_offset);
632               break;
633
634             case bfd_reloc_undefined:
635               r = info->callbacks->undefined_symbol
636                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
637               break;
638
639             case bfd_reloc_outofrange:
640               msg = _("internal error: out of range error");
641               break;
642
643             case bfd_reloc_notsupported:
644               msg = _("internal error: unsupported relocation error");
645               break;
646
647             case bfd_reloc_dangerous:
648               msg = _("internal error: dangerous relocation");
649               break;
650
651             default:
652               msg = _("internal error: unknown error");
653               break;
654             }
655
656           if (msg)
657             r = info->callbacks->warning
658               (info, msg, name, input_bfd, input_section, rel->r_offset);
659
660           if (! r)
661             return FALSE;
662         }
663     }
664
665   if (warn_tp)
666     info->callbacks->undefined_symbol
667       (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
668   if (warn_sda)
669     info->callbacks->undefined_symbol
670       (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
671   if (warn_sda || warn_tp)
672     return FALSE;
673
674   return TRUE;
675 }
676 \f
677
678 /* Update the got entry reference counts for the section being
679    removed.  */
680
681 static bfd_boolean
682 mep_elf_gc_sweep_hook
683     (bfd *                     abfd ATTRIBUTE_UNUSED,
684      struct bfd_link_info *    info ATTRIBUTE_UNUSED,
685      asection *                sec ATTRIBUTE_UNUSED,
686      const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
687 {
688   return TRUE;
689 }
690
691 /* Return the section that should be marked against GC for a given
692    relocation.  */
693
694 static asection *
695 mep_elf_gc_mark_hook
696     (asection *                   sec,
697      struct bfd_link_info *       info ATTRIBUTE_UNUSED,
698      Elf_Internal_Rela *          rel,
699      struct elf_link_hash_entry * h,
700      Elf_Internal_Sym *           sym)
701 {
702   if (h != NULL)
703     {
704       switch (ELF32_R_TYPE (rel->r_info))
705         {
706         default:
707           switch (h->root.type)
708             {
709             case bfd_link_hash_defined:
710             case bfd_link_hash_defweak:
711               return h->root.u.def.section;
712
713             case bfd_link_hash_common:
714               return h->root.u.c.p->section;
715
716             default:
717               break;
718             }
719         }
720     }
721   else
722     {
723       if (!(elf_bad_symtab (sec->owner)
724             && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
725           && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
726                 && sym->st_shndx != SHN_COMMON))
727         return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
728     }
729
730   return NULL;
731 }
732
733 \f
734 /* Function to set the ELF flag bits.  */
735
736 static bfd_boolean
737 mep_elf_set_private_flags (bfd *    abfd,
738                            flagword flags)
739 {
740   elf_elfheader (abfd)->e_flags = flags;
741   elf_flags_init (abfd) = TRUE;
742   return TRUE;
743 }
744
745 static bfd_boolean
746 mep_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
747 {
748   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
749       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
750     return TRUE;
751
752   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
753   elf_flags_init (obfd) = TRUE;
754
755   /* Copy object attributes.  */
756   _bfd_elf_copy_obj_attributes (ibfd, obfd);
757
758   return TRUE;
759 }
760
761 /* Merge backend specific data from an object file to the output
762    object file when linking.  */
763
764 static bfd_boolean
765 mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
766 {
767   static bfd *last_ibfd = 0;
768   flagword old_flags, new_flags;
769   flagword old_partial, new_partial;
770
771   /* Check if we have the same endianess.  */
772   if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
773     return FALSE;
774
775   new_flags = elf_elfheader (ibfd)->e_flags;
776   old_flags = elf_elfheader (obfd)->e_flags;
777
778 #ifdef DEBUG
779   _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
780                       ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
781 #endif
782
783     /* First call, no flags set.  */
784     if (!elf_flags_init (obfd))
785     {
786       elf_flags_init (obfd) = TRUE;
787       old_flags = new_flags;
788     }
789   else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
790     {
791       /* Non-library flags trump library flags.  The choice doesn't really
792          matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set.  */
793       if (old_flags & EF_MEP_LIBRARY)
794         old_flags = new_flags;
795     }
796   else
797     {
798       /* Make sure they're for the same mach.  Allow upgrade from the "mep"
799          mach.  */
800       new_partial = (new_flags & EF_MEP_CPU_MASK);
801       old_partial = (old_flags & EF_MEP_CPU_MASK);
802       if (new_partial == old_partial)
803         ;
804       else if (new_partial == EF_MEP_CPU_MEP)
805         ;
806       else if (old_partial == EF_MEP_CPU_MEP)
807         old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
808       else
809         {
810           _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
811           bfd_set_error (bfd_error_invalid_target);
812           return FALSE;
813         }
814
815       /* Make sure they're for the same me_module.  Allow basic config to
816          mix with any other.  */
817       new_partial = (new_flags & EF_MEP_INDEX_MASK);
818       old_partial = (old_flags & EF_MEP_INDEX_MASK);
819       if (new_partial == old_partial)
820         ;
821       else if (new_partial == 0)
822         ;
823       else if (old_partial == 0)
824         old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
825       else
826         {
827           _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
828           bfd_set_error (bfd_error_invalid_target);
829           return FALSE;
830         }
831     }
832
833   elf_elfheader (obfd)->e_flags = old_flags;
834   last_ibfd = ibfd;
835   return TRUE;
836 }
837
838 /* This will be edited by the MeP configration tool.  */
839 static const char * config_names[] =
840 {
841   "basic"
842   /* start-mepcfgtool */
843   ,"simple"
844   ,"fmax"
845   /* end-mepcfgtool */
846 };
847
848 static const char * core_names[] =
849 {
850   "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
851 };
852
853 static bfd_boolean
854 mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
855 {
856   FILE *   file = (FILE *) ptr;
857   flagword flags, partial_flags;
858
859   BFD_ASSERT (abfd != NULL && ptr != NULL);
860
861   /* Print normal ELF private data.  */
862   _bfd_elf_print_private_bfd_data (abfd, ptr);
863
864   flags = elf_elfheader (abfd)->e_flags;
865   fprintf (file, _("private flags = 0x%lx"), (long)flags);
866
867   partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
868   if (partial_flags < ARRAY_SIZE (core_names))
869     fprintf (file, "  core: %s", core_names[(long)partial_flags]);
870
871   partial_flags = flags & EF_MEP_INDEX_MASK;
872   if (partial_flags < ARRAY_SIZE (config_names))
873     fprintf (file, "  me_module: %s", config_names[(long)partial_flags]);
874
875   fputc ('\n', file);
876
877   return TRUE;
878 }
879
880 /* Return the machine subcode from the ELF e_flags header.  */
881
882 static int
883 elf32_mep_machine (bfd * abfd)
884 {
885   switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
886     {
887     default: break;
888     case EF_MEP_CPU_C2: return bfd_mach_mep;
889     case EF_MEP_CPU_C3: return bfd_mach_mep;
890     case EF_MEP_CPU_C4: return bfd_mach_mep;
891     case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
892     }
893
894   return bfd_mach_mep;
895 }
896
897 static bfd_boolean
898 mep_elf_object_p (bfd * abfd)
899 {
900   /* Irix 5 and 6 is broken.  Object file symbol tables are not always
901      sorted correctly such that local symbols preceed global symbols,
902      and the sh_info field in the symbol table is not always right.  */
903   /* This is needed for the RELC support code.  */
904   elf_bad_symtab (abfd) = TRUE;
905   bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
906   return TRUE;
907 }
908
909 static bfd_boolean
910 mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
911 {
912   if (hdr->sh_flags & SHF_MEP_VLIW)
913     * flags |= SEC_MEP_VLIW;
914   return TRUE;
915 }
916
917 static bfd_boolean
918 mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
919                        Elf_Internal_Shdr * hdr,
920                        asection *          sec)
921 {
922   if (sec->flags & SEC_MEP_VLIW)
923     hdr->sh_flags |= SHF_MEP_VLIW;
924   return TRUE;
925 }
926
927 \f
928 #define ELF_ARCH                bfd_arch_mep
929 #define ELF_MACHINE_CODE        EM_CYGNUS_MEP
930 #define ELF_MAXPAGESIZE         0x1000
931
932 #define TARGET_BIG_SYM          bfd_elf32_mep_vec
933 #define TARGET_BIG_NAME         "elf32-mep"
934
935 #define TARGET_LITTLE_SYM       bfd_elf32_mep_little_vec
936 #define TARGET_LITTLE_NAME      "elf32-mep-little"
937
938 #define elf_info_to_howto_rel                   NULL
939 #define elf_info_to_howto                       mep_info_to_howto_rela
940 #define elf_backend_relocate_section            mep_elf_relocate_section
941 #define elf_backend_gc_mark_hook                mep_elf_gc_mark_hook
942 #define elf_backend_gc_sweep_hook               mep_elf_gc_sweep_hook
943 #define elf_backend_check_relocs                mep_elf_check_relocs
944 #define elf_backend_object_p                    mep_elf_object_p
945 #define elf_backend_section_flags               mep_elf_section_flags
946 #define elf_backend_fake_sections               mep_elf_fake_sections
947
948 #define elf_backend_can_gc_sections             1
949
950 #define bfd_elf32_bfd_reloc_type_lookup         mep_reloc_type_lookup
951 #define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
952 #define bfd_elf32_bfd_set_private_flags         mep_elf_set_private_flags
953 #define bfd_elf32_bfd_copy_private_bfd_data     mep_elf_copy_private_bfd_data
954 #define bfd_elf32_bfd_merge_private_bfd_data    mep_elf_merge_private_bfd_data
955 #define bfd_elf32_bfd_print_private_bfd_data    mep_elf_print_private_bfd_data
956
957 /* We use only the RELA entries.  */
958 #define USE_RELA
959
960 #include "elf32-target.h"