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".
11 static char rcs_id[] = "$Id: cv.c,v 2.6 1994/06/24 13:03:23 ceriel Exp $" ;
15 There is a problem with Bleasdale 'nm' and the namelist produced
17 nm always acts as if there were no name list, while adb
18 understands a.out's with namelists without any complaint.
19 The cause is unclear. All sizes in the header and file are correct.
20 Setting the symbol table size to a size smaller than actually
21 present in the a.out causes 'adb' to produce error messages
22 about name list problems, but nm suddenly prints the namelist,
23 INCLUDING the entrie outside the size indicated in the a.out header.
25 #define ASSERT(x) switch (2) { case 0: case (x): ; }
28 * Header and section table of new format object file.
30 struct outhead outhead;
31 struct outsect outsect[S_MAX];
41 #define readf(a, b, c) fread((a), (b), (int)(c), input)
42 #define writef(a, b, c) fwrite((a), (b), (int)(c), output)
44 /* Output file definitions and such */
48 char hdr[HDR_LENGTH] ;
78 register struct outsect *pa, *pb;
80 /* return 1 if pa follows pb */
82 return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
94 ASSERT(sizeof(struct outhead) == SZ_HEAD);
95 ASSERT(sizeof(struct outsect) == SZ_SECT);
97 input = stdin; output = stdout;
99 if ( argc>1 && argv[1][0]=='-' ) {
105 case 3: if ((output = fopen(argv[2], "w")) == (FILE *)0)
106 fatal("Can't write %s.\n", argv[2]);
110 case 2: if ((input = fopen(argv[1], "r")) == (FILE *)0)
111 fatal("Can't read %s.\n", argv[1]);
113 default:fatal("Usage: %s <as object> <dl object>.\n", argv[0]);
115 if ( !rhead(input,&outhead) )
116 fatal("Reading header failed.\n");
117 if (BADMAGIC(outhead))
118 fatal("Not an ack object file.\n");
119 if (outhead.oh_nrelo > 0)
120 fprintf(stderr, "Warning: relocation information present.\n");
121 if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
122 fatal("Input file must have %d sections, not %ld\n",
123 NSECT,outhead.oh_nsect) ;
124 for ( nsect=0 ; nsect<outhead.oh_nsect ; nsect++ )
125 if ( !rsect(input,&outsect[nsect]) )
126 fatal("Reading section table failed.\n");
128 if ( outsect[TEXT].os_base != 0x20000 )
129 fatal("text must start at 0x20000 not at 0x%lx\n",
130 outsect[TEXT].os_base) ;
131 if ( outsect[BSS].os_flen != 0 )
132 fatal("bss space contains initialized data\n") ;
133 if ( ! follows(&outsect[BSS], &outsect[DATA]))
134 fatal("bss segment must follow data segment\n") ;
135 if ( outsect[ROM].os_lign == 0x8000 ) {
136 /* 410 file with ROM in data space */
137 if ( ! follows(&outsect[DATA], &outsect[ROM]))
138 fatal("data segment must follow rom\n") ;
140 textsize= outsect[TEXT].os_size ;
141 datasize= outsect[BSS].os_base - outsect[ROM].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;
145 if ( outsect[DATA].os_lign == 0x8000 ) {
146 /* 410 file with ROM in instruction space */
147 if ( ! follows(& outsect[ROM], &outsect[TEXT].os_base))
148 fatal("rom segment must follow text\n") ;
150 outsect[TEXT].os_size = outsect[ROM].os_base - outsect[TEXT].os_base;
151 textsize= outsect[TEXT].os_size + outsect[ROM].os_size ;
152 datasize= outsect[BSS].os_base - outsect[DATA].os_base ;
153 outsect[DATA].os_size = datasize;
156 if ( ! follows(& outsect[ROM], &outsect[TEXT]))
157 fatal("rom segment must follow text\n") ;
158 if ( ! follows(& outsect[DATA], &outsect[ROM]))
159 fatal("data segment must follow rom\n") ;
161 outsect[TEXT].os_size = textsize
162 = outsect[ROM].os_base - outsect[TEXT].os_base;
163 outsect[ROM].os_size = outsect[DATA].os_base - outsect[ROM].os_base;
164 outsect[DATA].os_size = outsect[BSS].os_base - outsect[DATA].os_base;
165 datasize= outsect[ROM].os_size + outsect[DATA].os_size ;
167 if ( outhead.oh_nsect==NSECT ) {
168 if (! follows(&outsect[LSECT], &outsect[BSS]))
169 fatal("end segment must follow bss\n") ;
170 if ( outsect[LSECT].os_size != 0 )
171 fatal("end segment must be empty\n") ;
175 fseek(output,(long)sizeof(hdr),0);
176 emits(&outsect[TEXT]) ;
177 emits(&outsect[ROM]) ;
178 emits(&outsect[DATA]) ;
181 set4(hdr,4,textsize) ;
182 set4(hdr,8,datasize) ;
183 set4(hdr,12,outsect[BSS].os_size) ;
184 set4(hdr,28,0x20000L) ; /* Entry point */
186 fwrite(hdr,sizeof(hdr),1,output);
187 if ( ferror(output) ) {
188 fatal("output write error\n") ;
190 if ( ofile_created ) chmod(argv[2],0755);
195 * Transfer the emitted byted from one file to another.
196 * and zero fill the uninitialized space
198 emits(section) struct outsect *section ; {
203 n= section->os_flen ;
205 blk = n > BUFSIZ ? BUFSIZ : n;
206 readf(buffer, 1, blk);
207 writef(buffer, 1, blk);
210 if ( section->os_flen!=section->os_size ) {
211 for ( n=BUFSIZ-1 ; n ; n-- ) buffer[n]=0 ;
212 n= section->os_size - section->os_flen ;
214 blk = n > BUFSIZ ? BUFSIZ : n;
215 writef(buffer, 1, blk);
222 * Copy the name table, except the last outhead.oh_nsect.
223 * These are assumed to be section names.
228 register unsigned n = outhead.oh_nname - outhead.oh_nsect;
230 struct outname outname ;
233 long length, fullength ;
235 fseek(input,OFF_CHAR(outhead),0) ;
237 if ( !stringarea ) return ;
238 fseek(input,OFF_NAME(outhead),0) ;
239 fullength=0 ; buffer[1]=0 ;
241 rname(input,&outname) ;
242 if (outname.on_foff == 0)
244 if (outname.on_type & S_ETC ) {
245 switch (outname.on_type & S_ETC ) {
256 set4(buffer,2,outname.on_valu ) ;
257 switch (outname.on_type & S_TYP) {
276 if (outname.on_type & S_EXT)
279 s1=buffer+6 ; s2= stringarea+outname.on_foff-OFF_CHAR(outhead);
281 while ( (++length<sizeof buffer) && (*s1++ = *s2++) ) ;
282 buffer[sizeof buffer - 1]= 0 ; /* make sure of zero byte */
283 writef(buffer, length, 1);
284 fullength += length ;
287 * The last outhead.oh_nsect names are discarded.
289 fseek(input, (long)(SZ_NAME * outhead.oh_nsect), 1);
290 set4(hdr,16,fullength) ;
294 * Grab the string area preceded by the long that indicates its size.
299 register long n = outhead.oh_nchar;
302 extern char *malloc() ;
305 if ( (unsigned)n != n ) fatal("string table too large\n") ;
306 stringarea= malloc((unsigned)n) ;
307 if ( !stringarea ) fatal("string table too large\n") ;
311 blk = n > BUFSIZ ? BUFSIZ : n;
317 rhead(f,head) struct outhead *head ; FILE *f ; {
319 if ( fread(buf,SZ_HEAD,1,f)!=1 ) return 0 ;
320 iconvert(buf,(char *)head,SF_HEAD) ;
324 rsect(f,sect) struct outsect *sect ; FILE *f ; {
326 if ( fread(buf,SZ_SECT,1,f)!=1 ) return 0 ;
327 iconvert(buf,(char *)sect,SF_SECT) ;
331 rrelo(f,relo) struct outrelo *relo ; FILE *f ; {
333 if ( fread(buf,SZ_RELO,1,f)!=1 ) return 0 ;
334 iconvert(buf,(char *)relo,SF_RELO) ;
338 rname(f,name) struct outname *name ; FILE *f ; {
340 if ( fread(buf,SZ_NAME,1,f)!=1 ) return 0 ;
341 iconvert(buf,(char *)name,SF_NAME) ;
345 iconvert(buf,str,fmt) char *buf, *str, *fmt ; {
346 register char *nf, *ni, *no ;
349 ni=buf ; no=str ; nf=fmt ;
350 while ( last = *nf++ ) {
352 if ( last<1 || last >9 ) fatal("illegal out.h format string\n");
356 value = (value<<8) + (ni[i]&0xFF) ;
360 case 1 : *no= value ; break ;
361 case 2 : *(unsigned short *)no = value ; break ;
362 case 4 : *(long *)no = value ; break ;
364 fatal("illegal out.h format string\n");
366 ni += last ; no += last ;
370 set2(buf,off,val) char *buf ; int val ; {
371 buf[off+0] = val>>8 ;
375 set4(buf,off,val) char *buf ; long val ; {
377 buf[off+1] = val>>16 ;
378 buf[off+2] = val>>8 ;
386 fprintf(stderr,"%s: ",program) ;
387 fprintf(stderr, s, a1, a2);