1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29: #include "sysdep.h"
30: #include "bfd.h"
31: #include "bucomm.h"
32: #include "sysroff.h"
33: #include "coffgrok.h"
34: #include "libiberty.h"
35: #include "getopt.h"
36:
37: #include "coff/internal.h"
38: #include "../bfd/libcoff.h"
39:
40:
41:
42: static int addrsize;
43: static char *toolname;
44: static char **rnames;
45:
46: static int get_member_id (int);
47: static int get_ordinary_id (int);
48: static char *section_translate (char *);
49: static char *strip_suffix (const char *);
50: static void checksum (FILE *, unsigned char *, int, int);
51: static void writeINT (int, unsigned char *, int *, int, FILE *);
52: static void writeBITS (int, unsigned char *, int *, int);
53: static void writeBARRAY (barray, unsigned char *, int *, int, FILE *);
54: static void writeCHARS (char *, unsigned char *, int *, int, FILE *);
55: static void wr_tr (void);
56: static void wr_un (struct coff_ofile *, struct coff_sfile *, int, int);
57: static void wr_hd (struct coff_ofile *);
58: static void wr_sh (struct coff_ofile *, struct coff_section *);
59: static void wr_ob (struct coff_ofile *, struct coff_section *);
60: static void wr_rl (struct coff_ofile *, struct coff_section *);
61: static void wr_object_body (struct coff_ofile *);
62: static void wr_dps_start
63: (struct coff_sfile *, struct coff_section *, struct coff_scope *, int, int);
64: static void wr_dps_end (struct coff_section *, struct coff_scope *, int);
65: static int *nints (int);
66: static void walk_tree_type_1
67: (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
68: static void walk_tree_type
69: (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
70: static void walk_tree_symbol
71: (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int);
72: static void walk_tree_scope
73: (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int);
74: static void walk_tree_sfile (struct coff_section *, struct coff_sfile *);
75: static void wr_program_structure (struct coff_ofile *, struct coff_sfile *);
76: static void wr_du (struct coff_ofile *, struct coff_sfile *, int);
77: static void wr_dus (struct coff_ofile *, struct coff_sfile *);
78: static int find_base (struct coff_sfile *, struct coff_section *);
79: static void wr_dln (struct coff_ofile *, struct coff_sfile *, int);
80: static void wr_globals (struct coff_ofile *, struct coff_sfile *, int);
81: static void wr_debug (struct coff_ofile *);
82: static void wr_cs (void);
83: static int wr_sc (struct coff_ofile *, struct coff_sfile *);
84: static void wr_er (struct coff_ofile *, struct coff_sfile *, int);
85: static void wr_ed (struct coff_ofile *, struct coff_sfile *, int);
86: static void wr_unit_info (struct coff_ofile *);
87: static void wr_module (struct coff_ofile *);
88: static int align (int);
89: static void prescan (struct coff_ofile *);
90: static void show_usage (FILE *, int);
91: extern int main (int, char **);
92:
93: static FILE *file;
94: static bfd *abfd;
95: static int debug = 0;
96: static int quick = 0;
97: static int noprescan = 0;
98: static struct coff_ofile *tree;
99:
100:
101:
102:
103: static int segmented_p;
104: static int code;
105:
106: static int ids1[20000];
107: static int ids2[20000];
108:
109: static int base1 = 0x18;
110: static int base2 = 0x2018;
111:
112: static int
113: get_member_id (int x)
114: {
115: if (ids2[x])
116: return ids2[x];
117:
118: ids2[x] = base2++;
119: return ids2[x];
120: }
121:
122: static int
123: get_ordinary_id (int x)
124: {
125: if (ids1[x])
126: return ids1[x];
127:
128: ids1[x] = base1++;
129: return ids1[x];
130: }
131: static char *
132: section_translate (char *n)
133: {
134: if (strcmp (n, ".text") == 0)
135: return "P";
136: if (strcmp (n, ".data") == 0)
137: return "D";
138: if (strcmp (n, ".bss") == 0)
139: return "B";
140: return n;
141: }
142:
143: #define DATE "940201073000";
144:
145: static char *
146: strip_suffix (const char *name)
147: {
148: int i;
149: char *res;
150:
151: for (i = 0; name[i] != 0 && name[i] != '.'; i++)
152: ;
153: res = (char *) xmalloc (i + 1);
154: memcpy (res, name, i);
155: res[i] = 0;
156: return res;
157: }
158:
159:
160: static void
161: checksum (FILE *file, unsigned char *ptr, int size, int code)
162: {
163: int j;
164: int last;
165: int sum = 0;
166: int bytes = size / 8;
167:
168: last = !(code & 0xff00);
169: if (size & 0x7)
170: abort ();
171: ptr[0] = code | (last ? 0x80 : 0);
172: ptr[1] = bytes + 1;
173:
174: for (j = 0; j < bytes; j++)
175: sum += ptr[j];
176:
177:
178: ptr[bytes] = ~sum;
179: fwrite (ptr, bytes + 1, 1, file);
180: }
181:
182:
183: static void
184: writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *file)
185: {
186: int byte = *idx / 8;
187:
188: if (size == -2)
189: size = addrsize;
190: else if (size == -1)
191: size = 0;
192:
193: if (byte > 240)
194: {
195:
196: checksum (file, ptr, *idx, code | 0x1000);
197: *idx = 16;
198: byte = *idx / 8;
199: }
200:
201: switch (size)
202: {
203: case 0:
204: break;
205: case 1:
206: ptr[byte] = n;
207: break;
208: case 2:
209: ptr[byte + 0] = n >> 8;
210: ptr[byte + 1] = n;
211: break;
212: case 4:
213: ptr[byte + 0] = n >> 24;
214: ptr[byte + 1] = n >> 16;
215: ptr[byte + 2] = n >> 8;
216: ptr[byte + 3] = n >> 0;
217: break;
218: default:
219: abort ();
220: }
221: *idx += size * 8;
222: }
223:
224: static void
225: writeBITS (int val, unsigned char *ptr, int *idx, int size)
226: {
227: int byte = *idx / 8;
228: int bit = *idx % 8;
229: int old;
230:
231: *idx += size;
232:
233: old = ptr[byte];
234:
235: old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));
236:
237: old |= (val & ((1 << size) - 1)) << (8 - bit - size);
238: ptr[byte] = old;
239: }
240:
241: static void
242: writeBARRAY (barray data, unsigned char *ptr, int *idx,
243: int size ATTRIBUTE_UNUSED, FILE *file)
244: {
245: int i;
246:
247: writeINT (data.len, ptr, idx, 1, file);
248: for (i = 0; i < data.len; i++)
249: writeINT (data.data[i], ptr, idx, 1, file);
250: }
251:
252: static void
253: writeCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *file)
254: {
255: int i = *idx / 8;
256:
257: if (i > 240)
258: {
259:
260: checksum (file, ptr, *idx, code | 0x1000);
261: *idx = 16;
262: i = *idx / 8;
263: }
264:
265: if (size == 0)
266: {
267:
268: size = strlen (string);
269: ptr[i++] = size;
270: }
271:
272:
273: memcpy (ptr + i, string, size);
274: i += size;
275: *idx = i * 8;
276: }
277:
278: #define SYSROFF_SWAP_OUT
279: #include "sysroff.c"
280:
281: static char *rname_sh[] =
282: {
283: "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
284: };
285:
286: static char *rname_h8300[] =
287: {
288: "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"
289: };
290:
291: static void
292: wr_tr (void)
293: {
294:
295:
296: static char b[] =
297: {
298: 0xff,
299: 0x03,
300: 0xfd,
301: };
302: fwrite (b, 1, sizeof (b), file);
303: }
304:
305: static void
306: wr_un (struct coff_ofile *ptr, struct coff_sfile *sfile, int first,
307: int nsecs ATTRIBUTE_UNUSED)
308: {
309: struct IT_un un;
310: struct coff_symbol *s;
311:
312: un.spare1 = 0;
313:
314: if (bfd_get_file_flags (abfd) & EXEC_P)
315: un.format = FORMAT_LM;
316: else
317: un.format = FORMAT_OM;
318: un.spare1 = 0;
319:
320:
321: un.nsections = ptr->nsections - 1;
322:
323: un.nextdefs = 0;
324: un.nextrefs = 0;
325:
326:
327: if (first)
328: {
329: for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
330: {
331: if (s->visible->type == coff_vis_ext_def
332: || s->visible->type == coff_vis_common)
333: un.nextdefs++;
334:
335: if (s->visible->type == coff_vis_ext_ref)
336: un.nextrefs++;
337: }
338: }
339: un.tool = toolname;
340: un.tcd = DATE;
341: un.linker = "L_GX00";
342: un.lcd = DATE;
343: un.name = sfile->name;
344: sysroff_swap_un_out (file, &un);
345: }
346:
347: static void
348: wr_hd (struct coff_ofile *p)
349: {
350: struct IT_hd hd;
351:
352: hd.spare1 = 0;
353: if (bfd_get_file_flags (abfd) & EXEC_P)
354: hd.mt = MTYPE_ABS_LM;
355: else
356: hd.mt = MTYPE_OMS_OR_LMS;
357:
358: hd.cd = DATE;
359:
360: hd.nu = p->nsources;
361: hd.code = 0;
362: hd.ver = "0200";
363:
364: switch (bfd_get_arch (abfd))
365: {
366: case bfd_arch_h8300:
367: hd.au = 8;
368: hd.si = 0;
369: hd.spcsz = 32;
370: hd.segsz = 0;
371: hd.segsh = 0;
372: switch (bfd_get_mach (abfd))
373: {
374: case bfd_mach_h8300:
375: hd.cpu = "H8300";
376: hd.afl = 2;
377: addrsize = 2;
378: toolname = "C_H8/300";
379: break;
380: case bfd_mach_h8300h:
381: hd.cpu = "H8300H";
382: hd.afl = 4;
383: addrsize = 4;
384: toolname = "C_H8/300H";
385: break;
386: case bfd_mach_h8300s:
387: hd.cpu = "H8300S";
388: hd.afl = 4;
389: addrsize = 4;
390: toolname = "C_H8/300S";
391: break;
392: default:
393: abort();
394: }
395: rnames = rname_h8300;
396: break;
397: case bfd_arch_sh:
398: hd.au = 8;
399: hd.si = 0;
400: hd.afl = 4;
401: hd.spcsz = 32;
402: hd.segsz = 0;
403: hd.segsh = 0;
404: hd.cpu = "SH";
405: addrsize = 4;
406: toolname = "C_SH";
407: rnames = rname_sh;
408: break;
409: default:
410: abort ();
411: }
412:
413: if (! bfd_get_file_flags(abfd) & EXEC_P)
414: {
415: hd.ep = 0;
416: }
417: else
418: {
419: hd.ep = 1;
420: hd.uan = 0;
421: hd.sa = 0;
422: hd.sad = 0;
423: hd.address = bfd_get_start_address (abfd);
424: }
425:
426: hd.os = "";
427: hd.sys = "";
428: hd.mn = strip_suffix (bfd_get_filename (abfd));
429:
430: sysroff_swap_hd_out (file, &hd);
431: }
432:
433:
434: static void
435: wr_sh (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *sec)
436: {
437: struct IT_sh sh;
438: sh.unit = 0;
439: sh.section = sec->number;
440: #ifdef FOOP1
441: sh.section = 0;
442: #endif
443: sysroff_swap_sh_out (file, &sh);
444: }
445:
446:
447: static void
448: wr_ob (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *section)
449: {
450: bfd_size_type i;
451: int first = 1;
452: unsigned char stuff[200];
453:
454: i = 0;
455: while (i < bfd_get_section_size (section->bfd_section))
456: {
457: struct IT_ob ob;
458: int todo = 200;
459:
460: ob.spare = 0;
461: if (i + todo > bfd_get_section_size (section->bfd_section))
462: todo = bfd_get_section_size (section->bfd_section) - i;
463:
464: if (first)
465: {
466: ob.saf = 1;
467: if (bfd_get_file_flags (abfd) & EXEC_P)
468: ob.address = section->address;
469: else
470: ob.address = 0;
471:
472: first = 0;
473: }
474: else
475: {
476: ob.saf = 0;
477: }
478:
479: ob.cpf = 0;
480: ob.data.len = todo;
481: bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo);
482: ob.data.data = stuff;
483: sysroff_swap_ob_out (file, &ob );
484: i += todo;
485: }
486:
487:
488: while (i < (bfd_size_type) section->size)
489: {
490: struct IT_ob ob;
491: int todo = 200;
492:
493: ob.spare = 0;
494: if (i + todo > (bfd_size_type) section->size)
495: todo = section->size - i;
496: ob.saf = 0;
497:
498: ob.cpf = 0;
499: ob.data.len = todo;
500: memset (stuff, 0, todo);
501: ob.data.data = stuff;
502: sysroff_swap_ob_out (file, &ob);
503: i += todo;
504: }
505:
506: }
507:
508: static void
509: wr_rl (struct coff_ofile *ptr ATTRIBUTE_UNUSED, struct coff_section *sec)
510: {
511: int nr = sec->nrelocs;
512: int i;
513:
514: for (i = 0; i < nr; i++)
515: {
516: struct coff_reloc *r = sec->relocs + i;
517: struct coff_symbol *ref;
518: struct IT_rl rl;
519:
520: rl.apol = 0;
521: rl.boundary = 0;
522: rl.segment = 1;
523: rl.sign = 0;
524: rl.check = 0;
525: rl.addr = r->offset;
526: rl.bitloc = 0;
527: rl.flen = 32;
528:
529:
530: ref = r->symbol;
531: if (ref->visible->type == coff_vis_ext_ref)
532: {
533: rl.bcount = 4;
534: rl.op = OP_EXT_REF;
535: rl.symn = ref->er_number;
536: }
537: else if (ref->visible->type == coff_vis_common)
538: {
539: rl.bcount = 11;
540: rl.op = OP_SEC_REF;
541: rl.secn = ref->where->section->number;
542: rl.copcode_is_3 = 3;
543: rl.alength_is_4 = 4;
544: rl.addend = ref->where->offset - ref->where->section->address;
545: rl.aopcode_is_0x20 = 0x20;
546: }
547: else
548: {
549: rl.bcount = 11;
550: rl.op = OP_SEC_REF;
551: rl.secn = ref->where->section->number;
552: