1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #include "sysdep.h"
24: #include "bfd.h"
25: #include "libbfd.h"
26: #include "bfdlink.h"
27: #include "coff/tic54x.h"
28: #include "coff/internal.h"
29: #include "libcoff.h"
30:
31: #undef F_LSYMS
32: #define F_LSYMS F_LSYMS_TICOFF
33:
34: static void tic54x_reloc_processing
35: PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
36: static bfd_reloc_status_type tic54x_relocation
37: PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
38: static bfd_boolean tic54x_set_section_contents
39: PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type));
40: static reloc_howto_type *coff_tic54x_rtype_to_howto
41: PARAMS ((bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *));
42: static bfd_boolean tic54x_set_arch_mach
43: PARAMS ((bfd *, enum bfd_architecture, unsigned long));
44: static reloc_howto_type * tic54x_coff_reloc_type_lookup
45: PARAMS ((bfd *, bfd_reloc_code_real_type));
46: static void tic54x_lookup_howto
47: PARAMS ((arelent *, struct internal_reloc *));
48: static bfd_boolean ticoff_bfd_is_local_label_name
49: PARAMS ((bfd *, const char *));
50:
51:
52:
53:
54:
55:
56:
57:
58: static bfd_vma
59: tic54x_getl32 (const void *p)
60: {
61: const bfd_byte *addr = p;
62: unsigned long v;
63:
64: v = (unsigned long) addr[2];
65: v |= (unsigned long) addr[3] << 8;
66: v |= (unsigned long) addr[0] << 16;
67: v |= (unsigned long) addr[1] << 24;
68: return v;
69: }
70:
71: static void
72: tic54x_putl32 (bfd_vma data, void *p)
73: {
74: bfd_byte *addr = p;
75: addr[2] = data & 0xff;
76: addr[3] = (data >> 8) & 0xff;
77: addr[0] = (data >> 16) & 0xff;
78: addr[1] = (data >> 24) & 0xff;
79: }
80:
81: static bfd_signed_vma
82: tic54x_getl_signed_32 (const void *p)
83: {
84: const bfd_byte *addr = p;
85: unsigned long v;
86:
87: v = (unsigned long) addr[2];
88: v |= (unsigned long) addr[3] << 8;
89: v |= (unsigned long) addr[0] << 16;
90: v |= (unsigned long) addr[1] << 24;
91: #define COERCE32(x) \
92: ((bfd_signed_vma) (long) (((unsigned long) (x) ^ 0x80000000) - 0x80000000))
93: return COERCE32 (v);
94: }
95:
96: #define coff_get_section_load_page bfd_ticoff_get_section_load_page
97: #define coff_set_section_load_page bfd_ticoff_set_section_load_page
98:
99: void
100: bfd_ticoff_set_section_load_page (sect, page)
101: asection *sect;
102: int page;
103: {
104: sect->lma = (sect->lma & ADDR_MASK) | PG_TO_FLAG(page);
105: }
106:
107: int
108: bfd_ticoff_get_section_load_page (sect)
109: asection *sect;
110: {
111: int page;
112:
113:
114: if (sect == &bfd_com_section)
115: page = PG_DATA;
116:
117: else if (sect == &bfd_und_section
118: || sect == &bfd_abs_section
119: || sect == &bfd_ind_section)
120: page = PG_PROG;
121:
122: else
123: page = FLAG_TO_PG (sect->lma);
124:
125: return page;
126: }
127:
128:
129:
130:
131: static bfd_boolean
132: tic54x_set_arch_mach (abfd, arch, machine)
133: bfd *abfd;
134: enum bfd_architecture arch;
135: unsigned long machine;
136: {
137: if (arch == bfd_arch_unknown)
138: arch = bfd_arch_tic54x;
139:
140: else if (arch != bfd_arch_tic54x)
141: return FALSE;
142:
143: return bfd_default_set_arch_mach (abfd, arch, machine);
144: }
145:
146: static bfd_reloc_status_type
147: tic54x_relocation (abfd, reloc_entry, symbol, data, input_section,
148: output_bfd, error_message)
149: bfd *abfd ATTRIBUTE_UNUSED;
150: arelent *reloc_entry;
151: asymbol *symbol ATTRIBUTE_UNUSED;
152: PTR data ATTRIBUTE_UNUSED;
153: asection *input_section;
154: bfd *output_bfd;
155: char **error_message ATTRIBUTE_UNUSED;
156: {
157: if (output_bfd != (bfd *) NULL)
158: {
159:
160:
161:
162: reloc_entry->address += input_section->output_offset;
163: return bfd_reloc_ok;
164: }
165: return bfd_reloc_continue;
166: }
167:
168: reloc_howto_type tic54x_howto_table[] =
169: {
170:
171:
172:
173:
174:
175:
176: HOWTO (R_RELWORD,0,1,16,FALSE,0,complain_overflow_dont,
177: tic54x_relocation,"REL16",FALSE,0xFFFF,0xFFFF,FALSE),
178:
179:
180: HOWTO (R_PARTLS7,0,1,7,FALSE,0,complain_overflow_dont,
181: tic54x_relocation,"LS7",FALSE,0x007F,0x007F,FALSE),
182:
183:
184:
185: HOWTO (R_PARTMS9,7,1,9,FALSE,0,complain_overflow_dont,
186: tic54x_relocation,"MS9",FALSE,0x01FF,0x01FF,FALSE),
187:
188:
189: HOWTO (R_EXTWORD,0,2,23,FALSE,0,complain_overflow_dont,
190: tic54x_relocation,"RELEXT",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
191:
192:
193: HOWTO (R_EXTWORD16,0,1,16,FALSE,0,complain_overflow_dont,
194: tic54x_relocation,"RELEXT16",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
195:
196:
197: HOWTO (R_EXTWORDMS7,16,1,7,FALSE,0,complain_overflow_dont,
198: tic54x_relocation,"RELEXTMS7",FALSE,0x7F,0x7F,FALSE),
199:
200:
201:
202: HOWTO (R_RELWORD,0,1,16,FALSE,0,complain_overflow_dont,
203: tic54x_relocation,"AREL16",FALSE,0xFFFF,0xFFFF,FALSE),
204:
205:
206: HOWTO (R_PARTLS7,0,1,7,FALSE,0,complain_overflow_dont,
207: tic54x_relocation,"ALS7",FALSE,0x007F,0x007F,FALSE),
208:
209:
210:
211: HOWTO (R_PARTMS9,7,1,9,FALSE,0,complain_overflow_dont,
212: tic54x_relocation,"AMS9",FALSE,0x01FF,0x01FF,FALSE),
213:
214:
215: HOWTO (R_EXTWORD,0,2,23,FALSE,0,complain_overflow_dont,
216: tic54x_relocation,"ARELEXT",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
217:
218:
219: HOWTO (R_EXTWORD16,0,1,16,FALSE,0,complain_overflow_dont,
220: tic54x_relocation,"ARELEXT16",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
221:
222:
223: HOWTO (R_EXTWORDMS7,16,1,7,FALSE,0,complain_overflow_dont,
224: tic54x_relocation,"ARELEXTMS7",FALSE,0x7F,0x7F,FALSE),
225:
226:
227: HOWTO (R_RELLONG,0,2,32,FALSE,0,complain_overflow_dont,
228: tic54x_relocation,"STAB",FALSE,0xFFFFFFFF,0xFFFFFFFF,FALSE),
229: };
230:
231: #define coff_bfd_reloc_type_lookup tic54x_coff_reloc_type_lookup
232: #define coff_bfd_reloc_name_lookup tic54x_coff_reloc_name_lookup
233:
234:
235:
236:
237: reloc_howto_type *
238: tic54x_coff_reloc_type_lookup (abfd, code)
239: bfd *abfd ATTRIBUTE_UNUSED;
240: bfd_reloc_code_real_type code;
241: {
242: switch (code)
243: {
244: case BFD_RELOC_16:
245: return &tic54x_howto_table[0];
246: case BFD_RELOC_TIC54X_PARTLS7:
247: return &tic54x_howto_table[1];
248: case BFD_RELOC_TIC54X_PARTMS9:
249: return &tic54x_howto_table[2];
250: case BFD_RELOC_TIC54X_23:
251: return &tic54x_howto_table[3];
252: case BFD_RELOC_TIC54X_16_OF_23:
253: return &tic54x_howto_table[4];
254: case BFD_RELOC_TIC54X_MS7_OF_23:
255: return &tic54x_howto_table[5];
256: case BFD_RELOC_32:
257: return &tic54x_howto_table[12];
258: default:
259: return (reloc_howto_type *) NULL;
260: }
261: }
262:
263: static reloc_howto_type *
264: tic54x_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
265: const char *r_name)
266: {
267: unsigned int i;
268:
269: for (i = 0;
270: i < sizeof (tic54x_howto_table) / sizeof (tic54x_howto_table[0]);
271: i++)
272: if (tic54x_howto_table[i].name != NULL
273: && strcasecmp (tic54x_howto_table[i].name, r_name) == 0)
274: return &tic54x_howto_table[i];
275:
276: return NULL;
277: }
278:
279:
280:
281:
282: static void
283: tic54x_lookup_howto (internal, dst)
284: arelent *internal;
285: struct internal_reloc *dst;
286: {
287: unsigned i;
288: int bank = (dst->r_symndx == -1) ? HOWTO_BANK : 0;
289:
290: for (i = 0; i < sizeof tic54x_howto_table/sizeof tic54x_howto_table[0]; i++)
291: {
292: if (tic54x_howto_table[i].type == dst->r_type)
293: {
294: internal->howto = tic54x_howto_table + i + bank;
295: return;
296: }
297: }
298:
299: (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
300: (unsigned int) dst->r_type);
301: abort ();
302: }
303:
304: #define RELOC_PROCESSING(RELENT,RELOC,SYMS,ABFD,SECT)\
305: tic54x_reloc_processing(RELENT,RELOC,SYMS,ABFD,SECT)
306:
307: #define coff_rtype_to_howto coff_tic54x_rtype_to_howto
308:
309: static reloc_howto_type *
310: coff_tic54x_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
311: bfd *abfd ATTRIBUTE_UNUSED;
312: asection *sec;
313: struct internal_reloc *rel;
314: struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
315: struct internal_syment *sym ATTRIBUTE_UNUSED;
316: bfd_vma *addendp;
317: {
318: arelent genrel;
319:
320: if (rel->r_symndx == -1 && addendp != NULL)
321: {
322:
323:
324:
325: *addendp = (sec->output_section->vma + sec->output_offset) - sec->vma;
326: }
327:
328: tic54x_lookup_howto (&genrel, rel);
329:
330: return genrel.howto;
331: }
332:
333:
334:
335:
336: static bfd_boolean
337: ticoff_bfd_is_local_label_name (abfd, name)
338: bfd *abfd ATTRIBUTE_UNUSED;
339: const char *name;
340: {
341: if (TICOFF_LOCAL_LABEL_P(name))
342: return TRUE;
343: return FALSE;
344: }
345:
346: #define coff_bfd_is_local_label_name ticoff_bfd_is_local_label_name
347:
348:
349: #define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \
350: do \
351: { \
352: dst->r_reserved[0] = 0; \
353: dst->r_reserved[1] = 0; \
354: } \
355: while (0)
356:
357:
358:
359:
360:
361: #define BADMAG(x) COFF2_BADMAG(x)
362: #include "coffcode.h"
363:
364: static bfd_boolean
365: tic54x_set_section_contents (abfd, section, location, offset, bytes_to_do)
366: bfd *abfd;
367: sec_ptr section;
368: const PTR location;
369: file_ptr offset;
370: bfd_size_type bytes_to_do;
371: {
372: return coff_set_section_contents (abfd, section, location,
373: offset, bytes_to_do);
374: }
375:
376: static void
377: tic54x_reloc_processing (relent, reloc, symbols, abfd, section)
378: arelent *relent;
379: struct internal_reloc *reloc;
380: asymbol **symbols;
381: bfd *abfd;
382: asection *section;
383: {
384: asymbol *ptr;
385:
386: relent->address = reloc->r_vaddr;
387:
388: if (reloc->r_symndx != -1)
389: {
390: if (reloc->r_symndx < 0 || reloc->r_symndx >= obj_conv_table_size (abfd))
391: {
392: (*_bfd_error_handler)
393: (_("%B: warning: illegal symbol index %ld in relocs"),
394: abfd, reloc->r_symndx);
395: relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
396: ptr = NULL;
397: }
398: else
399: {
400: relent->sym_ptr_ptr = (symbols
401: + obj_convert (abfd)[reloc->r_symndx]);
402: ptr = *(relent->sym_ptr_ptr);
403: }
404: }
405: else
406: {
407: relent->sym_ptr_ptr = section->symbol_ptr_ptr;
408: ptr = *(relent->sym_ptr_ptr);
409: }
410:
411:
412:
413:
414:
415:
416:
417:
418:
419: CALC_ADDEND (abfd, ptr, *reloc, relent);
420:
421: relent->address -= section->vma;
422:
423:
424:
425: tic54x_lookup_howto (relent, reloc);
426: }
427:
428:
429: const bfd_target tic54x_coff0_vec =
430: {
431: "coff0-c54x",
432: bfd_target_coff_flavour,
433: BFD_ENDIAN_LITTLE,
434: BFD_ENDIAN_LITTLE,
435:
436: (HAS_RELOC | EXEC_P |
437: HAS_LINENO | HAS_DEBUG |
438: HAS_SYMS | HAS_LOCALS | WP_TEXT ),
439:
440: (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
441: '_',
442: '/',
443: 15,
444: bfd_getl64, bfd_getl_signed_64, bfd_putl64,
445: tic54x_getl32, tic54x_getl_signed_32, tic54x_putl32,
446: bfd_getl16, bfd_getl_signed_16, bfd_putl16,
447: bfd_getl64, bfd_getl_signed_64, bfd_putl64,
448: bfd_getl32, bfd_getl_signed_32, bfd_putl32,
449: bfd_getl16, bfd_getl_signed_16, bfd_putl16,
450:
451: {_bfd_dummy_target, coff_object_p,
452: bfd_generic_archive_p, _bfd_dummy_target},
453: {bfd_false, coff_mkobject, _bfd_generic_mkarchive,
454: bfd_false},
455: {bfd_false, coff_write_object_contents,
456: _bfd_write_archive_contents, bfd_false},
457:
458: BFD_JUMP_TABLE_GENERIC (coff),
459: BFD_JUMP_TABLE_COPY (coff),
460: BFD_JUMP_TABLE_CORE (_bfd_nocore),
461: BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
462: BFD_JUMP_TABLE_SYMBOLS (coff),
463: BFD_JUMP_TABLE_RELOCS (coff),
464: BFD_JUMP_TABLE_WRITE (tic54x),
465: BFD_JUMP_TABLE_LINK (coff),
466: BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
467: NULL,
468:
469: (PTR) & ticoff0_swap_table
470: };
471:
472:
473: const bfd_target tic54x_coff0_beh_vec =
474: {
475: "coff0-beh-c54x",
476: bfd_target_coff_flavour,
477: BFD_ENDIAN_LITTLE,
478: BFD_ENDIAN_BIG,
479:
480: (HAS_RELOC | EXEC_P |
481: HAS_LINENO | HAS_DEBUG |
482: HAS_SYMS | HAS_LOCALS | WP_TEXT ),
483:
484: (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
485: '_',
486: '/',
487: 15,
488: bfd_getl64, bfd_getl_signed_64, bfd_putl64,
489: tic54x_getl32, tic54x_getl_signed_32, tic54x_putl32,
490: bfd_getl16, bfd_getl_signed_16, bfd_putl16,
491: bfd_getb64, bfd_getb_signed_64, bfd_putb64,
492: bfd_getb32, bfd_getb_signed_32, bfd_putb32,
493: bfd_getb16, bfd_getb_signed_16, bfd_putb16,
494:
495: {_bfd_dummy_target, coff_object_p,
496: bfd_generic_archive_p, _bfd_dummy_target},
497: {bfd_false, coff_mkobject, _bfd_generic_mkarchive,
498: bfd_false},
499: {bfd_false, coff_write_object_contents,
500: _bfd_write_archive_contents, bfd_false},
501:
502: BFD_JUMP_TABLE_GENERIC (coff),
503: BFD_JUMP_TABLE_COPY (coff),
504: BFD_JUMP_TABLE_CORE (_bfd_nocore),
505: BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
506: BFD_JUMP_TABLE_SYMBOLS (coff),
507: BFD_JUMP_TABLE_RELOCS (coff),
508: BFD_JUMP_TABLE_WRITE (tic54x),
509: BFD_JUMP_TABLE_LINK (coff),
510: BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
511:
512: & tic54x_coff0_vec,
513:
514: (PTR) & ticoff0_swap_table
515: };
516:
517:
518: const bfd_target tic54x_coff1_vec =
519: {
520: "coff1-c54x",
521: bfd_target_coff_flavour,
522: BFD_ENDIAN_LITTLE,
523: BFD_ENDIAN_LITTLE,
524:
525: (HAS_RELOC | EXEC_P |
526: HAS_LINENO | HAS_DEBUG |
527: HAS_SYMS | HAS_LOCALS | WP_TEXT ),
528:
529: (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
530: '_',
531: '/',
532: 15,
533: bfd_getl64, bfd_getl_signed_64, bfd_putl64,
534: tic54x_getl32, tic54x_getl_signed_32, tic54x_putl32,
535: bfd_getl16, bfd_getl_signed_16, bfd_putl16,
536: bfd_getl64, bfd_getl_signed_64, bfd_putl64,
537: bfd_getl32, bfd_getl_signed_32, bfd_putl32,
538: bfd_getl16, bfd_getl_signed_16, bfd_putl16,
539:
540: {_bfd_dummy_target, coff_object_p,
541: bfd_generic_archive_p, _bfd_dummy_target},
542: {bfd_false, coff_mkobject, _bfd_generic_mkarchive,
543: bfd_false},
544: {bfd_false, coff_write_object_contents,
545: _bfd_write_archive_contents, bfd_false},
546:
547: BFD_JUMP_TABLE_GENERIC (coff),
548: BFD_JUMP_TABLE_COPY (coff),
549: BFD_JUMP_TABLE_CORE (_bfd_nocore),
550: BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
551: BFD_JUMP_TABLE_SYMBOLS (coff),
552: BFD_JUMP_TABLE_RELOCS (coff),
553: BFD_JUMP_TABLE_WRITE (tic54x),
554: BFD_JUMP_TABLE_LINK (coff),
555: BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
556: