cv.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Conversion from ack a.out to Arthur output format.
  3. * All this really does is to output the sections, text first,
  4. * with no header or symbol table information.
  5. *
  6. * Mostly pinched from the code for the m68k2 cv.
  7. * V1.0, 08-Mar-89 AJM
  8. */
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include "out.h"
  12. #include "arm.h"
  13. #define ASSERT(x) switch (2) { case 0: case (x): ; }
  14. /*
  15. * Header and section table of ack object file.
  16. */
  17. struct outhead outhead;
  18. struct outsect outsect[S_MAX];
  19. char *stringarea ;
  20. char *ofile;
  21. int ofile_created;
  22. char *program ;
  23. char flag ;
  24. #define readf(a, b, c) fread((a), (b), (int)(c), input)
  25. #define writef(a, b, c) fwrite((a), (b), (int)(c), output)
  26. /* Output file definitions and such */
  27. #define HDR_LENGTH 32
  28. char hdr[HDR_LENGTH] ;
  29. #define TEXT 0
  30. #define ROM 1
  31. #define DATA 2
  32. #define BSS 3
  33. #define LSECT BSS+1
  34. #define NSECT LSECT+1
  35. #define N_EXT 040
  36. #define N_UNDEF 00
  37. #define N_ABS 01
  38. #define N_TEXT 02
  39. #define N_DATA 03
  40. #define N_BSS 04
  41. #define N_FN 037
  42. FILE *input;
  43. FILE *output;
  44. long align(a,b)
  45. long a,b;
  46. {
  47. a += b - 1;
  48. return a - a % b;
  49. }
  50. int
  51. follows(pa, pb)
  52. register struct outsect *pa, *pb;
  53. {
  54. /* return 1 if pa follows pb */
  55. return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
  56. }
  57. main(argc, argv)
  58. int argc;
  59. char *argv[];
  60. {
  61. register int nsect;
  62. long magic ;
  63. long textsize ;
  64. long datasize ;
  65. long ss;
  66. ASSERT(sizeof(struct outhead) == SZ_HEAD);
  67. ASSERT(sizeof(struct outsect) == SZ_SECT);
  68. input = stdin; output = stdout;
  69. program= argv[0] ;
  70. if ( argc>1 && argv[1][0]=='-' ) {
  71. flag=argv[1][1] ;
  72. argc-- ; argv++ ;
  73. }
  74. switch (argc) {
  75. case 1: break;
  76. case 3: if ((output = fopen(argv[2], "w")) == (FILE *)0)
  77. fatal("Can't write %s.\n", argv[2]);
  78. ofile = argv[2];
  79. ofile_created = 1;
  80. /* FALLTHROUGH */
  81. case 2: if ((input = fopen(argv[1], "r")) == (FILE *)0)
  82. fatal("Can't read %s.\n", argv[1]);
  83. break;
  84. default:fatal("Usage: %s <ack object> <riscos object>.\n", argv[0]);
  85. }
  86. if ( !rhead(input,&outhead) )
  87. fatal("Reading header failed.\n");
  88. if (BADMAGIC(outhead))
  89. fatal("Not an ack object file.\n");
  90. if (outhead.oh_nrelo > 0)
  91. fprintf(stderr, "Warning: relocation information present.\n");
  92. if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
  93. fatal("Input file must have %d sections, not %ld\n",
  94. NSECT,outhead.oh_nsect) ;
  95. for ( nsect=0 ; nsect<outhead.oh_nsect ; nsect++ )
  96. if ( !rsect(input,&outsect[nsect]) )
  97. fatal("Reading section table failed.\n");
  98. /* A few checks */
  99. if ( outsect[TEXT].os_base != 0x8000 )
  100. fatal("text must start at 0x8000 not at 0x%lx\n",
  101. outsect[TEXT].os_base) ;
  102. if ( outsect[BSS].os_flen != 0 )
  103. fatal("bss space contains initialized data\n") ;
  104. if ( ! follows(&outsect[BSS], &outsect[DATA]))
  105. fatal("bss segment must follow data segment\n") ;
  106. if ( ! follows(& outsect[ROM], &outsect[TEXT]))
  107. fatal("rom segment must follow text\n") ;
  108. if ( ! follows(& outsect[DATA], &outsect[ROM]))
  109. fatal("data segment must follow rom\n") ;
  110. if ( outhead.oh_nsect==NSECT ) {
  111. if (! follows(&outsect[LSECT], &outsect[BSS]))
  112. fatal("end segment must follow bss\n") ;
  113. if ( outsect[LSECT].os_size != 0 )
  114. fatal("end segment must be empty\n") ;
  115. }
  116. /* Action at last */
  117. fseek(output,0L,0); /* Start of output file */
  118. emits(&outsect[TEXT]) ; /* Write out the text segment */
  119. emits(&outsect[ROM]) ; /* Then the rom */
  120. emits(&outsect[DATA]) ; /* Then the data */
  121. if ( ferror(output) ) {
  122. fatal("output write error\n") ;
  123. }
  124. if ( ofile_created ) chmod(argv[2],0755);
  125. ss = 0;
  126. printf(" text = %ld\n",outsect[TEXT].os_size);
  127. printf(" rom = %ld\n",outsect[ROM].os_size);
  128. printf(" data = %ld\n",outsect[DATA].os_size);
  129. printf(" bss = %ld\n",outsect[BSS].os_size);
  130. ss += outsect[TEXT].os_size;
  131. ss += outsect[ROM].os_size;
  132. ss += outsect[DATA].os_size;
  133. ss += outsect[BSS].os_size;
  134. printf("Total memory %ld bytes, plus heap and stack\n",ss);
  135. return 0;
  136. }
  137. /*
  138. * Transfer the emitted byted from one file to another.
  139. * and zero fill the uninitialized space
  140. */
  141. emits(section) struct outsect *section ; {
  142. register long n ;
  143. register int blk;
  144. char buffer[BUFSIZ];
  145. n= section->os_flen ;
  146. while (n > 0) {
  147. blk = n > BUFSIZ ? BUFSIZ : n;
  148. readf(buffer, 1, blk);
  149. writef(buffer, 1, blk);
  150. n -= blk;
  151. }
  152. if ( section->os_flen!=section->os_size ) {
  153. for ( n=BUFSIZ-1 ; n ; n-- ) buffer[n]=0 ;
  154. n= section->os_size - section->os_flen ;
  155. while (n > 0) {
  156. blk = n > BUFSIZ ? BUFSIZ : n;
  157. writef(buffer, 1, blk);
  158. n -= blk;
  159. }
  160. }
  161. }
  162. rhead(f,head) struct outhead *head ; FILE *f ; {
  163. char buf[SZ_HEAD] ;
  164. if ( fread(buf,SZ_HEAD,1,f)!=1 ) return 0 ;
  165. iconvert(buf,(char *)head,SF_HEAD) ;
  166. return 1 ;
  167. }
  168. rsect(f,sect) struct outsect *sect ; FILE *f ; {
  169. char buf[SZ_SECT] ;
  170. if ( fread(buf,SZ_SECT,1,f)!=1 ) return 0 ;
  171. iconvert(buf,(char *)sect,SF_SECT) ;
  172. return 1 ;
  173. }
  174. iconvert(buf,str,fmt) char *buf, *str, *fmt ; {
  175. register char *nf, *ni, *no ;
  176. int last, i ;
  177. long value ;
  178. ni=buf ; no=str ; nf=fmt ;
  179. while ( last = *nf++ ) {
  180. last -= '0' ;
  181. if ( last<1 || last >9 ) fatal("illegal out.h format string\n");
  182. value=0 ;
  183. i=last ;
  184. while ( i-- ) {
  185. value = (value<<8) + (ni[i]&0xFF) ;
  186. }
  187. switch ( last ) {
  188. case 0 : break ;
  189. case 1 : *no= value ; break ;
  190. case 2 : *(unsigned short *)no = value ; break ;
  191. case 4 : *(long *)no = value ; break ;
  192. default :
  193. fatal("illegal out.h format string\n");
  194. }
  195. ni += last ; no += last ;
  196. }
  197. }
  198. /* VARARGS1 */
  199. fatal(s, a1, a2)
  200. char *s;
  201. {
  202. fprintf(stderr,"%s: ",program) ;
  203. fprintf(stderr, s, a1, a2);
  204. if (ofile_created)
  205. unlink(ofile);
  206. exit(-1);
  207. }