Return to BSD News archive
Newsgroups: comp.os.386bsd.development Path: sserve!newshost.anu.edu.au!munnari.oz.au!network.ucsd.edu!usc!wupost!gumby!destroyer!cs.ubc.ca!unixg.ubc.ca!kakwa.ucs.ualberta.ca!acs.ucalgary.ca!cpsc.ucalgary.ca!xenlink!fsa.ca!deraadt From: deraadt@fsa.ca (Theo de Raadt) Subject: Making the a.out magic number be in network byte order Message-ID: <DERAADT.93May25061104@newt.fsa.ca> Sender: news@fsa.ca Nntp-Posting-Host: newt.fsa.ca Organization: little lizard city Date: Tue, 25 May 1993 13:11:04 GMT Lines: 78 It is my wish that the a.out header in a binary executable should tell what "architecture" it will run on. Support for this kind of thing already exists on Sun and HP machines. First, let's get a few header file things out of the way.... the a.out header on these machines is defined thus.... struct exec { u_short a_mid; /* or a_machtype on Sun */ u_short a_magic; u_long a_text; ... The a_mid field tells what machine this runs on. On a *BSD machine, look at /usr/include/sys/exec.h, then look below at the defined MID_* defines. The a_mid is used in HP300 BSD, HP300 HPUX, and SunOS (and no doubt other machines) to determine what machine type this executable can run on. The execve() system call can check both the magic number and the machineid to check if the executable can run here. A few things are important, if we wish this to work between different operating systems and processor types: 1. The a_magic and a_mid fields are the same size and in the same order in struct exec 2. The byte order is the same There is consistency between the HP and Sun machines: 1. They both put the a_mid field first, it's a short, and the a_magic field second, it is a short also. 2. they both have the same byte ordering. 3. and that byte ordering IS network byte order (4. For sun, the a_mid field contains a few more weird things, but that's not an important issue) I have modified /usr/bin/ld so far (a 1 line change), and the kernel (6 lines) to use this new method. More extensive modifications had to be done to /usr/include/a.out.h, to make it understand either the new or the old magic number format. I actually implemented it by defining a_magic as a long, and not defining a_mid, thus: u_long a_magic = htonl(magic | (mid << 16)) or, the other way around u_short magic = ntohl(a_magic) & 0xffff; u_short mid = (ntohl(a_magic) >> 16) & 0xffff; It is possible to write this with backwards compatibility in mind: In my scheme, if the kernel option COMPAT_MAGIC is defined, the kernel will still run old executables. The linker will also read old .o files, but will always generate files that have the new magic numbers. I have this backwards compatible mode working. A few more programs still need to be modified (strip, nm, the boot program, undump, file, etc.) to finish this.. BENEFITS 1. The file command could be taught to say "i386 executable". Or, "hp300 executable". "sun3 executable". 2. The kernel can never confuse a foreign executable (binary executable for another machine type) as being a shell script for the local machine. Normally, an "chmod +x" file is only a shell script if it's first two characters are "#!". But, the shell can also intuit that the file might be a shell script, and run it. This is done by looking for some sort of ascii text at the start of the file, or, just blindly executing it. If we do this change, for all those machines that are consistent (NetBSD, Sun, HP BSD, soon other ports no doubt) we will know whether it is a shell script better. 3. Probably more benefits. Anyone? Comments? -- This space not left unintentionally unblank. deraadt@fsa.ca