*** empty log message ***
This commit is contained in:
		
							parent
							
								
									0db1db10b8
								
							
						
					
					
						commit
						8cbd17b1ba
					
				
					 1 changed files with 385 additions and 0 deletions
				
			
		
							
								
								
									
										385
									
								
								mach/m68k2/cv/cv.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								mach/m68k2/cv/cv.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,385 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include "out.h" | ||||
| 
 | ||||
| #ifndef NORCSID | ||||
| static char rcs_id[] = "$Header$" ; | ||||
| #endif | ||||
| 
 | ||||
| /* BUG:
 | ||||
|    There is a problem with Bleasdale 'nm' and the namelist produced | ||||
|    by this program. | ||||
|    nm always acts as if there were no name list, while adb | ||||
|    understands a.out's with namelists without any complaint. | ||||
|    The cause is unclear. All sizes in the header and file are correct. | ||||
|    Setting the symbol table size to a size smaller than actually | ||||
|    present in the a.out causes 'adb' to produce error messages | ||||
|    about name list problems, but nm suddenly prints the namelist, | ||||
|    INCLUDING the entrie outside the size indicated in the a.out header. | ||||
| */ | ||||
| #define ASSERT(x) switch (2) { case 0: case (x): ; } | ||||
| 
 | ||||
| /*
 | ||||
|  * Header and section table of new format object file. | ||||
|  */ | ||||
| struct outhead	outhead; | ||||
| struct outsect	outsect[S_MAX]; | ||||
| char		*stringarea ; | ||||
| 
 | ||||
| char	*output_file; | ||||
| int	output_file_created; | ||||
| 
 | ||||
| char *program ; | ||||
| 
 | ||||
| char flag ; | ||||
| 
 | ||||
| #define readf(a, b, c)	fread((a), (b), (int)(c), input) | ||||
| #define writef(a, b, c)	fwrite((a), (b), (int)(c), output) | ||||
| 
 | ||||
| /* Output file definitions and such */ | ||||
| 
 | ||||
| #define HDR_LENGTH	32 | ||||
| 
 | ||||
| char hdr[HDR_LENGTH] ; | ||||
| 
 | ||||
| #define TEXT	0 | ||||
| #define ROM	1 | ||||
| #define DATA	2 | ||||
| #define BSS	3 | ||||
| #define LSECT	BSS+1 | ||||
| #define NSECT	LSECT+1 | ||||
| 
 | ||||
| 
 | ||||
| #define N_EXT	040 | ||||
| #define N_UNDEF	00 | ||||
| #define N_ABS	01 | ||||
| #define N_TEXT	02 | ||||
| #define N_DATA	03 | ||||
| #define N_BSS	04 | ||||
| #define N_FN	037 | ||||
| 
 | ||||
| FILE		*input; | ||||
| FILE		*output; | ||||
| 
 | ||||
