]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf32-mep.c
Switch sources over to use the GPL version 3
[thirdparty/binutils-gdb.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"