cv.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. /*
  8. * Fortunately we sold our PMDS machine. Unfortunately, we also sold the
  9. * documentation that came with it, so I don't know the a.out format
  10. * of the machine. This program is written partly by guessing, and partly from
  11. * an older conversion program for the PMDS, which put the whole program
  12. * in data. The produced object file does not contain a namelist.
  13. */
  14. #include <stdio.h>
  15. #include <out.h>
  16. #define ASSERT(x) switch (2) { case 0: case (x): ; }
  17. /*
  18. * Header and section table of new format object file.
  19. */
  20. struct outhead outhead;
  21. struct outsect outsect[S_MAX];
  22. char *output_file;
  23. int outputfile_created;
  24. int rom_in_data;
  25. char *program ;
  26. char flag ;
  27. #define writef(a, b, c) fwrite((a), (b), (int)(c), output)
  28. /* Output file definitions and such */
  29. #define ENTRY 0
  30. #define HDRSIZE 40
  31. char hdr[HDRSIZE];
  32. #define TEXTSG 0
  33. #define ROMSG 1
  34. #define DATASG 2
  35. #define BSSSG 3
  36. #define LSECT BSSSG+1
  37. #define NSECT LSECT+1
  38. FILE *output;
  39. long align(a,b)
  40. long a,b;
  41. {
  42. a += b - 1;
  43. return a - a % b;
  44. }
  45. int
  46. follows(pa, pb)
  47. register struct outsect *pa, *pb;
  48. {
  49. /* return 1 if pa follows pb */
  50. return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
  51. }
  52. main(argc, argv)
  53. int argc;
  54. char *argv[];
  55. {
  56. register int nsect;
  57. long magic ;
  58. long textsize ;
  59. long datasize ;
  60. long bsssize;
  61. long symstart;
  62. extern long ftell();
  63. output = stdout;
  64. program= argv[0] ;
  65. if ( argc>1 && argv[1][0]=='-' ) {
  66. flag=argv[1][1] ;
  67. argc-- ; argv++ ;
  68. }
  69. switch (argc) {
  70. case 3: if ((output = fopen(argv[2], "w")) == (FILE *)0)
  71. fatal("Can't write %s.\n", argv[2]);
  72. output_file = argv[2];
  73. outputfile_created = 1;
  74. if (! rd_open(argv[1]))
  75. fatal("Can't read %s.\n", argv[1]);
  76. break;
  77. default:fatal("Usage: %s <ACK object> <Mantra object>.\n", argv[0]);
  78. }
  79. rd_ohead(&outhead);
  80. if (BADMAGIC(outhead))
  81. fatal("Not an ack object file.\n");
  82. if (outhead.oh_flags & HF_LINK)
  83. fatal("Contains unresolved references.\n");
  84. if (outhead.oh_nrelo > 0)
  85. fprintf(stderr, "Warning: relocation information present.\n");
  86. if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
  87. fatal("Input file must have %d sections, not %ld\n",
  88. NSECT,outhead.oh_nsect) ;
  89. rd_sect(outsect, outhead.oh_nsect);
  90. /* A few checks */
  91. if ( outsect[TEXTSG].os_base != ENTRY)
  92. fatal("text must start at %d not at 0x%lx\n", ENTRY,
  93. outsect[TEXTSG].os_base) ;
  94. if ( outsect[BSSSG].os_flen != 0 )
  95. fatal("bss space contains initialized data\n") ;
  96. if (! follows(&outsect[BSSSG], &outsect[DATASG]))
  97. fatal("bss segment must follow data segment\n") ;
  98. if ( outsect[ROMSG].os_lign == 0x8000 ) {
  99. /* 410 file with ROMSG in data space */
  100. rom_in_data = 1;
  101. magic= 0410 ;
  102. if (! follows(&outsect[DATASG], &outsect[ROMSG]))
  103. fatal("data segment must follow rom\n") ;
  104. textsize= outsect[TEXTSG].os_size ;
  105. outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
  106. outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
  107. datasize= outsect[ROMSG].os_size + outsect[DATASG].os_size ;
  108. } else
  109. if ( outsect[DATASG].os_lign == 0x8000 ) {
  110. /* 410 file with ROMSG in instruction space */
  111. rom_in_data = 0;
  112. magic= 0410 ;
  113. if (! follows(&outsect[ROMSG], &outsect[TEXTSG]))
  114. fatal("rom segment must follow text\n") ;
  115. outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
  116. textsize= outsect[TEXTSG].os_size + outsect[ROMSG].os_size ;
  117. outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
  118. datasize= outsect[DATASG].os_size ;
  119. } else {
  120. /* Plain 407 file */
  121. rom_in_data = 1;
  122. magic= 0407 ;
  123. if (! follows(&outsect[ROMSG], &outsect[TEXTSG]))
  124. fatal("rom segment must follow text\n") ;
  125. if (! follows(&outsect[DATASG], &outsect[ROMSG]))
  126. fatal("data segment must follow rom\n") ;
  127. outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
  128. outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
  129. outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
  130. textsize= outsect[TEXTSG].os_size ;
  131. datasize= outsect[ROMSG].os_size + outsect[DATASG].os_size ;
  132. }
  133. bsssize = outsect[BSSSG].os_size;
  134. if ( outhead.oh_nsect==NSECT ) {
  135. if (! follows(&outsect[LSECT], &outsect[BSSSG]))
  136. fatal("end segment must follow bss\n") ;
  137. if ( outsect[LSECT].os_size != 0 )
  138. fatal("end segment must be empty\n") ;
  139. }
  140. /* Action at last */
  141. fseek(output,(long) HDRSIZE,0);
  142. emits(&outsect[TEXTSG]) ;
  143. emits(&outsect[ROMSG]) ;
  144. emits(&outsect[DATASG]) ;
  145. fseek(output,0L,0);
  146. sethdr(0, (long) magic);
  147. sethdr(4, textsize);
  148. sethdr(8, datasize);
  149. sethdr(12, bsssize);
  150. writef(hdr, 1, 40);
  151. if ( ferror(output) ) {
  152. fatal("output write error\n") ;
  153. }
  154. if ( outputfile_created ) chmod(argv[2],0755);
  155. return 0;
  156. }
  157. sethdr(off,val) long val ; {
  158. hdr[off] = val>>24 ;
  159. hdr[off+1] = val>>16 ;
  160. hdr[off+2] = val>>8 ;
  161. hdr[off+3] = val ;
  162. }
  163. /*
  164. * Transfer the emitted byted from one file to another.
  165. */
  166. emits(section) struct outsect *section ; {
  167. char *p;
  168. char *calloc();
  169. long length = section->os_size;
  170. rd_outsect(section - outsect);
  171. while (section->os_size > 0) {
  172. int i = section->os_size > 10*1024 ? 10*1024 : section->os_size;
  173. section->os_size -= i;
  174. if (!(p = calloc(i, 1))) {
  175. fatal("No memory.\n");
  176. }
  177. rd_emit(p, i >= section->os_flen ? section->os_flen:(long) i);
  178. section->os_flen -= i;
  179. writef(p, 1, i);
  180. free(p);
  181. }
  182. }
  183. /* VARARGS1 */
  184. fatal(s, a1, a2)
  185. char *s;
  186. {
  187. fprintf(stderr,"%s: ",program) ;
  188. fprintf(stderr, s, a1, a2);
  189. if (outputfile_created)
  190. unlink(output_file);
  191. exit(-1);
  192. }
  193. rd_fatal() { fatal("read error.\n"); }