Bad Secondary Magic Number?

Steve Hampson steve at oresoft.com
Fri Nov 2 11:20:00 AEST 1990


In article <1990Oct7.223540.27977 at rice.edu> lichter at 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 at oresoft.COM
(503) 245-2202                 :  sun!nosun -



More information about the Comp.sys.sun mailing list