1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #define TARGET_IS_BIG_ENDIAN_P
24: #define N_HEADER_IN_TEXT(x) 1
25: #define TEXT_START_ADDR 1024
26: #define TARGET_PAGE_SIZE 128
27: #define SEGMENT_SIZE TARGET_PAGE_SIZE
28: #define DEFAULT_ARCH bfd_arch_tic30
29: #define ARCH_SIZE 32
30:
31:
32:
33:
34: #define MY(OP) CONCAT2 (tic30_aout_,OP)
35: #define TARGETNAME "a.out-tic30"
36: #define NAME(x,y) CONCAT3 (tic30_aout,_32_,y)
37:
38: #include "sysdep.h"
39: #include "bfd.h"
40: #include "libaout.h"
41: #include "aout/aout64.h"
42: #include "aout/stab_gnu.h"
43: #include "aout/ar.h"
44:
45: #define MY_reloc_howto(BFD, REL, IN, EX, PC) tic30_aout_reloc_howto (BFD, REL, & IN, & EX, & PC)
46:
47: #define MY_final_link_relocate tic30_aout_final_link_relocate
48: #define MY_object_p tic30_aout_object_p
49: #define MY_mkobject NAME (aout,mkobject)
50: #define MY_write_object_contents tic30_aout_write_object_contents
51: #define MY_set_sizes tic30_aout_set_sizes
52:
53: #ifndef MY_exec_hdr_flags
54: #define MY_exec_hdr_flags 1
55: #endif
56:
57: #ifndef MY_backend_data
58:
59: #ifndef MY_zmagic_contiguous
60: #define MY_zmagic_contiguous 0
61: #endif
62: #ifndef MY_text_includes_header
63: #define MY_text_includes_header 0
64: #endif
65: #ifndef MY_entry_is_text_address
66: #define MY_entry_is_text_address 0
67: #endif
68: #ifndef MY_exec_header_not_counted
69: #define MY_exec_header_not_counted 1
70: #endif
71: #ifndef MY_add_dynamic_symbols
72: #define MY_add_dynamic_symbols 0
73: #endif
74: #ifndef MY_add_one_symbol
75: #define MY_add_one_symbol 0
76: #endif
77: #ifndef MY_link_dynamic_object
78: #define MY_link_dynamic_object 0
79: #endif
80: #ifndef MY_write_dynamic_symbol
81: #define MY_write_dynamic_symbol 0
82: #endif
83: #ifndef MY_check_dynamic_reloc
84: #define MY_check_dynamic_reloc 0
85: #endif
86: #ifndef MY_finish_dynamic_link
87: #define MY_finish_dynamic_link 0
88: #endif
89:
90: static bfd_boolean
91: tic30_aout_set_sizes (bfd *abfd)
92: {
93: adata (abfd).page_size = TARGET_PAGE_SIZE;
94:
95: #ifdef SEGMENT_SIZE
96: adata (abfd).segment_size = SEGMENT_SIZE;
97: #else
98: adata (abfd).segment_size = TARGET_PAGE_SIZE;
99: #endif
100:
101: #ifdef ZMAGIC_DISK_BLOCK_SIZE
102: adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
103: #else
104: adata (abfd).zmagic_disk_block_size = TARGET_PAGE_SIZE;
105: #endif
106:
107: adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
108:
109: return TRUE;
110: }
111:
112: static const struct aout_backend_data tic30_aout_backend_data =
113: {
114: MY_zmagic_contiguous,
115: MY_text_includes_header,
116: MY_entry_is_text_address,
117: MY_exec_hdr_flags,
118: 0,
119: MY_set_sizes,
120: MY_exec_header_not_counted,
121: MY_add_dynamic_symbols,
122: MY_add_one_symbol,
123: MY_link_dynamic_object,
124: MY_write_dynamic_symbol,
125: MY_check_dynamic_reloc,
126: MY_finish_dynamic_link
127: };
128: #define MY_backend_data &tic30_aout_backend_data
129: #endif
130:
131: static reloc_howto_type *
132: tic30_aout_reloc_howto (bfd *, struct reloc_std_external *, int *, int *, int *);
133: static bfd_reloc_status_type
134: tic30_aout_final_link_relocate
135: (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
136:
137:
138:
139:
140: #include "aoutx.h"
141:
142:
143:
144:
145:
146:
147:
148:
149: static bfd_reloc_status_type
150: tic30_aout_fix_pcrel_16 (bfd *abfd,
151: arelent *reloc_entry,
152: asymbol *symbol ATTRIBUTE_UNUSED,
153: void * data,
154: asection *input_section ATTRIBUTE_UNUSED,
155: bfd *output_bfd ATTRIBUTE_UNUSED,
156: char **error_message ATTRIBUTE_UNUSED)
157: {
158: bfd_vma relocation = 1;
159: bfd_byte offset_data = bfd_get_8 (abfd, (bfd_byte *) data + reloc_entry->address - 1);
160:
161:
162:
163:
164: if (offset_data & 0x20)
165: relocation -= 3;
166: else
167: relocation -= 1;
168: bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
169: return bfd_reloc_ok;
170: }
171:
172:
173:
174:
175:
176:
177:
178:
179: static bfd_reloc_status_type
180: tic30_aout_fix_16 (bfd *abfd,
181: arelent *reloc_entry,
182: asymbol *symbol,
183: void * data,
184: asection *input_section ATTRIBUTE_UNUSED,
185: bfd *output_bfd,
186: char **error_message ATTRIBUTE_UNUSED)
187: {
188: bfd_vma relocation;
189:
190:
191: if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
192: return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
193:
194:
195: relocation = (symbol->section->vma >> 2);
196: relocation += bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
197: bfd_put_16 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
198: return bfd_reloc_ok;
199: }
200:
201:
202:
203:
204: static bfd_reloc_status_type
205: tic30_aout_fix_32 (bfd *abfd,
206: arelent *reloc_entry,
207: asymbol *symbol,
208: void * data,
209: asection *input_section ATTRIBUTE_UNUSED,
210: bfd *output_bfd,
211: char **error_message ATTRIBUTE_UNUSED)
212: {
213: bfd_vma relocation;
214:
215:
216: if (symbol->section == &bfd_und_section && (symbol->flags & BSF_WEAK) == 0)
217: return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined;
218:
219:
220: relocation = (symbol->section->vma >> 2);
221: relocation += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
222: bfd_put_32 (abfd, relocation, (bfd_byte *) data + reloc_entry->address);
223: return bfd_reloc_ok;
224: }
225:
226:
227:
228:
229:
230: reloc_howto_type tic30_aout_howto_table[] =
231: {
232: EMPTY_HOWTO (-1),
233: HOWTO (1, 2, 1, 16, FALSE, 0, 0, tic30_aout_fix_16,
234: "16", FALSE, 0x0000FFFF, 0x0000FFFF, FALSE),
235: HOWTO (2, 2, 2, 24, FALSE, 0, complain_overflow_bitfield, NULL,
236: "24", FALSE, 0x00FFFFFF, 0x00FFFFFF, FALSE),
237: HOWTO (3, 18, 3, 24, FALSE, 0, complain_overflow_bitfield, NULL,
238: "LDP", FALSE, 0x00FF0000, 0x000000FF, FALSE),
239: HOWTO (4, 2, 4, 32, FALSE, 0, complain_overflow_bitfield, tic30_aout_fix_32,
240: "32", FALSE, 0xFFFFFFFF, 0xFFFFFFFF, FALSE),
241: HOWTO (5, 2, 1, 16, TRUE, 0, complain_overflow_signed,
242: tic30_aout_fix_pcrel_16, "PCREL", TRUE, 0x0000FFFF, 0x0000FFFF, TRUE),
243: EMPTY_HOWTO (-1),
244: EMPTY_HOWTO (-1),
245: EMPTY_HOWTO (-1),
246: EMPTY_HOWTO (-1),
247: EMPTY_HOWTO (-1)
248: };
249:
250:
251: static reloc_howto_type *
252: tic30_aout_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
253: bfd_reloc_code_real_type code)
254: {
255: switch (code)
256: {
257: case BFD_RELOC_8:
258: case BFD_RELOC_TIC30_LDP:
259: return &tic30_aout_howto_table[3];
260: case BFD_RELOC_16:
261: return &tic30_aout_howto_table[1];
262: case BFD_RELOC_24:
263: return &tic30_aout_howto_table[2];
264: case BFD_RELOC_16_PCREL:
265: return &tic30_aout_howto_table[5];
266: case BFD_RELOC_32:
267: return &tic30_aout_howto_table[4];
268: default:
269: return NULL;
270: }
271: }
272:
273: static reloc_howto_type *
274: tic30_aout_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
275: const char *r_name)
276: {
277: unsigned int i;
278:
279: for (i = 0;
280: i < (sizeof (tic30_aout_howto_table)
281: / sizeof (tic30_aout_howto_table[0]));
282: i++)
283: if (tic30_aout_howto_table[i].name != NULL
284: && strcasecmp (tic30_aout_howto_table[i].name, r_name) == 0)
285: return &tic30_aout_howto_table[i];
286:
287: return NULL;
288: }
289:
290: static reloc_howto_type *
291: tic30_aout_reloc_howto (bfd *abfd,
292: struct reloc_std_external *relocs,
293: int *r_index,
294: int *r_extern,
295: int *r_pcrel)
296: {
297: unsigned int r_length;
298: unsigned int r_pcrel_done;
299: int index;
300:
301: *r_pcrel = 0;
302: if (bfd_header_big_endian (abfd))
303: {
304: *r_index = ((relocs->r_index[0] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[2]);
305: *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
306: r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
307: r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) >> RELOC_STD_BITS_LENGTH_SH_BIG);
308: }
309: else
310: {
311: *r_index = ((relocs->r_index[2] << 16) | (relocs->r_index[1] << 8) | relocs->r_index[0]);
312: *r_extern = (0 != (relocs->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
313: r_pcrel_done = (0 != (relocs->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
314: r_length = ((relocs->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
315: }
316: index = r_length + 4 * r_pcrel_done;
317: return tic30_aout_howto_table + index;
318: }
319:
320:
321:
322: #define bfd_getb_24(BFD,ADDR) \
323: (bfd_get_8 (BFD, ADDR ) << 16) | \
324: (bfd_get_8 (BFD, ADDR + 1) << 8) | \
325: (bfd_get_8 (BFD, ADDR + 2) )
326:
327: #define bfd_putb_24(BFD,DATA,ADDR) \
328: bfd_put_8 (BFD, (bfd_byte) ((DATA >> 16) & 0xFF), ADDR ); \
329: bfd_put_8 (BFD, (bfd_byte) ((DATA >> 8) & 0xFF), ADDR + 1); \
330: bfd_put_8 (BFD, (bfd_byte) ( DATA & 0xFF), ADDR + 2)
331:
332:
333:
334:
335: static const bfd_target *
336: tic30_aout_callback (bfd *abfd)
337: {
338: struct internal_exec *execp = exec_hdr (abfd);
339: unsigned int arch_align_power;
340: unsigned long arch_align;
341:
342:
343: obj_textsec (abfd)->size = N_TXTSIZE (*execp);
344:
345:
346: obj_textsec (abfd)->vma = N_TXTADDR (*execp);
347: obj_datasec (abfd)->vma = N_DATADDR (*execp);
348: obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
349:
350: obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
351: obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
352: obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
353:
354:
355: obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
356: obj_datasec (abfd)->filepos = N_DATOFF (*execp);
357:
358:
359: obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
360: obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
361:
362:
363: obj_sym_filepos (abfd) = N_SYMOFF (*execp);
364: obj_str_filepos (abfd) = N_STROFF (*execp);
365:
366:
367: #ifdef SET_ARCH_MACH
368: SET_ARCH_MACH (abfd, *execp);
369: #else
370: bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0L);
371: #endif
372:
373:
374:
375:
376:
377:
378:
379: arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
380: arch_align = 1 << arch_align_power;
381: if ((BFD_ALIGN (obj_textsec (abfd)->size, arch_align)
382: == obj_textsec (abfd)->size)
383: && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align)
384: == obj_datasec (abfd)->size)
385: && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align)
386: == obj_bsssec (abfd)->size))
387: {
388: obj_textsec (abfd)->alignment_power = arch_align_power;
389: obj_datasec (abfd)->alignment_power = arch_align_power;
390: obj_bsssec (abfd)->alignment_power = arch_align_power;
391: }
392: return abfd->xvec;
393: }
394:
395: static bfd_reloc_status_type
396: tic30_aout_relocate_contents (reloc_howto_type *howto,
397: bfd *input_bfd,
398: bfd_vma relocation,
399: bfd_byte *location)
400: {
401: bfd_vma x;
402: bfd_boolean overflow;
403:
404: if (howto->size < 0)
405: relocation = -relocation;
406:
407: switch (howto->size)
408: {
409: default:
410: case 0:
411: abort ();
412: break;
413: case 1:
414: x = bfd_get_16 (input_bfd, location);
415: break;
416: case 2:
417: x = bfd_getb_24 (input_bfd, location);
418: break;
419: case 3:
420: x = bfd_get_8 (input_bfd, location);
421: break;
422: case 4:
423: x = bfd_get_32 (input_bfd, location);
424: break;
425: }
426:
427: overflow = FALSE;
428:
429: if (howto->complain_on_overflow != complain_overflow_dont)
430: {
431: bfd_vma check;
432: bfd_signed_vma signed_check;
433: bfd_vma add;
434: bfd_signed_vma signed_add;
435:
436: if (howto->rightshift == 0)
437: {
438: check = relocation;
439: signed_check = (bfd_signed_vma) relocation;
440: }
441: else
442: {
443: check = relocation >> howto->rightshift;
444: if ((bfd_signed_vma) relocation >= 0)
445: signed_check = check;
446: else
447: signed_check = (check | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->rightshift)));
448: }
449: add = x & howto->src_mask;
450: signed_add = add;
451: if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
452: signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
453: if (howto->bitpos == 0)
454: {
455: check += add;
456: signed_check += signed_add;
457: }
458: else
459: {
460: check += add >> howto->bitpos;
461: if (signed_add >= 0)
462: signed_check += add >> howto->bitpos;
463: else
464: signed_check += ((add >> howto->bitpos) | ((bfd_vma) - 1 & ~((bfd_vma) - 1 >> howto->bitpos)));
465: }
466: switch (howto->complain_on_overflow)
467: {
468: case complain_overflow_signed:
469: {
470: bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
471: bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
472:
473: if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
474: overflow = TRUE;
475: }
476: break;
477: case complain_overflow_unsigned:
478: {
479: bfd_vma reloc_unsigned_max = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
480:
481: if (check > reloc_unsigned_max)
482: overflow = TRUE;
483: }
484: break;
485: case complain_overflow_bitfield:
486: {
487: bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
488:
489: if ((check & ~reloc_bits) != 0
490: && (((bfd_vma) signed_check & ~reloc_bits)
491: != ((bfd_vma) -1 & ~reloc_bits)))
492: overflow = TRUE;
493: }
494: break;
495: default:
496: abort ();
497: }
498: }
499: relocation >>= (bfd_vma) howto->rightshift;
500: relocation <<= (bfd_vma) howto->bitpos;
501: x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask));
502: switch (howto->size)
503: {
504: default:
505: case 0:
506: abort ();
507: break;
508: case 1:
509: bfd_put_16 (input_bfd, x, location);
510: break;
511: case 2:
512: bfd_putb_24 (input_bfd, x, location);
513: break;
514: case 3:
515: bfd_put_8 (input_bfd, x, location);
516: break;
517: case 4:
518: bfd_put_32 (input_bfd, x, location);
519: break;
520: }
521: return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
522: }
523:
524: static bfd_reloc_status_type
525: tic30_aout_final_link_relocate (reloc_howto_type *howto,
526: bfd *input_bfd,
527: asection *input_section,
528: bfd_byte *contents,
529: bfd_vma address,
530: bfd_vma value,
531: bfd_vma addend)
532: {
533: bfd_vma relocation;
534:
535: if (address > bfd_get_section_limit (input_bfd, input_section))
536: return bfd_reloc_outofrange;
537:
538: relocation = value + addend;