(*
 *	Definition Module for the data structures and procedures required
 *	for a.out files.
 *	No support will be provided for sdb.
 *)

(* $Header: Aout.def,v 1.2 87/03/02 17:48:18 can Exp $ *)
(* $Log:	Aout.def,v $
Revision 1.2  87/03/02  17:48:18  can
Tidied and commented m2ld

Revision 1.1  87/03/02  11:22:35  can
Initial revision
 *)

DEFINITION MODULE Aout;

FROM SYSTEM IMPORT ADDRESS, WORD;
FROM Strings IMPORT String;
FROM SystemTypes IMPORT Short;

EXPORT QUALIFIED
	OMAGIC, NMAGIC, ZMAGIC,
	NUNDF, NABS, NTEXT, NDATA,
	NBSS, NCOMM, NFN, NEXT, NTYPE,
	pageSize, segmentSize,
	Exec,
	PtrExec,
	sizeExec,
	RelocationInfo,
	PtrRelocationInfo,
	sizeRelocationInfo,
	Nlist,
	sizeNlist,
	PtrNlist;
(* Now in SunSpecific.def
	NBadMag, NTxtOff, NSymOff, NStrOff,
	RSymbolnumExtract, RSymbolnumInsert,
	RPcrelExtract, RPcrelInsert,
	RLengthExtract, RLengthInsert,
	RExternExtract, RExternInsert;
*)

CONST
	(* Constants for aMagic member of Exec. *)
	OMAGIC = 0407B; (* Old impure format. *)
	NMAGIC = 0410B;	(* Read-only text. *)
	ZMAGIC = 0413B;	(* Demand load format. *)

	(* Constants for nType member of Nlist. *)
	NUNDF	= 0C;	(* undefined *)
	NABS	= 2C;	(* absolute *)
	NTEXT	= 4C;	(* text *)
	NDATA	= 6C;	(* data *)
	NBSS	= 10C;	(* bss *)
	NCOMM	= 22C;	(* common (internal to ld) *)
	NFN		= 37C;	(* file name symbol *)

	NEXT	= 01C;	(* external bit, or'ed in *)
	NTYPE	= 36C;	(* mask for all the type bits *)

	pageSize = 8192;
	segmentSize = 131072;

VAR
	sizeExec, sizeRelocationInfo, sizeNlist: CARDINAL;

TYPE

(* A.out header record. *)
Exec = RECORD
		aMagic	: CARDINAL;	(* magic number *)
		aText	: CARDINAL;	(* size of text segment *)
		aData	: CARDINAL;	(* size of initialized data *)
		aBss	: CARDINAL;	(* size of uninitialized data *)
		aSyms	: CARDINAL;	(* size of symbol table *)
		aEntry	: CARDINAL;	(* entry point *)
		aTrsize	: CARDINAL;	(* size of text relocation *)
		aDrsize	: CARDINAL;	(* size of data relocation *)
END;

PtrExec = POINTER TO Exec;


(* Corresponding C structure.

/*	a.out.h	4.1	83/05/03	*/

/*
 * 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 */
};

#define	OMAGIC	0407		/* old impure format */
#define	NMAGIC	0410		/* read-only text */
#define	ZMAGIC	0413		/* demand load format */

*)


(*  A.out relocation information record. *)
RelocationInfo = RECORD
				rAddress	: ADDRESS;	(* address which is relocated *)
				kludge		: BITSET;	(* Contains bit fields. *)
(*
 *	This is kludge is used to build a modula2 structure which is the
 *	same size as the corresponding C structure.
 *				rSymbolnum	bits 0..23	(* local symbol ordinal *)
 *				rPcrel		bit 24		(* was relocated pc relative already *)
 *				rLength		bits 25..26	(* 0=byte, 1=word, 2=long *)
 *				rExtern		bit 27
 *					If set then the symbol is
 *					external, and the local symbol ordinal is an index
 *					into the symbol table, otherwise if clear then the
 *					local symbol ordinal is an n_type and specifies how
 *					the symbol is to be relocated.
 *)

END;

PtrRelocationInfo = POINTER TO RelocationInfo;


(* Corresponding C 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,	/* does not include value of sym referenced */
		:4;		/* nothing, yet */
};
*)


ArrayKludge = ARRAY [0..3] OF CHAR;

