* elf32-mep.c (mep_final_link_relocate) [R_MEP_HI16S]: Correctly compensate
[deliverable/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 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"
This page took 0.049981 seconds and 5 git commands to generate.