cv.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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. #include <stdio.h>
  7. #include "out.h"
  8. #ifndef NORCSID
  9. static char rcs_id[] = "$Id$" ;
  10. #endif
  11. /* BUG:
  12. There is a problem with Bleasdale 'nm' and the namelist produced
  13. by this program.
  14. nm always acts as if there were no name list, while adb
  15. understands a.out's with namelists without any complaint.
  16. The cause is unclear. All sizes in the header and file are correct.
  17. Setting the symbol table size to a size smaller than actually
  18. present in the a.out causes 'adb' to produce error messages
  19. about name list problems, but nm suddenly prints the namelist,
  20. INCLUDING the entrie outside the size indicated in the a.out header.
  21. */
  22. #define ASSERT(x) switch (2) { case 0: case (x): ; }
  23. /*
  24. * Header and section table of new format object file.
  25. */
  26. struct outhead outhead;
  27. struct outsect outsect[S_MAX];
  28. char *stringarea ;
  29. char *ofile;
  30. int ofile_created;
  31. char *program ;
  32. char flag ;
  33. #define readf(a, b, c) fread((a), (b), (int)(c), input)
  34. #define writef(a, b, c) fwrite((a), (b), (int)(c), output)
  35. /* Output file definitions and such */
  36. #define HDR_LENGTH 32
  37. char hdr[HDR_LENGTH] ;
  38. #define TEXT 0
  39. #define ROM 1
  40. #define DATA 2
  41. #define BSS 3
  42. #define LSECT BSS+1
  43. #define NSECT LSECT+1
  44. #define N_EXT 040
  45. #define N_UNDEF 00
  46. #define N_ABS 01
  47. #define N_TEXT 02
  48. #define N_DATA 03
  49. #define N_BSS 04
  50. #define N_FN 037
  51. FILE *input;
  52. FILE *output;
  53. long align(a,b)
  54. long a,b;
  55. {
  56. a += b - 1;
  57. return a - a % b;
  58. }
  59. int
  60. follows(pa, pb)
  61. register struct outsect *pa, *pb;
  62. {
  63. /* return 1 if pa follows pb */
  64. return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
  65. }
  66. main(argc, argv)
  67. int argc;
  68. char *argv[];
  69. {
  70. register int nsect;
  71. long magic ;
  72. long textsize ;
  73. long datasize ;
  74. ASSERT(sizeof(struct outhead) == SZ_HEAD);
  75. ASSERT(sizeof(struct outsect) == SZ_SECT);
  76. input = stdin; 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: break;
  84. case 3: if ((output = fopen(argv[2], "w")) == (FILE *)0)
  85. fatal("Can't write %s.\n", argv[2]);
  86. ofile = argv[2];
  87. ofile_created = 1;
  88. /* FALLTHROUGH */
  89. case 2: if ((input = fopen(argv[1], "r")) == (FILE *)0)
  90. fatal("Can't read %s.\n", argv[1]);
  91. break;
  92. default:fatal("Usage: %s <as object> <dl object>.\n", argv[0]);
  93. }
  94. if ( !rhead(input,&outhead) )
  95. fatal("Reading header failed.\n");
  96. if (BADMAGIC(outhead))
  97. fatal("Not an ack object file.\n");
  98. if (outhead.oh_nrelo > 0)
  99. fprintf(stderr, "Warning: relocation information present.\n");
  100. if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
  101. fatal("Input file must have %d sections, not %ld\n",
  102. NSECT,outhead.oh_nsect) ;
  103. for ( nsect=0 ; nsect<outhead.oh_nsect ; nsect++ )
  104. if ( !rsect(input,&outsect[nsect]) )
  105. fatal("Reading section table failed.\n");
  106. /* A few checks */
  107. if ( outsect[TEXT].os_base != 0x20000 )
  108. fatal("text must start at 0x20000 not at 0x%lx\n",
  109. outsect[TEXT].os_base) ;
  110. if ( outsect[BSS].os_flen != 0 )
  111. fatal("bss space contains initialized data\n") ;
  112. if ( ! follows(&outsect[BSS], &outsect[DATA]))
  113. fatal("bss segment must follow data segment\n") ;
  114. if ( outsect[ROM].os_lign == 0x8000 ) {
  115. /* 410 file with ROM in data space */
  116. if ( ! follows(&outsect[DATA], &outsect[ROM]))
  117. fatal("data segment must follow rom\n") ;
  118. magic= 0410 ;
  119. textsize= outsect[TEXT].os_size ;
  120. datasize= outsect[BSS].os_base - outsect[ROM].os_base ;
  121. outsect[ROM].os_size = outsect[DATA].os_base - outsect[ROM].os_base;
  122. outsect[DATA].os_size = outsect[BSS].os_base - outsect[DATA].os_base;
  123. } else
  124. if ( outsect[DATA].os_lign == 0x8000 ) {
  125. /* 410 file with ROM in instruction space */
  126. if ( ! follows(& outsect[ROM], &outsect[TEXT].os_base))
  127. fatal("rom segment must follow text\n") ;
  128. magic= 0410 ;
  129. outsect[TEXT].os_size = outsect[ROM].os_base - outsect[TEXT].os_base;
  130. textsize= outsect[TEXT].os_size + outsect[ROM].os_size ;
  131. datasize= outsect[BSS].os_base - outsect[DATA].os_base ;
  132. outsect[DATA].os_size = datasize;
  133. } else {
  134. /* Plain 407 file */
  135. if ( ! follows(& outsect[ROM], &outsect[TEXT]))
  136. fatal("rom segment must follow text\n") ;
  137. if ( ! follows(& outsect[DATA], &outsect[ROM]))
  138. fatal("data segment must follow rom\n") ;
  139. magic= 0407 ;
  140. outsect[TEXT].os_size = textsize
  141. = outsect[ROM].os_base - outsect[TEXT].os_base;
  142. outsect[ROM].os_size = outsect[DATA].os_base - outsect[ROM].os_base;
  143. outsect[DATA].os_size = outsect[BSS].os_base - outsect[DATA].os_base;
  144. datasize= outsect[ROM].os_size + outsect[DATA].os_size ;
  145. }
  146. if ( outhead.oh_nsect==NSECT ) {
  147. if (! follows(&outsect[LSECT], &outsect[BSS]))
  148. fatal("end segment must follow bss\n") ;
  149. if ( outsect[LSECT].os_size != 0 )
  150. fatal("end segment must be empty\n") ;
  151. }
  152. /* Action at last */
  153. fseek(output,(long)sizeof(hdr),0);
  154. emits(&outsect[TEXT]) ;
  155. emits(&outsect[ROM]) ;
  156. emits(&outsect[DATA]) ;
  157. names() ;
  158. set4(hdr,0,magic) ;
  159. set4(hdr,4,textsize) ;
  160. set4(hdr,8,datasize) ;
  161. set4(hdr,12,outsect[BSS].os_size) ;
  162. set4(hdr,28,0x20000L) ; /* Entry point */
  163. fseek(output,0L,0);
  164. fwrite(hdr,sizeof(hdr),1,output);
  165. if ( ferror(output) ) {
  166. fatal("output write error\n") ;
  167. }
  168. if ( ofile_created ) chmod(argv[2],0755);
  169. return 0;
  170. }
  171. /*
  172. * Transfer the emitted byted from one file to another.
  173. * and zero fill the uninitialized space
  174. */
  175. emits(section) struct outsect *section ; {
  176. register long n ;
  177. register int blk;
  178. char buffer[BUFSIZ];
  179. n= section->os_flen ;
  180. while (n > 0) {
  181. blk = n > BUFSIZ ? BUFSIZ : n;
  182. readf(buffer, 1, blk);
  183. writef(buffer, 1, blk);
  184. n -= blk;
  185. }
  186. if ( section->os_flen!=section->os_size ) {
  187. for ( n=BUFSIZ-1 ; n ; n-- ) buffer[n]=0 ;
  188. n= section->os_size - section->os_flen ;
  189. while (n > 0) {
  190. blk = n > BUFSIZ ? BUFSIZ : n;
  191. writef(buffer, 1, blk);
  192. n -= blk;
  193. }
  194. }
  195. }
  196. /*
  197. * Copy the name table, except the last outhead.oh_nsect.
  198. * These are assumed to be section names.
  199. *
  200. */
  201. names()
  202. {
  203. register unsigned n = outhead.oh_nname - outhead.oh_nsect;
  204. int type = 0 ;
  205. struct outname outname ;
  206. char buffer[100] ;
  207. char *s1, *s2 ;
  208. long length, fullength ;
  209. fseek(input,OFF_CHAR(outhead),0) ;
  210. chars() ;
  211. if ( !stringarea ) return ;
  212. fseek(input,OFF_NAME(outhead),0) ;
  213. fullength=0 ; buffer[1]=0 ;
  214. while (n--) {
  215. rname(input,&outname) ;
  216. if (outname.on_foff == 0)
  217. continue ;
  218. if (outname.on_type & S_ETC ) {
  219. switch (outname.on_type & S_ETC ) {
  220. /* ???
  221. case S_FIL :
  222. type |= N_FN ;
  223. */
  224. case S_COM :
  225. break ;
  226. default :
  227. continue ;
  228. }
  229. }
  230. set4(buffer,2,outname.on_valu ) ;
  231. switch (outname.on_type & S_TYP) {
  232. case S_UND:
  233. type = N_UNDEF;
  234. break;
  235. case S_ABS:
  236. type = N_ABS;
  237. break;
  238. case S_MIN + TEXT:
  239. type = N_TEXT;
  240. break;
  241. case S_MIN + DATA:
  242. type = N_DATA;
  243. break;
  244. case S_MIN + BSS:
  245. case S_MIN + LSECT:
  246. type = N_BSS;
  247. break ;
  248. }
  249. if (outname.on_type & S_EXT)
  250. type |= N_EXT;
  251. buffer[0]= type ;
  252. s1=buffer+6 ; s2= stringarea+outname.on_foff-OFF_CHAR(outhead);
  253. length= 6 ;
  254. while ( (++length<sizeof buffer) && (*s1++ = *s2++) ) ;
  255. buffer[sizeof buffer - 1]= 0 ; /* make sure of zero byte */
  256. writef(buffer, length, 1);
  257. fullength += length ;
  258. }
  259. /*
  260. * The last outhead.oh_nsect names are discarded.
  261. */
  262. fseek(input, (long)(SZ_NAME * outhead.oh_nsect), 1);
  263. set4(hdr,16,fullength) ;
  264. }
  265. /*
  266. * Grab the string area preceded by the long that indicates its size.
  267. *
  268. */
  269. chars()
  270. {
  271. register long n = outhead.oh_nchar;
  272. register int blk;
  273. char *curr ;
  274. extern char *malloc() ;
  275. if ( n==0 ) return ;
  276. if ( (unsigned)n != n ) fatal("string table too large\n") ;
  277. stringarea= malloc((unsigned)n) ;
  278. if ( !stringarea ) fatal("string table too large\n") ;
  279. curr= stringarea ;
  280. while (n > 0) {
  281. blk = n > BUFSIZ ? BUFSIZ : n;
  282. readf(curr, 1, blk);
  283. curr += blk ;
  284. n -= blk;
  285. }
  286. }
  287. rhead(f,head) struct outhead *head ; FILE *f ; {
  288. char buf[SZ_HEAD] ;
  289. if ( fread(buf,SZ_HEAD,1,f)!=1 ) return 0 ;
  290. iconvert(buf,(char *)head,SF_HEAD) ;
  291. return 1 ;
  292. }
  293. rsect(f,sect) struct outsect *sect ; FILE *f ; {
  294. char buf[SZ_SECT] ;
  295. if ( fread(buf,SZ_SECT,1,f)!=1 ) return 0 ;
  296. iconvert(buf,(char *)sect,SF_SECT) ;
  297. return 1 ;
  298. }
  299. rrelo(f,relo) struct outrelo *relo ; FILE *f ; {
  300. char buf[SZ_RELO] ;
  301. if ( fread(buf,SZ_RELO,1,f)!=1 ) return 0 ;
  302. iconvert(buf,(char *)relo,SF_RELO) ;
  303. return 1 ;
  304. }
  305. rname(f,name) struct outname *name ; FILE *f ; {
  306. char buf[SZ_NAME] ;
  307. if ( fread(buf,SZ_NAME,1,f)!=1 ) return 0 ;
  308. iconvert(buf,(char *)name,SF_NAME) ;
  309. return 1 ;
  310. }
  311. iconvert(buf,str,fmt) char *buf, *str, *fmt ; {
  312. register char *nf, *ni, *no ;
  313. int last, i ;
  314. long value ;
  315. ni=buf ; no=str ; nf=fmt ;
  316. while ( last = *nf++ ) {
  317. last -= '0' ;
  318. if ( last<1 || last >9 ) fatal("illegal out.h format string\n");
  319. value=0 ;
  320. i=last ;
  321. while ( i-- ) {
  322. value = (value<<8) + (ni[i]&0xFF) ;
  323. }
  324. switch ( last ) {
  325. case 0 : break ;
  326. case 1 : *no= value ; break ;
  327. case 2 : *(unsigned short *)no = value ; break ;
  328. case 4 : *(long *)no = value ; break ;
  329. default :
  330. fatal("illegal out.h format string\n");
  331. }
  332. ni += last ; no += last ;
  333. }
  334. }
  335. set2(buf,off,val) char *buf ; int val ; {
  336. buf[off+0] = val>>8 ;
  337. buf[off+1] = val ;
  338. }
  339. set4(buf,off,val) char *buf ; long val ; {
  340. buf[off] = val>>24 ;
  341. buf[off+1] = val>>16 ;
  342. buf[off+2] = val>>8 ;
  343. buf[off+3] = val ;
  344. }
  345. /* VARARGS1 */
  346. fatal(s, a1, a2)
  347. char *s;
  348. {
  349. fprintf(stderr,"%s: ",program) ;
  350. fprintf(stderr, s, a1, a2);
  351. if (ofile_created)
  352. unlink(ofile);
  353. exit(-1);
  354. }