| main(argc, argv) | ||||
| 	int	argc; | ||||
| 	char	*argv[]; | ||||
| { | ||||
| 	register int		nsect; | ||||
| 	long			magic ; | ||||
| 	long			textsize ; | ||||
| 	long			datasize ; | ||||
| 
 | ||||
| 	ASSERT(sizeof(struct outhead) == SZ_HEAD); | ||||
| 	ASSERT(sizeof(struct outsect) == SZ_SECT); | ||||
| 
 | ||||
| 	input = stdin; output = stdout; | ||||
| 	program= argv[0] ; | ||||
| 	if ( argc>1 && argv[1][0]=='-' ) { | ||||
| 		flag=argv[1][1] ; | ||||
| 		argc-- ; argv++ ; | ||||
| 	} | ||||
| 	switch (argc) { | ||||
| 	case 1:	break; | ||||
| 	case 3:	if ((output = fopen(argv[2], "w")) == (FILE *)0) | ||||
| 			fatal("Can't write %s.\n", argv[2]); | ||||
| 		output_file = argv[2]; | ||||
| 		output_file_created = 1; | ||||
| 		/* FALLTHROUGH */ | ||||
| 	case 2:	if ((input = fopen(argv[1], "r")) == (FILE *)0) | ||||
| 			fatal("Can't read %s.\n", argv[1]); | ||||
| 		break; | ||||
| 	default:fatal("Usage: %s <as object> <dl object>.\n", argv[0]); | ||||
| 	} | ||||
| 	if ( !rhead(input,&outhead) ) | ||||
| 		fatal("Reading header failed.\n"); | ||||
| 	if (BADMAGIC(outhead)) | ||||
| 		fatal("Not an ack object file.\n"); | ||||
| 	if (outhead.oh_nrelo > 0) | ||||
| 		fprintf(stderr, "Warning: relocation information present.\n"); | ||||
| 	if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT ) | ||||
| 		fatal("Input file must have %d sections, not %ld\n", | ||||
| 			NSECT,outhead.oh_nsect) ; | ||||
| 	for ( nsect=0 ; nsect<outhead.oh_nsect ; nsect++ ) | ||||
| 		if ( !rsect(input,&outsect[nsect]) ) | ||||
| 			fatal("Reading section table failed.\n"); | ||||
| 	/* A few checks */ | ||||
| 	if ( outsect[TEXT].os_base != 0x20000 ) | ||||
| 		fatal("text must start at 0x20000 not at 0x%lx\n", | ||||
| 			outsect[TEXT].os_base) ; | ||||
| 	if ( outsect[BSS].os_flen != 0 ) | ||||
| 		fatal("bss space contains initialized data\n") ; | ||||
| 	if ( outsect[BSS].os_base != outsect[DATA].os_base+ | ||||
| 					outsect[DATA].os_size ) | ||||
| 		fatal("bss segment must follow data segment\n") ; | ||||
| 	if ( outsect[ROM].os_lign == 0x8000 ) { | ||||
| 		/* 410 file with ROM in data space */ | ||||
| 		magic= 0410 ; | ||||
| 		textsize= outsect[TEXT].os_size ; | ||||
| 		datasize= outsect[ROM].os_size + outsect[DATA].os_size ; | ||||
| 		if ( outsect[DATA].os_base != outsect[ROM].os_base+ | ||||
| 						outsect[ROM].os_size ) | ||||
| 			fatal("data segment must follow rom\n") ; | ||||
| 	} else | ||||
| 	if ( outsect[DATA].os_lign == 0x8000 ) { | ||||
| 		/* 410 file with ROM in instruction space */ | ||||
| 		magic= 0410 ; | ||||
| 		textsize= outsect[TEXT].os_size + outsect[ROM].os_size ; | ||||
| 		datasize= outsect[DATA].os_size ; | ||||
| 		if ( outsect[ROM].os_base != outsect[TEXT].os_base+ | ||||
| 						outsect[TEXT].os_size ) | ||||
| 			fatal("rom segment must follow text\n") ; | ||||
| 	} else { | ||||
| 		/* Plain 407 file */ | ||||
| 		magic= 0407 ; | ||||
| 		textsize= outsect[TEXT].os_size ; | ||||
| 		datasize= outsect[ROM].os_size + outsect[DATA].os_size ; | ||||
| 		if ( outsect[ROM].os_base != outsect[TEXT].os_base+ | ||||
| 						outsect[TEXT].os_size ) | ||||
| 			fatal("rom segment must follow text\n") ; | ||||
| 		if ( outsect[DATA].os_base != outsect[ROM].os_base+ | ||||
| 						outsect[ROM].os_size ) | ||||
| 			fatal("data segment must follow rom\n") ; | ||||
| 	} | ||||
| 	if ( outhead.oh_nsect==NSECT ) { | ||||
| 		if ( outsect[LSECT].os_base != outsect[BSS].os_base+ | ||||
| 						outsect[BSS].os_size ) | ||||
| 			fatal("end segment must follow bss\n") ; | ||||
| 		if ( outsect[LSECT].os_size != 0 ) | ||||
| 			fatal("end segment must be empty\n") ; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Action at last */ | ||||
| 	fseek(output,(long)sizeof(hdr),0); | ||||
| 	emits(&outsect[TEXT]) ; | ||||
| 	emits(&outsect[ROM]) ; | ||||
| 	emits(&outsect[DATA]) ; | ||||
| 	names() ; | ||||
| 	set4(hdr,0,magic) ; | ||||
| 	set4(hdr,4,textsize) ; | ||||
| 	set4(hdr,8,datasize) ; | ||||
| 	set4(hdr,12,outsect[BSS].os_size) ; | ||||
| 	set4(hdr,28,0x20000L) ;	/* Entry point */ | ||||
| 	fseek(output,0L,0); | ||||
| 	fwrite(hdr,sizeof(hdr),1,output); | ||||
| 	if ( ferror(output) ) { | ||||
| 		fatal("output write error\n") ; | ||||
| 	} | ||||
| 	if ( output_file_created ) chmod(argv[2],0755); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Transfer the emitted byted from one file to another. | ||||
|  * and zero fill the uninitialized space | ||||
|  */ | ||||
| emits(section) struct outsect *section ; { | ||||
| 	register long	n ; | ||||
| 	register int	blk; | ||||
| 	char		buffer[BUFSIZ]; | ||||
| 
 | ||||
| 	n= section->os_flen ; | ||||
| 	while (n > 0) { | ||||
| 		blk = n > BUFSIZ ? BUFSIZ : n; | ||||
| 		readf(buffer, 1, blk); | ||||
| 		writef(buffer, 1, blk); | ||||
| 		n -= blk; | ||||
| 	} | ||||
| 	if ( section->os_flen!=section->os_size ) { | ||||
| 		for ( n=BUFSIZ-1 ; n ; n-- ) buffer[n]=0 ; | ||||
| 		n= section->os_size - section->os_flen ; | ||||
| 		while (n > 0) { | ||||
| 			blk = n > BUFSIZ ? BUFSIZ : n; | ||||
| 			writef(buffer, 1, blk); | ||||
| 			n -= blk; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Copy the name table, except the last outhead.oh_nsect. | ||||
|  * These are assumed to be section names. | ||||
|  * | ||||
|  */ | ||||
| names() | ||||
| { | ||||
| 	register ushort	n = outhead.oh_nname - outhead.oh_nsect; | ||||
| 	int		type = 0 ; | ||||
| 	struct outname  outname ; | ||||
| 	char		buffer[100] ; | ||||
| 	char		*s1, *s2 ; | ||||
| 	long		length, fullength ; | ||||
| 
 | ||||
| 	fseek(input,OFF_CHAR(outhead),0) ; | ||||
| 	chars() ; | ||||
| 	if ( !stringarea ) return ; | ||||
| 	fseek(input,OFF_NAME(outhead),0) ; | ||||
| 	fullength=0 ; buffer[1]=0 ; | ||||
| 	while (n--) { | ||||
| 		rname(input,&outname) ; | ||||
| 		if (outname.on_foff == 0) | ||||
| 			continue ; | ||||
| 		if (outname.on_type & S_ETC ) { | ||||
| 			switch (outname.on_type & S_ETC ) { | ||||
| 			/* ???
 | ||||
| 			case S_FIL : | ||||
| 				type |= N_FN ; | ||||
| 			*/ | ||||
| 			case S_COM : | ||||
| 				break ; | ||||
| 			default : | ||||
| 				continue ; | ||||
| 			}  | ||||
| 		} | ||||
| 		set4(buffer,2,outname.on_valu ) ; | ||||
| 		switch (outname.on_type & S_TYP) { | ||||
| 		case S_UND: | ||||
| 			type = N_UNDEF; | ||||
| 			break; | ||||
| 		case S_ABS: | ||||
| 			type = N_ABS; | ||||
| 			break; | ||||
| 		case S_MIN + TEXT: | ||||
| 			type = N_TEXT; | ||||
| 			break; | ||||
| 		case S_MIN + DATA: | ||||
| 			type = N_DATA; | ||||
| 			break; | ||||
| 		case S_MIN + BSS: | ||||
| 		case S_MIN + LSECT: | ||||
| 			type = N_BSS; | ||||
| 			break ; | ||||
| 		} | ||||
| 
 | ||||
| 		if (outname.on_type & S_EXT) | ||||
| 			type |= N_EXT; | ||||
| 		buffer[0]= type ; | ||||
| 		s1=buffer+6 ; s2= stringarea+outname.on_foff-OFF_CHAR(outhead); | ||||
| 		length= 6 ; | ||||
| 		while ( (++length<sizeof buffer) && (*s1++ = *s2++) ) ; | ||||
| 		buffer[sizeof buffer - 1]= 0 ; /* make sure of zero byte */ | ||||
| 		writef(buffer, length, 1); | ||||
| 		fullength += length ; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * The last outhead.oh_nsect names are discarded. | ||||
| 	 */ | ||||
| 	fseek(input, (long)(SZ_NAME * outhead.oh_nsect), 1); | ||||
| 	set4(hdr,16,fullength) ; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Grab the string area preceded by the long that indicates its size. | ||||
|  * | ||||
|  */ | ||||
| chars() | ||||
| { | ||||
| 	register long	n = outhead.oh_nchar; | ||||
| 	register int	blk; | ||||
| 	char	 	*curr ; | ||||
| 	extern char	*malloc() ; | ||||
| 
 | ||||
| 	if ( n==0 ) return ; | ||||
| 	if ( (unsigned)n != n ) fatal("string table too large\n") ; | ||||
| 	stringarea= malloc((unsigned)n) ; | ||||
| 	if ( !stringarea ) fatal("string table too large\n") ; | ||||
| 
 | ||||
| 	curr= stringarea ; | ||||
| 	while (n > 0) { | ||||
| 		blk = n > BUFSIZ ? BUFSIZ : n; | ||||
| 		readf(curr, 1, blk); | ||||
| 		curr += blk ; | ||||
| 		n -= blk; | ||||
| 	} | ||||
| } | ||||
| rhead(f,head) struct outhead *head ; FILE *f ; { | ||||
| 	char buf[SZ_HEAD] ; | ||||
| 	if ( fread(buf,SZ_HEAD,1,f)!=1 ) return 0 ; | ||||
| 	iconvert(buf,(char *)head,SF_HEAD) ; | ||||
| 	return 1 ; | ||||
| } | ||||
| 
 | ||||
| rsect(f,sect) struct outsect *sect ; FILE *f ; { | ||||
| 	char buf[SZ_SECT] ; | ||||
| 	if ( fread(buf,SZ_SECT,1,f)!=1 ) return 0 ; | ||||
| 	iconvert(buf,(char *)sect,SF_SECT) ; | ||||
| 	return 1 ; | ||||
| } | ||||
| 
 | ||||
| rrelo(f,relo) struct outrelo *relo ; FILE *f ; { | ||||
| 	char buf[SZ_RELO] ; | ||||
| 	if ( fread(buf,SZ_RELO,1,f)!=1 ) return 0 ; | ||||
| 	iconvert(buf,(char *)relo,SF_RELO) ; | ||||
| 	return 1 ; | ||||
| } | ||||
| 
 | ||||
| rname(f,name) struct outname *name ; FILE *f ; { | ||||
| 	char buf[SZ_NAME] ; | ||||
| 	if ( fread(buf,SZ_NAME,1,f)!=1 ) return 0 ; | ||||
| 	iconvert(buf,(char *)name,SF_NAME) ; | ||||
| 	return 1 ; | ||||
| } | ||||
| 
 | ||||
| iconvert(buf,str,fmt) char *buf, *str, *fmt ; { | ||||
| 	register char *nf, *ni, *no ; | ||||
| 	int last, i ; | ||||
| 	long value ; | ||||
| 	ni=buf ; no=str ; nf=fmt ; | ||||
| 	while ( last = *nf++ ) { | ||||
| 		last -= '0' ; | ||||
| 		if ( last<1 || last >9 ) fatal("illegal out.h format string\n"); | ||||
| 		value=0 ; | ||||
| 		i=last ; | ||||
| 		while ( i-- ) { | ||||
| 			value = (value<<8) + (ni[i]&0xFF) ; | ||||
| 		} | ||||
| 		switch ( last ) { | ||||
| 		case 0 : break ; | ||||
| 		case 1 : *no= value ; break ; | ||||
| 		case 2 : *(unsigned short *)no = value ; break ; | ||||
| 		case 4 : *(long *)no = value ; break ; | ||||
| 		default : | ||||
| 			 fatal("illegal out.h format string\n"); | ||||
| 		} | ||||
| 		ni += last ; no += last ; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| set2(buf,off,val) char *buf ; int val ; { | ||||
| 	buf[off+0]	= val>>8 ; | ||||
| 	buf[off+1]	= val ; | ||||
| } | ||||
| 
 | ||||
| set4(buf,off,val) char *buf ; long val ; { | ||||
| 	buf[off]	= val>>24 ; | ||||
| 	buf[off+1]	= val>>16 ; | ||||
| 	buf[off+2]	= val>>8 ; | ||||
| 	buf[off+3]	= val ; | ||||
| } | ||||
| 
 | ||||
| /* VARARGS1 */ | ||||
| fatal(s, a1, a2) | ||||
| 	char	*s; | ||||
| { | ||||
| 	fprintf(stderr,"%s: ",program) ; | ||||
| 	fprintf(stderr, s, a1, a2); | ||||
| 	if (output_file_created) | ||||
| 		unlink(output_file); | ||||
| 	exit(-1); | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue