OSDN Git Service

* elf32-mep.c (mep_final_link_relocate) [R_MEP_HI16S]: Correctly compensate
[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       if (s & 0x8000)
337         s += 0x10000;
338       byte[2^e2] = ((s >> 24) & 0xff);
339       byte[3^e2] = ((s >> 16) & 0xff);
340       break;
341     case R_MEP_GPREL: /* ----------------fedcba9876543210 */
342       s -= mep_sdaoff_base(rel->r_offset);
343       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
344       byte[2^e2] = ((s >> 8) & 0xff);
345       byte[3^e2] = (s & 0xff);
346       break;
347     case R_MEP_TPREL: /* ----------------fedcba9876543210 */
348       s -= mep_tpoff_base(rel->r_offset);
349       if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
350       byte[2^e2] = ((s >> 8) & 0xff);
351       byte[3^e2] = (s & 0xff);
352       break;
353     case R_MEP_TPREL7: /* ---------6543210 */
354       u -= mep_tpoff_base(rel->r_offset);
355       if (u > 127) r = bfd_reloc_overflow;
356       byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
357       break;
358     case R_MEP_TPREL7A2: /* ---------654321- */
359       u -= mep_tpoff_base(rel->r_offset);
360       if (u > 127) r = bfd_reloc_overflow;
361       byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
362       break;
363     case R_MEP_TPREL7A4: /* ---------65432-- */
364       u -= mep_tpoff_base(rel->r_offset);
365       if (u > 127) r = bfd_reloc_overflow;
366       byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
367       break;
368     case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
369       if (u > 16777215) r = bfd_reloc_overflow;
370       byte[1^e2] = (u & 0xff);
371       byte[2^e2] = ((u >> 16) & 0xff);
372       byte[3^e2] = ((u >> 8) & 0xff);
373       break;
374     case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
375       if (u > 16777215) r = bfd_reloc_overflow;
376       byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
377       byte[2^e2] = ((u >> 16) & 0xff);
378       byte[3^e2] = ((u >> 8) & 0xff);
379       break;
380     case R_MEP_GNU_VTINHERIT: /* ---------------- */
381       break;
382     case R_MEP_GNU_VTENTRY: /* ---------------- */
383       break;
384     /* MEPRELOC:END */
385     default:
386       abort ();
387     }
388
389   return r;
390 }
391 \f
392 /* Set the howto pointer for a MEP ELF reloc.  */
393
394 static void
395 mep_info_to_howto_rela
396     (bfd *               abfd ATTRIBUTE_UNUSED,
397      arelent *           cache_ptr,
398      Elf_Internal_Rela * dst)
399 {
400   unsigned int r_type;
401
402   r_type = ELF32_R_TYPE (dst->r_info);
403   cache_ptr->howto = & mep_elf_howto_table [r_type];
404 }
405
406 /* Look through the relocs for a section during the first phase.
407    Since we don't do .gots or .plts, we just need to consider the
408    virtual table relocs for gc.  */
409
410 static bfd_boolean
411 mep_elf_check_relocs
412     (bfd *                     abfd,
413      struct bfd_link_info *    info,
414      asection *                sec,
415      const Elf_Internal_Rela * relocs)
416 {
417   Elf_Internal_Shdr *           symtab_hdr;
418   struct elf_link_hash_entry ** sym_hashes;
419   struct elf_link_hash_entry ** sym_hashes_end;
420   const Elf_Internal_Rela *     rel;
421   const Elf_Internal_Rela *     rel_end;
422
423   if (info->relocatable)
424     return TRUE;
425
426   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
427   sym_hashes = elf_sym_hashes (abfd);
428   sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
429   if (!elf_bad_symtab (abfd))
430     sym_hashes_end -= symtab_hdr->sh_info;
431
432   rel_end = relocs + sec->reloc_count;
433   for (rel = relocs; rel < rel_end; rel++)
434     {
435       struct elf_link_hash_entry *h;
436       unsigned long r_symndx;
437
438       r_symndx = ELF32_R_SYM (rel->r_info);
439       if (r_symndx < symtab_hdr->sh_info)
440         h = NULL;
441       else
442         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
443     }
444   return TRUE;
445 }
446
447 \f
448 /* Relocate a MEP ELF section.
449    There is some attempt to make this function usable for many architectures,
450    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
451    if only to serve as a learning tool.
452
453    The RELOCATE_SECTION function is called by the new ELF backend linker
454    to handle the relocations for a section.
455
456    The relocs are always passed as Rela structures; if the section
457    actually uses Rel structures, the r_addend field will always be
458    zero.
459
460    This function is responsible for adjusting the section contents as
461    necessary, and (if using Rela relocs and generating a relocatable
462    output file) adjusting the reloc addend as necessary.
463
464    This function does not have to worry about setting the reloc
465    address or the reloc symbol index.
466
467    LOCAL_SYMS is a pointer to the swapped in local symbols.
468
469    LOCAL_SECTIONS is an array giving the section in the input file
470    corresponding to the st_shndx field of each local symbol.
471
472    The global hash table entry for the global symbols can be found
473    via elf_sym_hashes (input_bfd).
474
475    When generating relocatable output, this function must handle
476    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
477    going to be the section symbol corresponding to the output
478    section, which means that the addend must be adjusted
479    accordingly.  */
480
481 static bfd_boolean
482 mep_elf_relocate_section
483     (bfd *                   output_bfd ATTRIBUTE_UNUSED,
484      struct bfd_link_info *  info,
485      bfd *                   input_bfd,
486      asection *              input_section,
487      bfd_byte *              contents,
488      Elf_Internal_Rela *     relocs,
489      Elf_Internal_Sym *      local_syms,
490      asection **             local_sections)
491 {
492   Elf_Internal_Shdr *           symtab_hdr;
493   struct elf_link_hash_entry ** sym_hashes;
494   Elf_Internal_Rela *           rel;
495   Elf_Internal_Rela *           relend;
496
497   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
498   sym_hashes = elf_sym_hashes (input_bfd);
499   relend     = relocs + input_section->reloc_count;
500
501   mep_info = info;
502
503   for (rel = relocs; rel < relend; rel ++)
504     {
505       reloc_howto_type *           howto;
506       unsigned long                r_symndx;
507       Elf_Internal_Sym *           sym;
508       asection *                   sec;
509       struct elf_link_hash_entry * h;
510       bfd_vma                      relocation;
511       bfd_reloc_status_type        r;
512       const char *                 name = NULL;
513       int                          r_type;
514
515       r_type = ELF32_R_TYPE (rel->r_info);
516
517       r_symndx = ELF32_R_SYM (rel->r_info);
518
519       /* Is this a complex relocation?  */
520       if (!info->relocatable && ELF32_R_TYPE (rel->r_info) == R_RELC)
521         {
522           bfd_elf_perform_complex_relocation (output_bfd, info,
523                                               input_bfd, input_section, contents,
524                                               rel, local_syms, local_sections);
525           continue;
526         }
527
528       howto  = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
529       h      = NULL;
530       sym    = NULL;
531       sec    = NULL;
532
533       if (r_symndx < symtab_hdr->sh_info)
534         {
535           sym = local_syms + r_symndx;
536           sec = local_sections [r_symndx];
537           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
538
539           name = bfd_elf_string_from_elf_section
540             (input_bfd, symtab_hdr->sh_link, sym->st_name);
541           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
542 #if 0
543           fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
544                    sec->name, name, sym->st_name,
545                    sec->output_section->vma, sec->output_offset,
546                    sym->st_value, rel->r_addend);
547 #endif
548         }
549       else
550         {
551           relocation = 0;
552           h = sym_hashes [r_symndx];
553
554           while (h->root.type == bfd_link_hash_indirect
555                  || h->root.type == bfd_link_hash_warning)
556             h = (struct elf_link_hash_entry *) h->root.u.i.link;
557
558           name = h->root.root.string;
559
560           if (h->root.type == bfd_link_hash_defined
561               || h->root.type == bfd_link_hash_defweak)
562             {
563               sec = h->root.u.def.section;
564               relocation = (h->root.u.def.value
565                             + sec->output_section->vma
566                             + sec->output_offset);
567 #if 0
568               fprintf (stderr,
569                        "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
570                        sec->name, name, h->root.u.def.value,
571                        sec->output_section->vma, sec->output_offset, relocation);
572 #endif
573             }
574           else if (h->root.type == bfd_link_hash_undefweak)
575             {
576 #if 0
577               fprintf (stderr, "undefined: sec: %s, name: %s\n",
578                        sec->name, name);
579 #endif
580             }
581           else if (!info->relocatable)
582             {
583               if (! ((*info->callbacks->undefined_symbol)
584                      (info, h->root.root.string, input_bfd,
585                       input_section, rel->r_offset,
586                       (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR))))
587                 return FALSE;
588 #if 0
589               fprintf (stderr, "unknown: name: %s\n", name);
590 #endif
591             }
592         }
593
594       if (sec != NULL && elf_discarded_section (sec))
595         {
596           /* For relocs against symbols from removed linkonce sections,
597              or sections discarded by a linker script, we just want the
598              section contents zeroed.  Avoid any special processing.  */
599           _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
600           rel->r_info = 0;
601           rel->r_addend = 0;
602           continue;
603         }
604
605       if (info->relocatable)
606         {
607           /* This is a relocatable link.  We don't have to change
608              anything, unless the reloc is against a section symbol,
609              in which case we have to adjust according to where the
610              section symbol winds up in the output section.  */
611           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
612             rel->r_addend += sec->output_offset;
613           continue;
614         }
615
616       switch (r_type)
617         {
618         default:
619           r = mep_final_link_relocate (howto, input_bfd, input_section,
620                                          contents, rel, relocation);
621           break;
622         }
623
624       if (r != bfd_reloc_ok)
625         {
626           const char * msg = (const char *) NULL;
627
628           switch (r)
629             {
630             case bfd_reloc_overflow:
631               r = info->callbacks->reloc_overflow
632                 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
633                  input_bfd, input_section, rel->r_offset);
634               break;
635
636             case bfd_reloc_undefined:
637               r = info->callbacks->undefined_symbol
638                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
639               break;
640
641             case bfd_reloc_outofrange:
642               msg = _("internal error: out of range error");
643               break;
644
645             case bfd_reloc_notsupported:
646               msg = _("internal error: unsupported relocation error");
647               break;
648
649             case bfd_reloc_dangerous:
650               msg = _("internal error: dangerous relocation");
651               break;
652
653             default:
654               msg = _("internal error: unknown error");
655               break;
656             }
657
658           if (msg)
659             r = info->callbacks->warning
660               (info, msg, name, input_bfd, input_section, rel->r_offset);
661
662           if (! r)
663             return FALSE;
664         }
665     }
666
667   if (warn_tp)
668     info->callbacks->undefined_symbol
669       (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
670   if (warn_sda)
671     info->callbacks->undefined_symbol
672       (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
673   if (warn_sda || warn_tp)
674     return FALSE;
675
676   return TRUE;
677 }
678 \f
679
680 /* Update the got entry reference counts for the section being
681    removed.  */
682
683 static bfd_boolean
684 mep_elf_gc_sweep_hook
685     (bfd *                     abfd ATTRIBUTE_UNUSED,
686      struct bfd_link_info *    info ATTRIBUTE_UNUSED,
687      asection *                sec ATTRIBUTE_UNUSED,
688      const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
689 {
690   return TRUE;
691 }
692
693 /* Return the section that should be marked against GC for a given
694    relocation.  */
695
696 static asection *
697 mep_elf_gc_mark_hook
698     (asection *                   sec,
699      struct bfd_link_info *       info ATTRIBUTE_UNUSED,
700      Elf_Internal_Rela *          rel,
701      struct elf_link_hash_entry * h,
702      Elf_Internal_Sym *           sym)
703 {
704   if (h != NULL)
705     {
706       switch (ELF32_R_TYPE (rel->r_info))
707         {
708         default:
709           switch (h->root.type)
710             {
711             case bfd_link_hash_defined:
712             case bfd_link_hash_defweak:
713               return h->root.u.def.section;
714
715             case bfd_link_hash_common:
716               return h->root.u.c.p->section;
717
718             default:
719               break;
720             }
721         }
722     }
723   else
724     {
725       if (!(elf_bad_symtab (sec->owner)
726             && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
727           && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
728                 && sym->st_shndx != SHN_COMMON))
729         return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
730     }
731
732   return NULL;
733 }
734
735 \f
736 /* Function to set the ELF flag bits.  */
737
738 static bfd_boolean
739 mep_elf_set_private_flags (bfd *    abfd,
740                            flagword flags)
741 {
742   elf_elfheader (abfd)->e_flags = flags;
743   elf_flags_init (abfd) = TRUE;
744   return TRUE;
745 }
746
747 static bfd_boolean
748 mep_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
749 {
750   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
751       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
752     return TRUE;
753
754   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
755   elf_flags_init (obfd) = TRUE;
756
757   /* Copy object attributes.  */
758   _bfd_elf_copy_obj_attributes (ibfd, obfd);
759
760   return TRUE;
761 }
762
763 /* Merge backend specific data from an object file to the output
764    object file when linking.  */
765
766 static bfd_boolean
767 mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
768 {
769   static bfd *last_ibfd = 0;
770   flagword old_flags, new_flags;
771   flagword old_partial, new_partial;
772
773   /* Check if we have the same endianess.  */
774   if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
775     return FALSE;
776
777   new_flags = elf_elfheader (ibfd)->e_flags;
778   old_flags = elf_elfheader (obfd)->e_flags;
779
780 #ifdef DEBUG
781   _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
782                       ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
783 #endif
784
785     /* First call, no flags set.  */
786     if (!elf_flags_init (obfd))
787     {
788       elf_flags_init (obfd) = TRUE;
789       old_flags = new_flags;
790     }
791   else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
792     {
793       /* Non-library flags trump library flags.  The choice doesn't really
794          matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set.  */
795       if (old_flags & EF_MEP_LIBRARY)
796         old_flags = new_flags;
797     }
798   else
799     {
800       /* Make sure they're for the same mach.  Allow upgrade from the "mep"
801          mach.  */
802       new_partial = (new_flags & EF_MEP_CPU_MASK);
803       old_partial = (old_flags & EF_MEP_CPU_MASK);
804       if (new_partial == old_partial)
805         ;
806       else if (new_partial == EF_MEP_CPU_MEP)
807         ;
808       else if (old_partial == EF_MEP_CPU_MEP)
809         old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
810       else
811         {
812           _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
813           bfd_set_error (bfd_error_invalid_target);
814           return FALSE;
815         }
816
817       /* Make sure they're for the same me_module.  Allow basic config to
818          mix with any other.  */
819       new_partial = (new_flags & EF_MEP_INDEX_MASK);
820       old_partial = (old_flags & EF_MEP_INDEX_MASK);
821       if (new_partial == old_partial)
822         ;
823       else if (new_partial == 0)
824         ;
825       else if (old_partial == 0)
826         old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
827       else
828         {
829           _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
830           bfd_set_error (bfd_error_invalid_target);
831           return FALSE;
832         }
833     }
834
835   elf_elfheader (obfd)->e_flags = old_flags;
836   last_ibfd = ibfd;
837   return TRUE;
838 }
839
840 /* This will be edited by the MeP configration tool.  */
841 static const char * config_names[] =
842 {
843   "basic"
844   /* start-mepcfgtool */
845   ,"simple"
846   ,"fmax"
847   /* end-mepcfgtool */
848 };
849
850 static const char * core_names[] =
851 {
852   "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
853 };
854
855 static bfd_boolean
856 mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
857 {
858   FILE *   file = (FILE *) ptr;
859   flagword flags, partial_flags;
860
861   BFD_ASSERT (abfd != NULL && ptr != NULL);
862
863   /* Print normal ELF private data.  */
864   _bfd_elf_print_private_bfd_data (abfd, ptr);
865
866   flags = elf_elfheader (abfd)->e_flags;
867   fprintf (file, _("private flags = 0x%lx"), (long)flags);
868
869   partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
870   if (partial_flags < ARRAY_SIZE (core_names))
871     fprintf (file, "  core: %s", core_names[(long)partial_flags]);
872
873   partial_flags = flags & EF_MEP_INDEX_MASK;
874   if (partial_flags < ARRAY_SIZE (config_names))
875     fprintf (file, "  me_module: %s", config_names[(long)partial_flags]);
876
877   fputc ('\n', file);
878
879   return TRUE;
880 }
881
882 /* Return the machine subcode from the ELF e_flags header.  */
883
884 static int
885 elf32_mep_machine (bfd * abfd)
886 {
887   switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
888     {
889     default: break;
890     case EF_MEP_CPU_C2: return bfd_mach_mep;
891     case EF_MEP_CPU_C3: return bfd_mach_mep;
892     case EF_MEP_CPU_C4: return bfd_mach_mep;
893     case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
894     }
895
896   return bfd_mach_mep;
897 }
898
899 static bfd_boolean
900 mep_elf_object_p (bfd * abfd)
901 {
902   /* Irix 5 and 6 is broken.  Object file symbol tables are not always
903      sorted correctly such that local symbols preceed global symbols,
904      and the sh_info field in the symbol table is not always right.  */
905   /* This is needed for the RELC support code.  */
906   elf_bad_symtab (abfd) = TRUE;
907   bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
908   return TRUE;
909 }
910
911 static bfd_boolean
912 mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
913 {
914   if (hdr->sh_flags & SHF_MEP_VLIW)
915     * flags |= SEC_MEP_VLIW;
916   return TRUE;
917 }
918
919 static bfd_boolean
920 mep_elf_fake_sections (bfd *               abfd ATTRIBUTE_UNUSED,
921                        Elf_Internal_Shdr * hdr,
922                        asection *          sec)
923 {
924   if (sec->flags & SEC_MEP_VLIW)
925     hdr->sh_flags |= SHF_MEP_VLIW;
926   return TRUE;
927 }
928
929 \f
930 #define ELF_ARCH                bfd_arch_mep
931 #define ELF_MACHINE_CODE        EM_CYGNUS_MEP
932 #define ELF_MAXPAGESIZE         0x1000
933
934 #define TARGET_BIG_SYM          bfd_elf32_mep_vec
935 #define TARGET_BIG_NAME         "elf32-mep"
936
937 #define TARGET_LITTLE_SYM       bfd_elf32_mep_little_vec
938 #define TARGET_LITTLE_NAME      "elf32-mep-little"
939
940 #define elf_info_to_howto_rel                   NULL
941 #define elf_info_to_howto                       mep_info_to_howto_rela
942 #define elf_backend_relocate_section            mep_elf_relocate_section
943 #define elf_backend_gc_mark_hook                mep_elf_gc_mark_hook
944 #define elf_backend_gc_sweep_hook               mep_elf_gc_sweep_hook
945 #define elf_backend_check_relocs                mep_elf_check_relocs
946 #define elf_backend_object_p                    mep_elf_object_p
947 #define elf_backend_section_flags               mep_elf_section_flags
948 #define elf_backend_fake_sections               mep_elf_fake_sections
949
950 #define elf_backend_can_gc_sections             1
951
952 #define bfd_elf32_bfd_reloc_type_lookup         mep_reloc_type_lookup
953 #define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
954 #define bfd_elf32_bfd_set_private_flags         mep_elf_set_private_flags
955 #define bfd_elf32_bfd_copy_private_bfd_data     mep_elf_copy_private_bfd_data
956 #define bfd_elf32_bfd_merge_private_bfd_data    mep_elf_merge_private_bfd_data
957 #define bfd_elf32_bfd_print_private_bfd_data    mep_elf_print_private_bfd_data
958
959 /* We use only the RELA entries.  */
960 #define USE_RELA
961
962 #include "elf32-target.h"