A.OUT(5)

NAME
a.out - assembler and link editor output

SYNOPSIS
#include <a.out.h>

DESCRIPTION
A.out is the output file of the assembler as(1) and the link editor ld(1). Both programs make a.out executable if there were no errors and no unresolved external references.

Balance/NS32000

/*
 * Header prepended to each a.out file.
 */
struct exec {
	long	      a_magic;		/* magic number */
	unsigned long a_text;		/* size of text segment in memory*/
	unsigned long a_data;		/* size of initialized data */
	unsigned long a_bss;		/* size of uninitialized data */
	unsigned long a_syms;		/* size of symbol table */
	unsigned long a_entry;		/* entry point */
	unsigned long a_trsize;		/* size of text relocation */
	unsigned long a_drsize;		/* size of data relocation */
	struct modtbl {			/* a zeroed mod table entry */
		unsigned long m_staticbase;
		unsigned long m_linkbase;
		unsigned long m_programbase;
		unsigned long m_reserved;
	} a_modtbl;
	unsigned long a_brtoentry[2];	/* code to jump to the entry point */
	unsigned long a_shdata;		/* size of initialized shared data */
	unsigned long a_shbss;		/* size of uninitialized shared data */
	unsigned long a_shdrsize;	/* size of shared data relocation */
	unsigned long a_reserved[14];	/* reserved for future use */
	unsigned long a_version;	/* object version */
};
#define	OMAGIC		0x00ea		/* impure format - for .o's */
#define	ZMAGIC		0x10ea		/* demand load format - zero at zero */
#define	XMAGIC		0x20ea		/* demand load format - invalid zero */
#define	SMAGIC 		0x30ea		/* demand load format - standalone */

Symmetry/i386

/*
 * Header prepended to each a.out file.
 */
struct exec {
	long	      a_magic;		/* magic number */
	unsigned long a_text;		/* size of text segment */
	unsigned long a_data;		/* size of initialized data */
	unsigned long a_bss;		/* size of uninitialized data */
	unsigned long a_syms;		/* size of symbol table */
	unsigned long a_entry;		/* entry point */
	unsigned long a_trsize;		/* size of text relocation */
	unsigned long a_drsize;		/* size of data relocation */
	struct gdtbl {			/* Global Descriptor Table */
		unsigned long g_code[2];
		unsigned long g_data[2];
		unsigned long g_desc[2];
	} a_gdtbl;
	unsigned long a_shdata;		/* size of initialized shared data */
	unsigned long a_shbss;		/* size of uninitialized shared data */
	unsigned long a_shdrsize;	/* size of shared data relocation */
	unsigned long a_bootstrap[11];	/* bootstrap for standalone */
	unsigned long a_reserved[3];	/* reserved for future use */
	unsigned long a_version;	/* object version */
};
#define	OMAGIC		0x12eb		/* impure format - for .o's */
#define	ZMAGIC		0x22eb		/* demand load format - zero at zero */
#define	XMAGIC		0x32eb		/* demand load format - invalid zero */
#define	SMAGIC		0x42eb		/* demand load format - standalone */
/*
 * Macros to determine validity of object file and offsets in a file.
 *
 * In an executable a.out, a_magic determines how position in the file
 * relates to execution address: ZMAGIC and XMAGIC place position 0 in the
 * file at address EXECPGRND in memory; SMAGIC uses same file and execution
 * addresses.  a_text encodes the virtual (execution) size of the text,
 * not necessarily the size in the file.  Header is included in the
 * text.  N_ADDRADJ() encodes this.
 *
 * In a non-executable a.out (OMAGIC), text starts after header.
 *
 * N_MINSIZ(x) gives minimum size for legal executable.
 */
#define EXECPGRND       (LOWPAGES*NBPG)
#define	N_BADMAG(x) \
    (((x).a_magic)!=OMAGIC && ((x).a_magic)!=ZMAGIC && \
     ((x).a_magic)!=XMAGIC && ((x).a_magic)!=SMAGIC)
#define	N_ADDRADJ(x) \
	(((x).a_magic == ZMAGIC||(x).a_magic == XMAGIC) ? EXECPGRND : 0)
#define	N_TXTOFF(x)	((x).a_magic == OMAGIC ? sizeof (struct exec) : 0)
#define	N_DATAOFF(x)	(N_TXTOFF(x) + (x).a_text - N_ADDRADJ(x))
#define	N_SHDATAOFF(x)	(N_DATAOFF(x) + (x).a_data)
#define	N_TROFF(x)	(N_SHDATAOFF(x) + (x).a_shdata)
#define	N_DROFF(x)	(N_TROFF(x) + (x).a_trsize)
#define	N_SHDROFF(x)	(N_DROFF(x) + (x).a_drsize)
#define	N_SYMOFF(x)	(N_SHDROFF(x) + (x).a_shdrsize)
#define	N_STROFF(x)	(N_SYMOFF(x) + (x).a_syms)
#define	N_MINSIZ(x)	N_TROFF(x)

The file has four sections: (1) the header, program text, and data; (2) relocation information; (3) a symbol table; and (4) a string table (in that order). The last three might be omitted if the program was loaded with the -s option of ld, or if the symbols and relocation have been removed by strip(1).

The header gives the sizes (in bytes) of each section. The header size is included in the size of the text section (a_text).

In memory, the sections are offset by the amount returned by the N_ADDRADJ macro. Thus, to get the actual file offsets, you must subtract N_ADDRADJ from the addresses in the symbol table. For example, the actual size of text (including the header) in the a.out file is a_text-N_ADDRADJ.

When an a.out file is executed, three logical segments are created: a text segment, a data segment (which contains initialized data, followed by uninitialized data set to 0), and a stack. The text segment begins at 0 in the a.out file, and at address EXECPGRND (2048 for Balance 4096 for Symmetry) in memory.

If the magic number in the header is OMAGIC, then the file is a ".o" file and is not executable.

If the magic number is ZMAGIC, then the first EXECPGRND bytes in memory are 0's, and the text segment begins at address EXECPGRND. The data segment begins at the first 0 mod EXECPGRND byte boundary following the end of the text segment. Both the text and data sizes are multiples of EXECPGRND bytes. The text segment is not writable; all processes executing this program share the same text segment. The pages of the file are brought into the running image as needed (demand paged). ZMAGIC is the default format produced by ld(1), and is especially suitable for very large programs.

If the magic number is XMAGIC, the format is the same as ZMAGIC, except that the first EXECPGRND bytes in memory are invalid. XMAGIC is useful for finding NULL-pointer dereferencing bugs.

If the magic number is SMAGIC, then the file is a stand alone file that does not run under DYNIX. In this format, The text section begins at 0 in memory (N_ADDRADJ is 0). By default, the text and data segments are rounded to EXECPGRND byte boundaries. The loader's -p flag, which is only valid for SMAGIC files, instructs the loader to not round the text and data segments.

The stack occupies the highest possible locations in the core image and grows downwards. The stack is automatically extended as required. The data segment is only extended as requested by brk(2).

The header is followed by the text, data, shared data, text relocation, data relocation, shared data relocation, symbol table, and string table (in that order). When given the name of an exec structure as an argument, the N_TXTOFF, N_DATAOFF, N_SHDATAOFF, N_SYMOFF, and N_STROFF macros return the absolute file positions of the beginning of the text, data, shared data, symbol table, and string table sections, respectively. The N_TROFF, N_DROFF, and N_SHDROFF macros return the absolute file positions of the beginning of the text, data, and shared data relocation information, respectively.

The first 4 bytes of the string table contain the string table's size. These bytes are not used for string storage, but are included in the size. Thus, the minimum string table size is 4.

The layout of a symbol table entry and the principal flag values that distinguish symbol types are given in the include file as follows:

/*
 * Format of a symbol table entry.
 */
struct nlist {
	union {
		char *n_name;		/* for use when in-core */
		long n_strx;		/* index into file string table */
	} n_un;
	unsigned char n_type;		/* type flag, N_TEXT etc; see below */
	char	n_other;		/* unused */
	short	n_desc;			/* see <stab.h> */
	unsigned long	n_value;	/* value of symbol (or sdb offset) */
};
#define	n_hash		n_desc		/* used internally by ld */
/*
 * Simple values for n_type.
 */
#define	N_UNDF		0x00		/* undefined */
#define	N_ABS		0x02		/* absolute */
#define	N_TEXT		0x04		/* text (implicitly shared) */
#define	N_DATA		0x06		/* private data */
#define	N_BSS		0x08		/* private bss */
#define	N_COMM		0x0a		/* common (internal to ld) */
#define	N_FN		0x0c		/* file-name */
#define	N_SHARED	0x10		/* shared N_UNDF, N_DATA, N_BSS */
#define	N_SHUNDF	(N_SHARED|N_UNDF)
#define	N_SHDATA	(N_SHARED|N_DATA)
#define	N_SHBSS		(N_SHARED|N_BSS)
#define	N_SHCOMM	(N_SHARED|N_COMM)
#define	N_EXT		0x01		/* external bit, or'ed in */
#define	N_TYPE		0x1e		/* mask for all the type bits */
/*
 * Other permanent symbol table entries have some of the N_STAB bits set.
 * These are given in <stab.h>
 */
#define	N_STAB	0xe0	/* if any of these bits set, don't discard */
/*
 * Format for namelist values.
 */
#define	N_FORMAT	"%08x"

In the a.out file, a symbol's n_un.n_strx field gives an index into the string table. An n_strx value of 0 indicates that no name is associated with a particular symbol table entry. The field n_un.n_name can be used to refer to the symbol name only if the program sets this up using n_strx and appropriate data from the string table.

If a symbol's type is undefined external or shared undefined external, and the value field is non-zero, the symbol is interpreted by the loader ld(1) as the name of a common region whose size is indicated by the value of the symbol.

In the text or data, the value of a byte that is not a portion of a reference to an undefined external symbol is exactly the value that will appear in memory when the file is executed. If a byte in the text or data involves a reference to an undefined external symbol, as indicated by the relocation information, then the value stored in the file is an offset from the associated external symbol. When the file is processed by the link editor and the external symbol becomes defined, the value of the symbol will be added to the bytes in the file.

If relocation information is present, it amounts to eight bytes per relocatable datum as in the following structure:

/*
 * Format of a relocation datum.
 */
struct relocation_info {
	int		r_address;	/* address which is relocated */
	unsigned int	r_symbolnum:24,	/* local symbol ordinal */
			r_pcrel:1,	/* was relocated pc relative already */
			r_length:2,	/* 0=byte, 1=word, 2=long */
			r_extern:1,	/* doesn't include value of sym ref'd */
			r_bsr:1,	/* this is an entry for a bsr dest. */
			r_disp:1,	/* the value is a displacement */
				:2;	/* nothing, yet */
};

There is no relocation information if a_trsize+a_drsize+a_shdrsize==0. If r_extern is 0, then r_symbolnum is actually a n_type for the relocation (i.e. N_TEXT meaning relative to segment text origin.)

SEE ALSO
as(1), ld(1), nm(1), pdbx(1), stab(5), strip(1), ddt(1)

CAVEATS
Shared data and bss are supported only for programs that are linked with the Parallel Programming Library, /usr/lib/libpps.a (see intro(3P)).