cv.c 7.0 KB

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