gcc compiler under ultrix 4.0 (-g opt.)

Michael Meissner meissner at osf.org
Tue Jan 8 13:10:30 AEST 1991


In article <91007.141905DEEJ at MAINE.BITNET> DEEJ at MAINE.BITNET (Dj Merrill) writes:

| I am trying to make the gcc compiler under ultrix 4.0 on a decstation 3100.
| I have followed the instructions (At least I think so..  :-) )
|  
| but am having problems compiling with the -g option.  If I omit this, the
| gcc compiler seems to make okay, but when I do the check to see if the files
| are different, they are.  This would indicate an error of some kind.
| Has anyone run across this problem and have a fix??
|  
| I have tried the    'ar rc /usr/local/lib/libg.a' mentioned in the
| INSTALL file with no luck.

Sigh, I seem to make the same explanation about the MIPS object file
format every month of so (though in different groups).  Here is what I
posted to the gnu newsgroup recently (the debug hacks mentioned are
the patches available for anonymous FTP from foobar.colorado.edu in
the pub/Gnu-For-Pmax directory):

| From: rusty at belch.Berkeley.EDU (Rusty Wright)
| Newsgroups: gnu.gcc.help
| Date: 1 Jan 91 23:32:43 GMT
| Distribution: gnu
| Organization: Computer Center, UC Berkeley
| 
| The suggested method of doing the compares of the .o files for the
| different stages (2 & 3?) no longer works; strip now complains about
| not stripping objects with relocation entries in them.  Does anybody
| have a method for doing the verify?

Here is a perl script that I hacked together to compare MIPS objects
(ie, on a DECstation), section by section.  Without my debug hacks,
expect that you will see differences in the local strings section.
This is because the assembler puts the filename into the file section,
and the filename changes each time, based on the PID of the gcc cover
program.  My debug hacks strip out this filename, since the compiler
provided .file directive identifies the file properly.  My script
expects you to have done a make stage3 after doing the bootstrap.

Alternatively, you could use the fixes the ecoff-cmp that were
recently posted.

#! /usr/bin/perl

# Script to compare gcc binaries in the stage2 and stage3 directories.
# Author: Michael Meissner		meissner at osf.org

sub MAX {
	local($max) = pop(@_);
	foreach $foo (@_) {
		$max = $foo if $max < $foo;
	}
	$max;
}

sub MIN {
	local($min) = pop(@_);
	foreach $foo (@_) {
		$min = $foo if $min > $foo;
	}
	$max;
}

# Arg 1 is the character value as a numeric
# Arg 2 is the character value as a string
# Arg 3 is prefix string
# Arg 4 is suffix string

sub PRINT {
	local ($numeric, $string, $prefix, $suffix) = @_;
	printf ("%s: 0x%.2x %3d %s%s", $prefix, $numeric, $numeric,
		($numeric >= ord (' ') && $numeric <= ord ('~')) ? "'$string'" : "   ",
		$suffix);
}

# Arg 1 is the offset into the beginning of the bytes to compare
# Arg 2 is the length of the bytes to compare
# Arg 3 is the name of the section being compared
# Arg 4 is the secondary name
# Return 1 if the sections are equal, 0 otherwise

