1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "sysdep.h"
25: #include "bfd.h"
26: #include "libbfd.h"
27:
28: #include "coff/i860.h"
29:
30: #include "coff/internal.h"
31:
32: #include "libcoff.h"
33:
34:
35: #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
36:
37:
38: #define COFF_PAGE_SIZE 0x1000
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49: static bfd_reloc_status_type
50: coff_i860_reloc (bfd *abfd,
51: arelent *reloc_entry,
52: asymbol *symbol,
53: void *data,
54: asection *input_section ATTRIBUTE_UNUSED,
55: bfd *output_bfd,
56: char **error_message ATTRIBUTE_UNUSED)
57: {
58: symvalue diff;
59:
60: if (output_bfd == (bfd *) NULL)
61: return bfd_reloc_continue;
62:
63: if (bfd_is_com_section (symbol->section))
64: {
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76: diff = symbol->value + reloc_entry->addend;
77: }
78: else
79: {
80:
81:
82:
83:
84: diff = reloc_entry->addend;
85: }
86:
87: #define DOIT(x) \
88: x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
89:
90: if (diff != 0)
91: {
92: reloc_howto_type *howto = reloc_entry->howto;
93: unsigned char *addr = (unsigned char *) data + reloc_entry->address;
94:
95: switch (howto->size)
96: {
97: case 0:
98: {
99: char x = bfd_get_8 (abfd, addr);
100: DOIT (x);
101: bfd_put_8 (abfd, x, addr);
102: }
103: break;
104:
105: case 1:
106: {
107: short x = bfd_get_16 (abfd, addr);
108: DOIT (x);
109: bfd_put_16 (abfd, (bfd_vma) x, addr);
110: }
111: break;
112:
113: case 2:
114: {
115: long x = bfd_get_32 (abfd, addr);
116: DOIT (x);
117: bfd_put_32 (abfd, (bfd_vma) x, addr);
118: }
119: break;
120:
121: default:
122: abort ();
123: }
124: }
125:
126:
127: return bfd_reloc_continue;
128: }
129:
130:
131:
132:
133: static bfd_reloc_status_type
134: coff_i860_reloc_nyi (bfd *abfd ATTRIBUTE_UNUSED,
135: arelent *reloc_entry,
136: asymbol *symbol ATTRIBUTE_UNUSED,
137: void *data ATTRIBUTE_UNUSED,
138: asection *input_section ATTRIBUTE_UNUSED,
139: bfd *output_bfd ATTRIBUTE_UNUSED,
140: char **error_message ATTRIBUTE_UNUSED)
141: {
142: reloc_howto_type *howto = reloc_entry->howto;
143: fprintf (stderr, _("Relocation `%s' not yet implemented\n"), howto->name);
144: return bfd_reloc_notsupported;
145: }
146:
147: #ifndef PCRELOFFSET
148: #define PCRELOFFSET FALSE
149: #endif
150:
151: static reloc_howto_type howto_table[] =
152: {
153: EMPTY_HOWTO (0),
154: EMPTY_HOWTO (1),
155: EMPTY_HOWTO (2),
156: EMPTY_HOWTO (3),
157: EMPTY_HOWTO (4),
158: EMPTY_HOWTO (5),
159: HOWTO (R_DIR32,
160: 0,
161: 2,
162: 32,
163: FALSE,
164: 0,
165: complain_overflow_bitfield,
166: coff_i860_reloc,
167: "dir32",
168: TRUE,
169: 0xffffffff,
170: 0xffffffff,
171: TRUE),
172:
173: HOWTO (R_IMAGEBASE,
174: 0,
175: 2,
176: 32,
177: FALSE,
178: 0,
179: complain_overflow_bitfield,
180: coff_i860_reloc,
181: "rva32",
182: TRUE,
183: 0xffffffff,
184: 0xffffffff,
185: FALSE),
186: EMPTY_HOWTO (010),
187: EMPTY_HOWTO (011),
188: EMPTY_HOWTO (012),
189: EMPTY_HOWTO (013),
190: EMPTY_HOWTO (014),
191: EMPTY_HOWTO (015),
192: EMPTY_HOWTO (016),
193: HOWTO (R_RELBYTE,
194: 0,
195: 0,
196: 8,
197: FALSE,
198: 0,
199: complain_overflow_bitfield,
200: coff_i860_reloc,
201: "8",
202: TRUE,
203: 0x000000ff,
204: 0x000000ff,
205: PCRELOFFSET),
206: HOWTO (R_RELWORD,
207: 0,
208: 1,
209: 16,
210: FALSE,
211: 0,
212: complain_overflow_bitfield,
213: coff_i860_reloc,
214: "16",
215: TRUE,
216: 0x0000ffff,
217: 0x0000ffff,
218: PCRELOFFSET),
219: HOWTO (R_RELLONG,
220: 0,
221: 2,
222: 32,
223: FALSE,
224: 0,
225: complain_overflow_bitfield,
226: coff_i860_reloc,
227: "32",
228: TRUE,
229: 0xffffffff,
230: 0xffffffff,
231: PCRELOFFSET),
232: HOWTO (R_PCRBYTE,
233: 0,
234: 0,
235: 8,
236: TRUE,
237: 0,
238: complain_overflow_signed,
239: coff_i860_reloc,
240: "DISP8",
241: TRUE,
242: 0x000000ff,
243: 0x000000ff,
244: PCRELOFFSET),
245: HOWTO (R_PCRWORD,
246: 0,
247: 1,
248: 16,
249: TRUE,
250: 0,
251: complain_overflow_signed,
252: coff_i860_reloc,
253: "DISP16",
254: TRUE,
255: 0x0000ffff,
256: 0x0000ffff,
257: PCRELOFFSET),
258: HOWTO (R_PCRLONG,
259: 0,
260: 2,
261: 32,
262: TRUE,
263: 0,
264: complain_overflow_signed,
265: coff_i860_reloc,
266: "DISP32",
267: TRUE,
268: 0xffffffff,
269: 0xffffffff,
270: PCRELOFFSET),
271: EMPTY_HOWTO (0x15),
272: EMPTY_HOWTO (0x16),
273: EMPTY_HOWTO (0x17),
274: EMPTY_HOWTO (0x18),
275: EMPTY_HOWTO (0x19),
276: EMPTY_HOWTO (0x1a),
277: EMPTY_HOWTO (0x1b),
278: HOWTO (COFF860_R_PAIR,
279: 0,
280: 2,
281: 16,
282: FALSE,
283: 0,
284: complain_overflow_dont,
285: coff_i860_reloc_nyi,
286: "PAIR",
287: FALSE,
288: 0xffff,
289: 0xffff,
290: FALSE),
291: EMPTY_HOWTO (0x1d),
292: HOWTO (COFF860_R_HIGH,
293: 16,
294: 2,
295: 16,
296: FALSE,
297: 0,
298: complain_overflow_dont,
299: coff_i860_reloc,
300: "HIGH",
301: FALSE,
302: 0xffff,
303: 0xffff,
304: FALSE),
305: HOWTO (COFF860_R_LOW0,
306: 0,
307: 2,
308: 16,
309: FALSE,
310: 0,
311: complain_overflow_dont,
312: coff_i860_reloc,
313: "LOW0",
314: FALSE,
315: 0xffff,
316: 0xffff,
317: FALSE),
318: HOWTO (COFF860_R_LOW1,
319: 0,
320: 2,
321: 16,
322: FALSE,
323: 0,
324: complain_overflow_dont,
325: coff_i860_reloc,
326: "LOW1",
327: FALSE,
328: 0xfffe,
329: 0xfffe,
330: FALSE),
331: HOWTO (COFF860_R_LOW2,
332: 0,
333: 2,
334: 16,
335: FALSE,
336: 0,
337: complain_overflow_dont,
338: coff_i860_reloc,
339: "LOW2",
340: FALSE,
341: 0xfffc,
342: 0xfffc,
343: FALSE),
344: HOWTO (COFF860_R_LOW3,
345: 0,
346: 2,
347: 16,
348: FALSE,
349: 0,
350: complain_overflow_dont,
351: coff_i860_reloc,
352: "LOW3",
353: FALSE,
354: 0xfff8,
355: 0xfff8,
356: FALSE),
357: HOWTO (COFF860_R_LOW4,
358: 0,
359: 2,
360: 16,
361: FALSE,
362: 0,
363: complain_overflow_dont,
364: coff_i860_reloc,
365: "LOW4",
366: FALSE,
367: 0xfff0,
368: 0xfff0,
369: FALSE),
370: HOWTO (COFF860_R_SPLIT0,
371: 0,
372: 2,
373: 16,
374: FALSE,
375: 0,
376: complain_overflow_dont,
377: coff_i860_reloc_nyi,
378: "SPLIT0",
379: FALSE,
380: 0x1f07ff,
381: 0x1f07ff,
382: FALSE),
383: HOWTO (COFF860_R_SPLIT1,
384: 0,
385: 2,
386: 16,
387: FALSE,
388: 0,
389: complain_overflow_dont,
390: coff_i860_reloc_nyi,
391: "SPLIT1",
392: FALSE,
393: 0x1f07fe,
394: 0x1f07fe,
395: FALSE),
396: HOWTO (COFF860_R_SPLIT2,
397: 0,
398: 2,
399: 16,
400: FALSE,
401: 0,
402: complain_overflow_dont,
403: coff_i860_reloc_nyi,
404: "SPLIT2",
405: FALSE,
406: 0x1f07fc,
407: 0x1f07fc,
408: FALSE),
409: HOWTO (COFF860_R_HIGHADJ,
410: 0,
411: 2,
412: 16,
413: FALSE,
414: 0,
415: complain_overflow_dont,
416: coff_i860_reloc_nyi,
417: "HIGHADJ",
418: FALSE,
419: 0xffff,
420: 0xffff,
421: FALSE),
422: HOWTO (COFF860_R_BRADDR,
423: 2,
424: 2,
425: 26,
426: TRUE,
427: 0,
428: complain_overflow_bitfield,
429: coff_i860_reloc_nyi,
430: "BRADDR",
431: FALSE,
432: 0x3ffffff,
433: 0x3ffffff,
434: TRUE)
435: };
436:
437:
438:
439: #define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
440: #define BADMAG(x) I860BADMAG(x)
441: #define I860 1
442:
443: #define RTYPE2HOWTO(cache_ptr, dst) \
444: ((cache_ptr)->howto = \
445: ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \
446: ? howto_table + (dst)->r_type \
447: : NULL))
448:
449:
450:
451:
452: #define BSS_NOLOAD_IS_SHARED_LIBRARY
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467: #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)
468:
469:
470: #define coff_relocate_section _bfd_coff_generic_relocate_section
471:
472: static reloc_howto_type *
473: coff_i860_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
474: asection *sec,
475: struct internal_reloc *rel,
476: struct coff_link_hash_entry *h,
477: struct internal_syment *sym,
478: bfd_vma *addendp)
479: {
480:
481: reloc_howto_type *howto;
482:
483: if (rel->r_type > sizeof (howto_table) / sizeof (howto_table[0]))
484: {
485: bfd_set_error (bfd_error_bad_value);
486: return NULL;
487: }
488:
489: howto = howto_table + rel->r_type;
490:
491: if (howto->pc_relative)
492: *addendp += sec->vma;
493:
494: if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
495: {
496:
497:
498:
499:
500:
501:
502: BFD_ASSERT (h != NULL);
503:
504:
505:
506:
507:
508:
509:
510: *addendp -= sym->n_value;
511: }
512:
513:
514:
515:
516: if (h != NULL && h->root.type == bfd_link_hash_common)
517: *addendp += h->root.u.c.size;
518:
519: return howto;
520: }
521:
522: static reloc_howto_type *
523: coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
524: bfd_reloc_code_real_type code)
525: {
526: switch (code)
527: {
528: case BFD_RELOC_32:
529: return howto_table + R_DIR32;
530: case BFD_RELOC_860_PC26:
531: return howto_table + COFF860_R_BRADDR;
532: case BFD_RELOC_860_PC16:
533:
534: return howto_table + COFF860_R_SPLIT0;
535: case BFD_RELOC_860_LOW0:
536: return howto_table + COFF860_R_LOW0;
537: case BFD_RELOC_860_SPLIT0:
538: return howto_table + COFF860_R_SPLIT0;
539: case BFD_RELOC_860_LOW1:
540: return howto_table + COFF860_R_LOW1;
541: case BFD_RELOC_860_SPLIT1:
542: return howto_table + COFF860_R_SPLIT1;
543: case BFD_RELOC_860_LOW2:
544: return howto_table + COFF860_R_LOW2;
545: case BFD_RELOC_860_SPLIT2:
546: return howto_table + COFF860_R_SPLIT2;
547: case BFD_RELOC_860_LOW3:
548: return howto_table + COFF860_R_LOW3;
549: case BFD_RELOC_860_HIGHADJ:
550: return howto_table + COFF860_R_HIGHADJ;
551: case BFD_RELOC_860_HIGH:
552: return howto_table + COFF860_R_HIGH;
553: default:
554: BFD_FAIL ();
555: return 0;
556: }
557: }
558:
559: static reloc_howto_type *
560: coff_i860_reloc_name_lookup (bfd