cv.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. *
  6. */
  7. #include <stdio.h>
  8. #include <out.h>
  9. #define FMAGIC 0407
  10. #define NMAGIC 0410
  11. struct bhdr {
  12. long fmagic;
  13. long tsize;
  14. long dsize;
  15. long bsize;
  16. long ssize;
  17. long rtsize;
  18. long rdsize;
  19. long entry;
  20. };
  21. struct sym {
  22. char stype;
  23. char sympad;
  24. long svalue;
  25. };
  26. #define N_UNDF 0
  27. #define N_ABS 01
  28. #define N_TEXT 02
  29. #define N_DATA 03
  30. #define N_BSS 04
  31. #define N_EXT 040
  32. #define ASSERT(x) switch (2) { case 0: case (x): ; }
  33. /*
  34. * Header and section table of new format object file.
  35. */
  36. struct outhead outhead;
  37. struct outsect outsect[S_MAX];
  38. char *output_file;
  39. int outputfile_created;
  40. int rom_in_data;
  41. char *program ;
  42. char flag ;
  43. #define writef(a, b, c) fwrite((a), (b), (int)(c), output)
  44. /* Output file definitions and such */
  45. struct bhdr bh;
  46. #define ENTRY 0x80000
  47. #define TOT_HDRSIZE (sizeof(struct bhdr))
  48. #define TEXTSG 0
  49. #define ROMSG 1
  50. #define DATASG 2
  51. #define BSSSG 3
  52. #define LSECT BSSSG+1
  53. #define NSECT LSECT+1
  54. FILE *output;
  55. long align(a,b)
  56. long a,b;
  57. {
  58. a += b - 1;
  59. return a - a % b;
  60. }
  61. int
  62. follows(pa, pb)
  63. register struct outsect *pa, *pb;
  64. {
  65. /* return 1 if pa follows pb */
  66. return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
  67. }
  68. main(argc, argv)
  69. int argc;
  70. char *argv[];
  71. {
  72. register int nsect;
  73. long magic ;
  74. long textsize ;
  75. long datasize ;
  76. long bsssize;
  77. long symstart;
  78. extern long ftell();
  79. output = stdout;
  80. program= argv[0] ;
  81. if ( argc>1 && argv[1][0]=='-' ) {
  82. flag=argv[1][1] ;
  83. argc-- ; argv++ ;
  84. }
  85. switch (argc) {
  86. case 3: if ((output = fopen(argv[2], "w")) == (FILE *)0)
  87. fatal("Can't write %s.\n", argv[2]);
  88. output_file = argv[2];
  89. outputfile_created = 1;
  90. if (! rd_open(argv[1]))
  91. fatal("Can't read %s.\n", argv[1]);
  92. break;
  93. default:fatal("Usage: %s <ACK object> <Mantra object>.\n", argv[0]);
  94. }
  95. rd_ohead(&outhead);
  96. if (BADMAGIC(outhead))
  97. fatal("Not an ack object file.\n");
  98. if (outhead.oh_flags & HF_LINK)
  99. fatal("Contains unresolved references.\n");
  100. if (outhead.oh_nrelo > 0)
  101. fprintf(stderr, "Warning: relocation information present.\n");
  102. if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
  103. fatal("Input file must have %d sections, not %ld\n",
  104. NSECT,outhead.oh_nsect) ;
  105. rd_sect(outsect, outhead.oh_nsect);
  106. /* A few checks */
  107. if ( outsect[TEXTSG].os_base != ENTRY)
  108. fatal("text must start at %d not at 0x%lx\n", ENTRY,
  109. outsect[TEXTSG].os_base) ;
  110. if ( outsect[BSSSG].os_flen != 0 )
  111. fatal("bss space contains initialized data\n") ;
  112. if ( ! follows(&outsect[BSSSG], &outsect[DATASG]))
  113. fatal("bss segment must follow data segment\n") ;
  114. if ( outsect[ROMSG].os_lign == 0x8000 ) {
  115. /* 410 file with ROMSG in data space */
  116. if ( ! follows(&outsect[DATASG], &outsect[ROMSG]))
  117. fatal("data segment must follow rom\n") ;
  118. rom_in_data = 1;
  119. magic= NMAGIC ;
  120. textsize= outsect[TEXTSG].os_size ;
  121. datasize= outsect[BSSSG].os_base - outsect[ROMSG].os_base ;
  122. outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
  123. outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
  124. } else
  125. if ( outsect[DATASG].os_lign == 0x8000 ) {
  126. /* 410 file with ROMSG in instruction space */
  127. if ( ! follows(&outsect[ROMSG], &outsect[TEXTSG]))
  128. fatal("rom segment must follow text\n") ;
  129. rom_in_data = 0;
  130. magic= NMAGIC ;
  131. outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
  132. textsize= outsect[TEXTSG].os_size + outsect[ROMSG].os_size ;
  133. outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
  134. datasize= outsect[DATASG].os_size ;
  135. } else {
  136. /* Plain 407 file */
  137. if ( ! follows(&outsect[ROMSG], &outsect[TEXTSG]))
  138. fatal("rom segment must follow text\n") ;
  139. if ( ! follows(&outsect[DATASG], &outsect[ROMSG]))
  140. fatal("data segment must follow rom\n") ;
  141. rom_in_data = 1;
  142. magic= FMAGIC ;
  143. outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
  144. outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
  145. outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
  146. textsize= outsect[TEXTSG].os_size ;
  147. datasize= outsect[ROMSG].os_size + outsect[DATASG].os_size ;
  148. }
  149. bsssize = outsect[BSSSG].os_size;
  150. if ( outhead.oh_nsect==NSECT ) {
  151. if ( ! follows(&outsect[LSECT], &outsect[BSSSG]))
  152. fatal("end segment must follow bss\n") ;
  153. if ( outsect[LSECT].os_size != 0 )
  154. fatal("end segment must be empty\n") ;
  155. }
  156. bh.fmagic = magic;
  157. bh.tsize = textsize;
  158. bh.bsize = bsssize;
  159. bh.dsize = datasize;
  160. bh.entry = ENTRY;
  161. /* Action at last */
  162. fseek(output,(long) TOT_HDRSIZE,0);
  163. emits(&outsect[TEXTSG]) ;
  164. emits(&outsect[ROMSG]) ;
  165. emits(&outsect[DATASG]) ;
  166. symstart = ftell(output);
  167. emit_symtab();
  168. bh.ssize = ftell(output) - symstart;
  169. fseek(output,0L,0);
  170. write_header(&bh);
  171. if ( ferror(output) ) {
  172. fatal("output write error\n") ;
  173. }
  174. if ( outputfile_created ) chmod(argv[2],0755);
  175. return 0;
  176. }
  177. /*
  178. * Transfer the emitted byted from one file to another.
  179. */
  180. emits(section) struct outsect *section ; {
  181. char *p;
  182. char *calloc();
  183. rd_outsect(section - outsect);
  184. if (!(p = calloc(section->os_size, 1))) {
  185. fatal("No memory.\n");
  186. }
  187. rd_emit(p, section->os_flen);
  188. writef(p, 1, section->os_size);
  189. free(p);
  190. }
  191. emit_symtab()
  192. {
  193. struct outname *ACK_names;
  194. register unsigned short i;
  195. register struct outname *A;
  196. register char x;
  197. register char *p;
  198. extern char *malloc(), *calloc();
  199. long l;
  200. long off = OFF_CHAR(outhead);
  201. char *chars;
  202. if ((unsigned) outhead.oh_nchar != outhead.oh_nchar ||
  203. !( chars = malloc((unsigned) outhead.oh_nchar))) {
  204. fatal("No memory\n.");
  205. }
  206. rd_string(chars,outhead.oh_nchar);
  207. if ((unsigned) outhead.oh_nname != outhead.oh_nname ||
  208. !(A = (struct outname *)
  209. calloc(outhead.oh_nname, sizeof(struct outname)))) {
  210. fatal("No memory.\n");
  211. }
  212. ACK_names = A;
  213. rd_name(ACK_names, outhead.oh_nname);
  214. for (i = 0; i < outhead.oh_nname; i++, A++) {
  215. if ((A->on_type & S_TYP) >= S_MIN + LSECT ||
  216. A->on_foff == 0) continue;
  217. switch(A->on_type & S_TYP) {
  218. case S_UND:
  219. x = N_UNDF;
  220. break;
  221. case S_ABS:
  222. x = N_ABS;
  223. break;
  224. case S_MIN + TEXTSG:
  225. x = N_TEXT;
  226. break;
  227. case S_MIN + ROMSG:
  228. x = (rom_in_data ? N_DATA : N_TEXT);
  229. break;
  230. case S_MIN + DATASG:
  231. x = N_DATA;
  232. break;
  233. case S_MIN + BSSSG:
  234. x = N_BSS;
  235. break;
  236. default:
  237. fprintf(stderr,"warning: unknown s_type: %d\n",
  238. A->on_type & S_TYP);
  239. }
  240. if (A->on_type & S_EXT) x |= N_EXT;
  241. putc(x,output);
  242. putc(0,output);
  243. write_long(A->on_valu);
  244. l = A->on_foff - off;
  245. if (l < 0 || l >= outhead.oh_nchar) {
  246. fatal("bad on_off: %ld\n",l);
  247. }
  248. p = &chars[l];
  249. while (x = *p++) {
  250. putc(x,output);
  251. }
  252. putc('\0',output);
  253. }
  254. }
  255. write_long(l)
  256. register long l;
  257. {
  258. /* write long "l" in 68000 order
  259. */
  260. putc((int) (l >> 24), output);
  261. putc((int) (l >> 16), output);
  262. putc((int) (l >> 8), output);
  263. putc((int) l, output);
  264. }
  265. write_header(h)
  266. register struct bhdr *h;
  267. {
  268. write_long(h->fmagic);
  269. write_long(h->tsize);
  270. write_long(h->dsize);
  271. write_long(h->bsize);
  272. write_long(h->ssize);
  273. write_long(h->rtsize);
  274. write_long(h->rdsize);
  275. write_long(h->entry);
  276. }
  277. /* VARARGS1 */
  278. fatal(s, a1, a2)
  279. char *s;
  280. {
  281. fprintf(stderr,"%s: ",program) ;
  282. fprintf(stderr, s, a1, a2);
  283. if (outputfile_created)
  284. unlink(output_file);
  285. exit(-1);
  286. }
  287. rd_fatal() { fatal("read error.\n"); }