sub COMPARE_SECTION {
	local ($offset, $length, $name, $name2) = @_;
	local ($i, $j, $ch2_str, $ch2, $ch3_str, $ch3, $lines, $max, $max2, $chunk_len);

	printf ("comparing offset %10d [0x%.8x], length %10d [0x%.8x], name %s%s\n", $offset, $offset,
		$length, $length, $name, $name2) if ($vflag);

	if ($length == 0) {
		return 1;
	}

	$max = $offset + $length;
	die "Offset $offset is out of bounds in $name\n"	unless ($offset >= 0 && $offset <= length ($bytes2));
	die "Max Offset $max is out of bounds in $name\n"	unless ($max >= 0 && $max <= length ($bytes2));

	if (substr ($bytes2, $offset, $length) eq substr ($bytes3, $offset, $length)) {
		return 1;
	}

	$lines = 0;
	for ($i = $offset; $i < $max; $i += 8192) {
		$chunk_len = ($i + 8192 <= $max) ? 8192 : ($max - $i);
		if (substr ($bytes2, $i, $chunk_len) ne substr ($bytes3, $i, $chunk_len)) {
			$max2 = $i + $chunk_len;
			for ($j = $i; $j < $max2; $j++) {
				$ch2_str = substr ($bytes2, $j, 1);
				$ch3_str = substr ($bytes3, $j, 1);
				$ch2 = ord ($ch2_str);
				$ch3 = ord ($ch3_str);
				if ($ch2 != $ch3) {
					&PRINT ($ch2, $ch2_str,
						("\t" . $name . $name2 . ' ' . sprintf ($size_format,$i) . ": stage2"),
						' ');

					&PRINT ($ch3, $ch3_str, "stage3", "\n");
					if (++$lines > 20) {
						print "\tSkipping remaining differences\n";
						return 0;
					}
				}
			}
		}
	}
}

