1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include "sysdep.h"
23: #include "bfd.h"
24: #include "libbfd.h"
25: #include "coff/mcore.h"
26: #include "coff/internal.h"
27: #include "coff/pe.h"
28: #include "libcoff.h"
29:
30: #ifdef BADMAG
31: #undef BADMAG
32: #endif
33: #define BADMAG(x) MCOREBADMAG(x)
34:
35: #ifndef NUM_ELEM
36: #define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
37: #endif
38:
39:
40:
41: extern bfd_boolean mcore_bfd_coff_final_link
42: PARAMS ((bfd *, struct bfd_link_info *));
43: static bfd_reloc_status_type mcore_coff_unsupported_reloc
44: PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
45: static bfd_boolean coff_mcore_relocate_section
46: PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
47: struct internal_reloc *, struct internal_syment *, asection **));
48: static reloc_howto_type *mcore_coff_reloc_type_lookup
49: PARAMS ((bfd *, bfd_reloc_code_real_type));
50: static reloc_howto_type *coff_mcore_rtype_to_howto
51: PARAMS ((bfd *, asection *, struct internal_reloc *,
52: struct coff_link_hash_entry *, struct internal_syment *,
53: bfd_vma *));
54: static void mcore_emit_base_file_entry
55: PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_vma));
56: static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
57: ^L
58:
59:
60:
61: #define TOC_LOAD_ADJUSTMENT (-32768)
62: #define TOC_SECTION_NAME ".private.toc"
63:
64:
65: #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
66:
67:
68:
69: #define MINUS_ONE (((bfd_vma)0) - 1)
70: ^L
71: static reloc_howto_type mcore_coff_howto_table[] =
72: {
73:
74: HOWTO (IMAGE_REL_MCORE_ABSOLUTE,
75: 0,
76: 0,
77: 0,
78: FALSE,
79: 0,
80: complain_overflow_dont,
81: NULL,
82: "ABSOLUTE",
83: FALSE,
84: 0x00,
85: 0x00,
86: FALSE),
87:
88: HOWTO (IMAGE_REL_MCORE_ADDR32,
89: 0,
90: 2,
91: 32,
92: FALSE,
93: 0,
94: complain_overflow_bitfield,
95: NULL,
96: "ADDR32",
97: TRUE,
98: 0xffffffff,
99: 0xffffffff,
100: FALSE),
101:
102:
103:
104: HOWTO (IMAGE_REL_MCORE_PCREL_IMM8BY4,
105: 2,
106: 1,
107: 8,
108: TRUE,
109: 0,
110: complain_overflow_bitfield,
111: mcore_coff_unsupported_reloc,
112: "IMM8BY4",
113: FALSE,
114: 0,
115: 0,
116: TRUE),
117:
118:
119:
120:
121: HOWTO (IMAGE_REL_MCORE_PCREL_IMM11BY2,
122: 1,
123: 1,
124: 11,
125: TRUE,
126: 0,
127: complain_overflow_signed,
128: NULL,
129: "IMM11BY2",
130: FALSE,
131: 0x0,
132: 0x7ff,
133: TRUE),
134:
135:
136: HOWTO (IMAGE_REL_MCORE_PCREL_IMM4BY2,
137: 1,
138: 1,
139: 4,
140: TRUE,
141: 0,
142: complain_overflow_bitfield,
143: mcore_coff_unsupported_reloc,
144: "IMM4BY2",
145: FALSE,
146: 0,
147: 0,
148: TRUE),
149:
150:
151: HOWTO (IMAGE_REL_MCORE_PCREL_32,
152: 0,
153: 2,
154: 32,
155: TRUE,
156: 0,
157: complain_overflow_bitfield,
158: NULL,
159: "PCREL_32",
160: FALSE,
161: 0x0,
162: 0xffffffff,
163: TRUE),
164:
165:
166:
167:
168:
169:
170:
171:
172: HOWTO (IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2,
173: 1,
174: 1,
175: 11,
176: TRUE,
177: 0,
178: complain_overflow_signed,
179: NULL,
180: "JSR_IMM11BY2",
181: FALSE,
182: 0x0,
183: 0x7ff,
184: TRUE),
185:
186: HOWTO (IMAGE_REL_MCORE_RVA,
187: 0,
188: 2,
189: 32,
190: FALSE,
191: 0,
192: complain_overflow_signed,
193: NULL,
194: "MCORE_RVA",
195: TRUE,
196: 0xffffffff,
197: 0xffffffff,
198: TRUE)
199: };
200: ^L
201:
202:
203:
204: typedef struct coff_mcore_link_hash_table
205: {
206:
207: struct coff_link_hash_table root;
208:
209: bfd * bfd_of_toc_owner;
210: long int global_toc_size;
211: long int import_table_size;
212: long int first_thunk_address;
213: long int thunk_size;
214: }
215: mcore_hash_table;
216:
217:
218: #define coff_mcore_hash_table(info) \
219: ((mcore_hash_table *) ((info)->hash))
220:
221: ^L
222:
223:
224: static void
225: mcore_emit_base_file_entry (info, output_bfd, input_section, reloc_offset)
226: struct bfd_link_info * info;
227: bfd * output_bfd;
228: asection * input_section;
229: bfd_vma reloc_offset;
230: {
231: bfd_vma addr = reloc_offset
232: - input_section->vma
233: + input_section->output_offset
234: + input_section->output_section->vma;
235:
236: if (coff_data (output_bfd)->pe)
237: addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
238:
239: fwrite (&addr, 1, sizeof (addr), (FILE *) info->base_file);
240: }
241: ^L
242: static bfd_reloc_status_type
243: mcore_coff_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
244: output_bfd, error_message)
245: bfd * abfd;
246: arelent * reloc_entry;
247: asymbol * symbol ATTRIBUTE_UNUSED;
248: PTR data ATTRIBUTE_UNUSED;
249: asection * input_section ATTRIBUTE_UNUSED;
250: bfd * output_bfd ATTRIBUTE_UNUSED;
251: char ** error_message ATTRIBUTE_UNUSED;
252: {
253: BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
254:
255: _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
256: abfd,
257: reloc_entry->howto->name,
258: reloc_entry->howto->type);
259:
260: return bfd_reloc_notsupported;
261: }
262: ^L
263:
264: #define HOW2MAP(bfd_rtype, mcore_rtype) \
265: case bfd_rtype: return & mcore_coff_howto_table [mcore_rtype]
266:
267: static reloc_howto_type *
268: mcore_coff_reloc_type_lookup (abfd, code)
269: bfd * abfd ATTRIBUTE_UNUSED;
270: bfd_reloc_code_real_type code;
271: {
272: switch (code)
273: {
274: HOW2MAP (BFD_RELOC_32, IMAGE_REL_MCORE_ADDR32);
275: HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM8BY4, IMAGE_REL_MCORE_PCREL_IMM8BY4);
276: HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM11BY2, IMAGE_REL_MCORE_PCREL_IMM11BY2);
277: HOW2MAP (BFD_RELOC_MCORE_PCREL_IMM4BY2, IMAGE_REL_MCORE_PCREL_IMM4BY2);
278: HOW2MAP (BFD_RELOC_32_PCREL, IMAGE_REL_MCORE_PCREL_32);
279: HOW2MAP (BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2);
280: HOW2MAP (BFD_RELOC_RVA, IMAGE_REL_MCORE_RVA);
281: default:
282: return NULL;
283: }
284:
285: }
286: #undef HOW2MAP
287:
288: static reloc_howto_type *
289: mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
290: const char *r_name)
291: {
292: unsigned int i;
293:
294: for (i = 0;
295: i < (sizeof (mcore_coff_howto_table)
296: / sizeof (mcore_coff_howto_table[0]));
297: i++)
298: if (mcore_coff_howto_table[i].name != NULL
299: && strcasecmp (mcore_coff_howto_table[i].name, r_name) == 0)
300: return &mcore_coff_howto_table[i];
301:
302: return NULL;
303: }
304:
305: #define RTYPE2HOWTO(cache_ptr, dst) \
306: (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
307:
308: static reloc_howto_type *
309: coff_mcore_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
310: bfd * abfd ATTRIBUTE_UNUSED;
311: asection * sec;
312: struct internal_reloc * rel;
313: struct coff_link_hash_entry * h ATTRIBUTE_UNUSED;
314: struct internal_syment * sym;
315: bfd_vma * addendp;
316: {
317: reloc_howto_type * howto;
318:
319: if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
320: return NULL;
321:
322: howto = mcore_coff_howto_table + rel->r_type;
323:
324: if (rel->r_type == IMAGE_REL_MCORE_RVA)
325: * addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
326:
327: else if (howto->pc_relative)
328: {
329: * addendp = sec->vma - 2;
330:
331:
332:
333:
334:
335:
336:
337: if (sym != NULL && sym->n_scnum != 0)
338: * addendp -= sym->n_value;
339: }
340: else
341: * addendp = 0;
342:
343: return howto;
344: }
345:
346:
347:
348:
349: static bfd_boolean
350: in_reloc_p (abfd, howto)
351: bfd * abfd ATTRIBUTE_UNUSED;
352: reloc_howto_type * howto;
353: {
354: return ! howto->pc_relative && howto->type != IMAGE_REL_MCORE_RVA;
355: }
356: ^L
357:
358: static bfd_boolean
359: coff_mcore_relocate_section (output_bfd, info, input_bfd, input_section,
360: contents, relocs, syms, sections)
361: bfd * output_bfd;
362: struct bfd_link_info * info;
363: bfd * input_bfd;
364: asection * input_section;
365: bfd_byte * contents;
366: struct internal_reloc * relocs;
367: struct internal_syment * syms;
368: asection ** sections;
369: {
370: struct internal_reloc * rel;
371: struct internal_reloc * relend;
372: bfd_boolean hihalf;
373: bfd_vma hihalf_val;
374:
375:
376:
377:
378: if (info->relocatable)
379: return TRUE;
380:
381:
382: if ( input_bfd->xvec->byteorder != output_bfd->xvec->byteorder
383: && output_bfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
384: {
385: (*_bfd_error_handler)
386: (_("%B: compiled for a %s system and target is %s.\n"),
387: input_bfd,
388: bfd_big_endian (input_bfd) ? _("big endian") : _("little endian"),
389: bfd_big_endian (output_bfd) ? _("big endian") : _("little endian"));
390:
391: bfd_set_error (bfd_error_wrong_format);
392: return FALSE;
393: }
394:
395: hihalf = FALSE;
396: hihalf_val = 0;
397:
398: rel = relocs;
399: relend = rel + input_section->reloc_count;
400:
401: for (; rel < relend; rel++)
402: {
403: long symndx;
404: struct internal_syment * sym;
405: bfd_vma val;
406: bfd_vma addend;
407: bfd_reloc_status_type rstat;
408: bfd_byte * loc;
409: unsigned short r_type = rel->r_type;
410: reloc_howto_type * howto = NULL;
411: struct coff_link_hash_entry * h;
412: const char * my_name;
413:
414: symndx = rel->r_symndx;
415: loc = contents + rel->r_vaddr - input_section->vma;
416:
417: if (symndx == -1)
418: {
419: h = NULL;
420: sym = NULL;
421: }
422: else
423: {
424: h = obj_coff_sym_hashes (input_bfd)[symndx];
425: sym = syms + symndx;
426: }
427:
428: addend = 0;
429:
430:
431: howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
432: sym, & addend);
433: if (howto == NULL)
434: return FALSE;
435:
436: val = 0;
437:
438: if (h == NULL)
439: {
440: if (symndx == -1)
441: my_name = "*ABS*";
442: else
443: {
444: asection * sec = sections[symndx];
445:
446: val = (sym->n_value
447: + sec->output_section->vma
448: + sec->output_offset);
449:
450: if (sym == NULL)
451: my_name = "*unknown*";
452: else if ( sym->_n._n_n._n_zeroes == 0
453: && sym->_n._n_n._n_offset != 0)
454: my_name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;
455: else
456: {
457: static char buf [SYMNMLEN + 1];
458:
459: strncpy (buf, sym->_n._n_name, SYMNMLEN);
460: buf[SYMNMLEN] = '\0';
461: my_name = buf;
462: }
463: }
464: }
465: else
466: {
467: if ( h->root.type == bfd_link_hash_defined
468: || h->root.type == bfd_link_hash_defweak)
469: {
470: asection * sec = h->root.u.def.section;
471:
472: val = (h->root.u.def.value
473: + sec->output_section->vma
474: + sec->output_offset);
475: }
476: else
477: {
478: if (! ((*info->callbacks->undefined_symbol)
479: (info, h->root.root.string, input_bfd, input_section,
480: rel->r_vaddr - input_section->vma, TRUE)))
481: return FALSE;
482: }
483:
484: my_name = h->root.root.string;
485: }
486:
487: rstat = bfd_reloc_ok;
488:
489:
490: switch (r_type)
491: {
492: default:
493: _bfd_error_handler (_("%B: unsupported relocation type 0x%02x"),
494: input_bfd, r_type);
495: bfd_set_error (bfd_error_bad_value);
496: return FALSE;
497:
498: case IMAGE_REL_MCORE_ABSOLUTE:
499: _bfd_error_handler
500: (_("Warning: unsupported reloc %s <file %B, section %A>\n"
501: "sym %ld (%s), r_vaddr %ld (%lx)"),
502: input_bfd, input_section, howto->name,
503: rel->r_symndx, my_name, (long) rel->r_vaddr,
504: (unsigned long) rel->r_vaddr);
505: break;
506:
507: case IMAGE_REL_MCORE_PCREL_IMM8BY4:
508: case IMAGE_REL_MCORE_PCREL_IMM11BY2:
509: case IMAGE_REL_MCORE_PCREL_IMM4BY2:
510: case IMAGE_REL_MCORE_PCREL_32:
511: case IMAGE_REL_MCORE_PCREL_JSR_IMM11BY2:
512: case IMAGE_REL_MCORE_ADDR32:
513:
514: rstat = _bfd_relocate_contents (howto, input_bfd, val, loc);
515: break;
516:
517: case IMAGE_REL_MCORE_RVA:
518: rstat = _bfd_final_link_relocate
519: (howto, input_bfd,
520: input_section, contents, rel->r_vaddr - input_section->vma,
521: val, addend);
522: break;
523: }
524:
525: if (info->base_file)
526: {
527:
528: if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto))
529: mcore_emit_base_file_entry (info, output_bfd, input_section, rel->r_vaddr);
530: }
531:
532: switch (rstat)
533: {
534: default:
535: abort ();
536:
537: case bfd_reloc_ok:
538: break;
539:
540: case bfd_reloc_overflow:
541: if (! ((*info->callbacks->reloc_overflow)
542: (info, (h ? &h->root : NULL), my_name, howto->name,
543: (bfd_vma) 0, input_bfd,
544: input_section, rel->r_vaddr - input_section->vma)))
545: return FALSE;
546: }
547: }
548:
549: return TRUE;
550: }
551: ^L
552:
553:
554:
555:
556: #define coff_bfd_reloc_type_lookup mcore_coff_reloc_type_lookup
557: #define coff_bfd_reloc_name_lookup mcore_coff_reloc_name_lookup
558: #define coff_relocate_section coff_mcore_relocate_section
559: #define coff_rtype_to_howto