cv.c 7.0 KB

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