Nlist = RECORD
		kludge:	WORD;	
		(*
		 *	This is kludge is used to build a modula2 structure which is the
		 *	same size as the corresponding C structure.
		 *	And is the raw representation for the undiscrimintated
		 *	union shown below.
		 *	UNION
		 *		name	: nName	: String; | (* for use when in-core *)
		 *		index	: nStrx	: INTEGER;	(* index into string table *)
		 *	END;
		 *)
		anotherKludge: ArrayKludge;
		(*
		 *	This kludge is used to build a modula2 structure which is the
		 *	same size as the corresponding C structure.
		 *	Modula2 word aligns chars in arrays!
		 *	nType = AnotherKludge[0] (* type flag, i.e. nTEXT etc; see above. *)
		 *	nOther = AnotherKludge[1]	(* unused *)
		 *	ndesc = AnotherKludge[2..3]
		*)
		nValue: CARDINAL; (* value of this symbol (or sdb offset) *)
END;

PtrNlist = POINTER TO Nlist;


(* Corresponding C structure.

/*
 * Format of a symbol table entry; this file is included by <a.out.h>
 * and should be used if you aren't interested the a.out header
 * or relocation information.
 */
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, i.e. N_TEXT etc; see below */
	char	n_other;	/* unused */
	short	n_desc;		/* see <stab.h> */
unsigned long	n_value;	/* value of this symbol (or sdb offset) */
};
#define	n_hash	n_desc		/* used internally by ld */

/*
 * Simple values for n_type.
 */
#define	N_UNDF	0x0		/* undefined */
#define	N_ABS	0x2		/* absolute */
#define	N_TEXT	0x4		/* text */
#define	N_DATA	0x6		/* data */
#define	N_BSS	0x8		/* bss */
#define	N_COMM	0x12		/* common (internal to ld) */
#define	N_FN	0x1f		/* file name symbol */

#define	N_EXT	01		/* external bit, or'ed in */
#define	N_TYPE	0x1e		/* mask for all the type bits */
*)


(*
 *	Functions to determine whether the Magic number is legal and to
 *	calculate the offset of the sections in an a.out file.
 *)

(* Now in SunSpecific.def
(* Validate Magic number, returns TRUE if bad, FALSE if valid. *)
PROCEDURE NBadMag( ptrHeader: PtrExec ): BOOLEAN;

(* Determine offset for text segment. *)
PROCEDURE NTxtOff( ptrHeader: PtrExec ): CARDINAL;

(* Determine offset for symbol table. *)
PROCEDURE NSymOff( ptrHeader: PtrExec ): CARDINAL;

(* Determine offset for string table. *)
PROCEDURE NStrOff( ptrHeader: PtrExec ): CARDINAL;
*)


(* Corresponding CPP macros.

/*
 * Macros which take exec structures as arguments and tell whether
 * the file has a reasonable magic number or offsets to text|symbols|strings.
 */
#define	N_BADMAG(x) \
    (((x).a_magic)!=OMAGIC && ((x).a_magic)!=NMAGIC && ((x).a_magic)!=ZMAGIC)

#define	N_TXTOFF(x) \
	((x).a_magic==ZMAGIC ? 1024 : sizeof (struct exec))
#define N_SYMOFF(x) \
	(N_TXTOFF(x) + (x).a_text+(x).a_data + (x).a_trsize+(x).a_drsize)
#define	N_STROFF(x) \
	(N_SYMOFF(x) + (x).a_syms)
*)

(* sdb stuff which is not implemented.
/*
 * Sdb 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, a SDB entry */

/*
 * Format for namelist values.
 */
#define	N_FORMAT	"%08x"
*)

(* Now in SunSpecific.def
(* Procedures for simulating bitfields in the relcation structure. *)
PROCEDURE RSymbolnumExtract( relInfo: PtrRelocationInfo ): CARDINAL; 
PROCEDURE RSymbolnumInsert( relInfo: PtrRelocationInfo; value: CARDINAL);
PROCEDURE RPcrelExtract( relInfo: PtrRelocationInfo ): BOOLEAN;
PROCEDURE RPcrelInsert( relInfo: PtrRelocationInfo; value: BOOLEAN );
PROCEDURE RLengthExtract( relInfo: PtrRelocationInfo ): CARDINAL;
PROCEDURE RLengthInsert( relInfo: PtrRelocationInfo; value: CARDINAL);
PROCEDURE RExternExtract( relInfo: PtrRelocationInfo ): BOOLEAN;
PROCEDURE RExternInsert( relInfo: PtrRelocationInfo; value: BOOLEAN );
*)

END Aout.
