[comp.sys.sun] Bad Secondary Magic Number?

lichter@cs.ucla.edu (Michael I. Lichter) (10/08/90)

Hi.  One of the people 'round here is trying to compile one of his
programs under SunOS 4.1.  It works fine under SunOS 4.0.3, but when he
goes to load it under SunOS 4.1, he gets:

	ld: sfinx_fxcore.o: bad secondary magic number

Just to be sure about this problem, I tried

	cc -o junk sfinx_fxcore.o

and got the same message.  

The .o file mentioned above was constructed from a bunch of .o files in a
hierarchical fashion, which bunches of .o files linked together using "ld
-r" and then linked together with some more .o files and a .a file.  I
tried using roughly the same procedure with a different batch of .o files
and didn't encounter this problem.

This is all on an SS1 running SunOS 4.1 using regular cc, and all of the
.o files were created in this environment.

Does anybody know what this means?  Does anybody have any idea what to do
about it?

Michael

steve@oresoft.com (Steve Hampson) (11/02/90)

In article <1990Oct7.223540.27977@rice.edu> lichter@cs.ucla.edu (Michael I. Lichter) writes:
>Hi.  One of the people 'round here is trying to compile one of his
>programs under SunOS 4.1.  It works fine under SunOS 4.0.3, but when he
>goes to load it under SunOS 4.1, he gets:
>
>	ld: sfinx_fxcore.o: bad secondary magic number

The problem is that Sun changed the a.out (object) format in 4.1.  Extra
information has been added to the end of the object and the file length is
used to indicate that more stuff follows.  The secondary magic number is
the first long word of the new section and is used to validate it.  Sun's
compilers have always terminated the object on the last byte, so this
"worked".  The problem is that some compilers (like mine) write objects a
disk block at a time and so may have nulls after the last byte of the
object.  Ld reports the error because 4 bytes of 0 is not a valid
secondary magic number.

The real solution is to modify the offending program to truncate the file
correctly.  In your case, you can use this program to truncate the object:

------objtrunc.c---------------------------------------------

/*
	Truncates a Sun object file in-place to its natural
	size (calculated by adding the offset of the string
	table, which is the last section of an a.out file,
	to its size).
*/

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/file.h>
#include <machine/a.out.h>

/* Local error codes */

#define	LEREAD	(-1)
#define	LESEEK	(-2)
#define	LETRUNC	(-3)
#define	LEOPEN	(-4)

#define formerr(x)	(fprintf(stderr, "%s: not an object file\n", x))

main(c, v)
char **v;
{
	int fd;
	char *progname = *v;
	int err;

	if (!*++v) {
		fprintf(stderr, "Usage: %s objfile ...\n", progname);
		exit(-2);
	}
	else {
		while (*v) {
			if ((fd = open(*v, O_RDWR)) < 0) {
				perror(*v);
				err = LEOPEN;
			}
			else {
				if ((err = otrunc(fd)) < 0) {
					formerr(*v);
				}
				close(fd);
			}
			++v;
		}
		exit(0);
	}
}

#define	EXECSIZ		(sizeof(struct exec))
#define	LONG_SIZ	(4)

otrunc(fd)
int fd;
{
	struct exec ebu;
	size_t strsiz;

	errno = 0;
	if (read(fd, &ebu, EXECSIZ) != EXECSIZ)			return(LEREAD);
	errno = 0;
	if (lseek(fd, N_STROFF(ebu), L_SET) < 0)		return(LESEEK);
	errno = 0;
	if (read(fd, &strsiz, LONG_SIZ) != LONG_SIZ)	return(LEREAD);
	errno = 0;
	if (ftruncate(fd, N_STROFF(ebu)+strsiz) < 0)	return(LETRUNC);
	return(0);
}

-- 
Steve Hampson                  :  uunet     -
Oregon Software                :  tektronix   \!oresoft.COM!steve
Portland, Oregon               :  reed        /         steve@oresoft.COM
(503) 245-2202                 :  sun!nosun -