# Set up global variables relating to MIPS offsets
sub SET_UP_MIPS {
	local ($i);

	# Mips filehdr looks like:
	# unsigned short	f_magic		 0	magic number
	# unsigned short	f_nscns		 2	number of sections
	# long			f_timdat	 4	time & date stamp
	# long			f_symptr	 8	file pointer to symbolic header
	# long			f_nsyms		12	sizeof(symbolic hdr)
	# unsigned short	f_opthdr	16	sizeof(optional hdr)
	# unsigned short	f_flags		18	flags
	#					20	size of filehdr

	$filehdr_unpack = 'SSLLLSS';
	$filehdr_size   = 20;
	$i = $[;			# array indices after unpacking
	$f_magic  = $i++;
	$f_nscns  = $i++;
	$f_timdat = $i++;
	$f_symptr = $i++;
	$f_nsyms  = $i++;
	$f_opthdr = $i++;
	$f_flags  = $i++;

	# Each section header looks like
	# char		 s_name[8]	 0	section name
	# long		 s_paddr	 8	physical address, aliased s_nlib
	# long		 s_vaddr	12	virtual address
	# long		 s_size		16	section size
	# long		 s_scnptr	20	file ptr to raw data for section
	# long		 s_relptr	24	file ptr to relocation
	# long		 s_lnnoptr	28	file ptr to gp histogram
	# unsigned short s_nreloc	32	number of relocation entries
	# unsigned short s_nlnno	34	number of gp histogram entries
	# long		 s_flags	36	flags
	#				40	size of scnhdr

	$scnhdr_unpack = 'A8LLLLLLSSL';
	$scnhdr_size   = 40;
	$i = $[;			# array indices after unpacking
	$s_name    = $i++;
	$s_paddr   = $i++;
	$s_vaddr   = $i++;
	$s_size    = $i++;
	$s_scnptr  = $i++;
	$s_relptr  = $i++;
	$s_lnnoptr = $i++;
	$s_nreloc  = $i++;
	$s_nlnno   = $i++;
	$s_flags   = $i++;

	# Each relocation entry looks like
	# long		r_vaddr		0 /* virtual address of reference */
	# unsigned	r_symndx   :24	4 /* index into symbol table */
	# unsigned	r_reserved : 3	4
	# unsigned	r_type     : 4	4 /* relocation type */
	# unsigned	r_extern   : 1	4 /* ext. sym table vs. section # */
	#				8

	$reloc_unpack = 'LL';
	$reloc_size   = 8;
	$i = $[;			# array indices after unpacking
	$r_vaddr	     = $i++;
	$r_index_type_extern = $i++;

	# Each gp entry looks like:
	# long		g_value;	0 /* real/hypothetical value */
	# long		bytes;		4 /* section size if hypothetical value */
	#				8
	
	$gp_unpack = 'LL';
	$gp_size   = 8;
	$i = $[;			# array indices after unpacking
	$g_value = $i++;
	$g_bytes = $i++;

	# The symbol table header looks like:
	# short	magic		 0	to verify validity of the table
	# short	vstamp		 2	version stamp
	# long	ilineMax	 4	number of line number entries
	# long	cbLine		 8	number of bytes for line number entries
	# long	cbLineOffset	12	offset to start of line number entries
	# long	idnMax		16	max index into dense number table
	# long	cbDnOffset	20	offset to start dense number table
	# long	ipdMax		24	number of procedures
	# long	cbPdOffset	28	offset to procedure descriptor table
	# long	isymMax		32	number of local symbols
	# long	cbSymOffset	36	offset to start of local symbol
	# long	ioptMax		40	max index into optimization symbol entries
	# long	cbOptOffset	44	offset to optimization symbol entries
	# long	iauxMax		48	number of auxillary symbol entries
	# long	cbAuxOffset	52	offset to start of auxillary symbol entries
	# long	issMax		56	max index into local strings
	# long	cbSsOffset	60	offset to start of local strings
	# long	issExtMax	64	max index into external strings
	# long	cbSsExtOffset	68	offset to start of external strings
	# long	ifdMax		72	number of file descriptor entries
	# long	cbFdOffset	76	offset to file descriptor table
	# long	crfd		80	number of relative file descriptor entries
	# long	cbRfdOffset	84	offset to relative file descriptor table
	# long	iextMax		88	max index into external symbols
	# long	cbExtOffset	92	offset to start of external symbol entries
	#			96

	$symhdr_unpack = 'SSL23';
	$symhdr_size   = 96;

	$i = $[;			# array indices after unpacking
	$S_magic	 = $i++;
	$S_vstamp	 = $i++;
	$S_ilineMax	 = $i++;
	$S_cbLine	 = $i++;
	$S_cbLineOffset	 = $i++;
	$S_idnMax	 = $i++;
	$S_cbDnOffset	 = $i++;
	$S_ipdMax	 = $i++;
	$S_cbPdOffset	 = $i++;
	$S_isymMax	 = $i++;
	$S_cbSymOffset	 = $i++;
	$S_ioptMax	 = $i++;
	$S_cbOptOffset	 = $i++;
	$S_iauxMax	 = $i++;
	$S_cbAuxOffset	 = $i++;
	$S_issMax	 = $i++;
	$S_cbSsOffset	 = $i++;
	$S_issExtMax	 = $i++;
	$S_cbSsExtOffset = $i++;
	$S_ifdMax	 = $i++;
	$S_cbFdOffset	 = $i++;
	$S_crfd		 = $i++;
	$S_cbRfdOffset	 = $i++;
	$S_iextMax	 = $i++;
	$S_cbExtOffset	 = $i++;

	# Sizes for the various structures in the symbol table
	# TODO: provide array indices and unpack info for these

	$HDRR_size	= 96;
	$DNR_size	=  8;
	$PDR_size	= 52;
	$SYMR_size	= 12;
	$FDR_size	= 72;
	$TIR_size	=  4;
	$RFD_size	=  4;

	# Magic numbers -- don't recognize byte swapped headers
	$MIPSEBMAGIC = 0x0160;
	$MIPSELMAGIC = 0x0162;

}

{
	require 'stat.pl';
	&SET_UP_MIPS;

	if ($#ARGV >= 0 && $ARGV[0] eq "-v") {
		$vflag = 1;
		shift;
	} else {
		$vflag = 0;
	}

	if ($#ARGV >= 0) {
		@files = @ARGV;
	} else {
		@files = ('gcc', 'cc1', 'cpp');
		if (-f "stage2/mips-as") {
			push(files, ('mips-as', 'mips-tfile', 'mips-tdump'));
		}
	}

	print "\n========== Comparing";
	$maxlength = 0;
	$maxsize = 0;
	foreach $x (@files) {
		print " ", $x;
		$maxlength = &MAX ($maxlength, length ($x));
		if (-f "stage2/$x") {
			&Stat ("stage2/$x");
			$maxsize = &MAX ($maxsize, $st_size);
		}
	}
	print " in stage2, stage3 subdirectories\n\n";

	$| = 1;
	$successful = 0;
	$name_format = '%-' . ($maxlength + 2) . 's';
	$size_format = '%' . (length ($maxsize . "")) . 'd';
	foreach $x (@files) {
		printf ($name_format, ($x . ","));
		$stage2 = "stage2/" . $x;
		$stage3 = "stage3/" . $x;

		if (! -f $stage2) {
			if (! -f $stage3) {
				print "Does not exist in either stage2 or stage3\n";
			} else {
				print "Does not exist in stage2\n";
			}
			next;
		}

		&Stat ($stage2);
		$s2 = $st_size;

		if (! -f $stage3) {
			print "Does not exist in stage3\n";
			next;
		}

		&Stat ($stage3);
		$s3 = $st_size;

		if ($s2 != $s3) {
			print "Objects are different sizes (", $s2, ", ", $s3, ")\n";
			next;
		}

		printf ("$size_format bytes, ", $s2);

		$mips = 0;
		$timestamp = 0;
		$no_diffs = 0;

		# slurp the files into memory
		open (FILE2, $stage2)				|| die "$0: open $stage2: $!\n";
		$nread2 = read (FILE2, $bytes2, $s2);
		close (FILE2)					|| die "$0: close $stage2: $!\n";

		if ($nread2 != $s2) {
			print "Read ", $nread2, " bytes, expected ", $s2, " in reading $stage2.\n";
			next;
		}

		open (FILE3, $stage3)				|| die "$0: open $stage3: $!\n";
		$nread3 = read (FILE3, $bytes3, $s3);
		close (FILE3)					|| die "$0: close $stage3: $!\n";

		if ($nread3 != $s3) {
			print "Read ", $nread3, " bytes, expected ", $s3, " in reading $stage3.\n";
			next;
		}

		if ($s2 > $filehdr_size) {
			@filehdr2 = unpack ($filehdr_unpack, substr ($bytes2, 0, $filehdr_size));
			@filehdr3 = unpack ($filehdr_unpack, substr ($bytes3, 0, $filehdr_size));

			if (($filehdr2[$f_magic] == $MIPSEBMAGIC || $filehdr2[$f_magic] == $MIPSELMAGIC)
			    && $filehdr2[$f_magic]  == $filehdr3[$f_magic]
			    && $filehdr2[$f_nscns]  == $filehdr3[$f_nscns]
			    && $filehdr2[$f_symptr] == $filehdr3[$f_symptr]
			    && $filehdr2[$f_nsyms]  == $filehdr3[$f_nsyms]
			    && $filehdr2[$f_opthdr] == $filehdr3[$f_opthdr]
			    && $filehdr2[$f_flags]  == $filehdr3[$f_flags]) {
				$mips++;
				printf "Ecoff symbol table starts at $size_format, ", $filehdr2[$f_symptr];

				if ($filehdr2[$f_timdat] != $filehdr3[$f_timdat]) {
					$timestamp++;
					substr ($bytes2, 4, 4) = "\000\000\000\000";
					substr ($bytes3, 4, 4) = "\000\000\000\000";
				}
			}
		}

		# do the big compare (presumably with something fast like memcmp).

		if ($bytes2 eq $bytes3) {
			print (($timestamp) ? "Only timestamps differ." : "No differences.");
			$successful++;

		} else {
			print "Differences exist:\n\n";

			if (! $mips) {
				&COMPARE_SECTION (0, $s2, "Offset ", "");

			} else {

				# something's different, go through each section and find what's different
				&COMPARE_SECTION (20, $filehdr2[$f_opthdr], "a.out", "\theader\t");

				$section_offset = 20 + $filehdr2[$f_opthdr];
				for ($i = 0; $i < $filehdr2[$f_nscns]; $i++) {
					@scnhdr2 = unpack ($scnhdr_unpack,
							   substr ($bytes2, $section_offset, $scnhdr_size));

					&COMPARE_SECTION ($section_offset, 40, $scnhdr2[$s_name], "\theader\t");
					$section_offset += 40;

					&COMPARE_SECTION ($scnhdr2[$s_scnptr],
							  $scnhdr2[$s_size],
							  $scnhdr2[$s_name],
							  "\tdata\t");

					&COMPARE_SECTION ($scnhdr2[$s_relptr],
							  $scnhdr2[$s_nreloc] * $reloc_size,
							  $scnhdr2[$s_name],
							  "\treloc\t");

					&COMPARE_SECTION ($scnhdr2[$s_lnnoptr],
							  $scnhdr2[$s_nlnno] * 8,
							  $scnhdr2[$s_name],
							  "\tgp.\t");
				}

				# Compare symbol tables now

				$symlen = $s2 - $filehdr2[$f_symptr];
				if ($symlen > 0) {
					&COMPARE_SECTION ($filehdr2[$f_symptr], $symhdr_size, "symtbl", "\theader\t");
					@symhdr2 = unpack ($symhdr_unpack,
							   substr ($bytes2, $filehdr2[$f_symptr], $symhdr_size));

					&COMPARE_SECTION ($symhdr2[$S_cbLineOffset],
							  $symhdr2[$S_cbLine],
							  "symtbl",
							  "\tline #\t");

					&COMPARE_SECTION ($symhdr2[$S_cbDnOffset],
							  $symhdr2[$S_idnMax] * $DNR_size,
							  "symtbl",
							  "\tdense #\t");

					&COMPARE_SECTION ($symhdr2[$S_cbPdOffset],
							  $symhdr2[$S_ipdMax] * $PDR_size,
							  "symtbl",
							  "\t.proc\t");

					&COMPARE_SECTION ($symhdr2[$S_cbSymOffset],
							  $symhdr2[$S_isymMax] * $SYMR_size,
							  "symtbl",
							  "\t.lsym\t");

					&COMPARE_SECTION ($symhdr2[$S_cbOptOffset],
							  $symhdr2[$S_ioptMax] * $OPTR_size,
							  "symtbl",
							  "\t.opt\t");

					&COMPARE_SECTION ($symhdr2[$S_cbAuxOffset],
							  $symhdr2[$S_iauxMax] * $AUXU_size,
							  "symtbl",
							  "\t.aux\t");

					&COMPARE_SECTION ($symhdr2[$S_cbSsOffset],
							  $symhdr2[$S_issMax],
							  "symtbl",
							  "\t.lstr\t");

					&COMPARE_SECTION ($symhdr2[$S_cbSsExtOffset],
							  $symhdr2[$S_issExtMax],
							  "symtbl",
							  "\t.estr\t");

					&COMPARE_SECTION ($symhdr2[$S_cbFdOffset],
							  $symhdr2[$S_ifdMax] * $FDR_size,
							  "symtbl",
							  "\t.file\t");

					&COMPARE_SECTION ($symhdr2[$S_cbRfdOffset],
							  $symhdr2[$S_crfd] * $RFD_size,
							  "symtbl",
							  "\t.rfd\t");

					&COMPARE_SECTION ($symhdr2[$S_cbExtOffset],
							  $symhdr2[$S_iextMax] * $EXTR_size,
							  "symtbl",
							  "\t.esym\t");
				}
			}

		}

		print "\n";
	}

	exit ( $#files + 1 - $successful );
}

--
Michael Meissner	email: meissner at osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Considering the flames and intolerance, shouldn't USENET be spelled ABUSENET?

--
Michael Meissner	email: meissner at osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Considering the flames and intolerance, shouldn't USENET be spelled ABUSENET?



More information about the Comp.unix.ultrix mailing list