ftp.nice.ch/pub/next/unix/hack/hackkit.2.N.bs.tar.gz#/freebies/source/dis/dis.h

This is dis.h in view mode; [Download] [Up]

/*	dis include file, contains function prototypes and shared data
	structures (but does NOT contain extern declarations, I prefer
	to put them right next to where they are used).
*/

/*	Define some standart macros and prototypes: */

#define strerror(x) strerror()	/* hack so no arg in in prototype */
#include <ansi.h>
#undef strerror
typedef char flag;
#define TRUE 1
#define FALSE 0
#define		movmem(a,b,c)		memmove(b,a,c)
#define		fill(a,b,c)		memset(a,c,b)
#define repeat for(;;)

/*======================== Mach-O object file format =======================*/

/*	Edited from original include files by Bill Spitzak.

	The major change I made was to consolidate all the information that is
	in a Mach object file into a single include file.  It was spread amoung
	many files and difficult to locate.

	I also removed pointless typedefs that only served to confuse how
	the data is stored, such as "cpu_type_t" when knowing it is an "int"
	would make life simpler.

	Occasionally some field names were changed.  I deleted prefixes such
	as "m_" off of structure elements and changed some so they have the
	same name as elements used for the same purpose in other structures.
	I also deleted some unions: there are no pointers in a mach-o file,
	when a pointer appears actually what is stored is an integer offset
	from some point in a file, a program would normally map the entire
	file into memory and change these to real pointers.

*/

/* The start of the file is a header: */

struct mach_header {
	unsigned long	magic;	/* 0xfeedface */
	int cputype;			/* 6 for MC68030 */
	int cpusubtype;		/* 1 for NeXT */
	unsigned long filetype;	/* 1=object,2=execute,3=fvmlib,4=core,5=preload*/
	unsigned long ncmds;
	unsigned long sizeofcmds;
	unsigned long flags;	/* 1= no undefined symbols */
	};

/*	followed by header.ncmds "load commands", of different types.  We
	are only interested in certain types, all the others can be skipped
	over by moving by the "cmdsize" field.

	Code and data are mapped into memory with "segment" commands:
*/

struct segment_command {
	unsigned long cmd;		/* 1 */
	unsigned long cmdsize;	/* includes sections, below */
	char	segname[16];
	unsigned long vmaddr;	/* where to put it */
	unsigned long vmsize;	/* how much memory (>=filesize) */
	unsigned long fileoff;	/* where in file */
	unsigned long filesize;	/* how much in file (rest is zeroed) */
	unsigned int maxprot;	/* maximum protection, r=1,w=2,x=4 */
	unsigned int initprot;	/* initial protection, r=1,w=2,x=4 */
	unsigned long nsects;	/* number of sections */
	unsigned long flags;	/* 1=map at end of segment, 2=fvmlib */
	};

/*	A segment may have 0 or more "section" commands.  These apparently
	have no effect on how the segment is loaded.  They just identify
	the areas for the linker.  Notice that the "segname" in the section
	may not match the "segname" in the segment, and this section segname
	is what the linker uses to match things up.
*/
struct section {
	char sectname[16];
	char segname[16];		/* segment to link it into */
	unsigned long vmaddr;	/* s_addr in mach header */
	unsigned long vmsize;	/* s_size in mach header */
	unsigned long fileoff;	/* s_offset in mach header */
	unsigned long align;	/* type of alignment ? */
	unsigned long reloff;	/* file offset of relocation table */
	unsigned long nreloc;	/* number of relocation entries */
	unsigned long flags;	/* 1=zero-filled */
	unsigned long reserved[2];
	};

/*	section.reloff points at a table of these, used to identify the
	locations in the section that must be modified by the linker.
*/
struct relocation_info {
	int address;			/* offset in the section */
	unsigned	symbolnum:24,	/* symbol table index or section number */
			pcrel:1,		/* pc relative (ie store offset to symbol) */
			length:2,		/* 0=byte, 1=word, 2=long */
			r_extern:1,	/* 1=symbol table index, 0=section number */
			reserved:4;
	};

/*	There is a "LC_UNIXTHREAD" command that specifies how to set the
	registers at program startup.  The real mach-o specification gives
	this as a number of nested structures, but the resulting structure
	looks like this (note it will be different for other processors):
*/

struct unixthread {
	unsigned long cmd;		/* 5 */
	unsigned long cmdsize;
	unsigned long flavor;	/* 1 */
	unsigned long count;	/* sizeof(rest of structure) / sizeof(int) */
	int dreg[8];			/* d0-d7 */
	int areg[8];			/* a0-a7 */
	short pad0;
	short sr;				/* status register */
	int pc;				/* program counter */
	};

/*	The symbol table (used by the linker and by the standard Unix
	debuggers, not to be confused with the gdb table which we do not
	use) has the following header:
*/
struct symtab_command {
	unsigned long cmd;		/* 2 */
	unsigned long cmdsize;
	unsigned long symoff;	/* file offset of symbol table */
	unsigned long nsyms;	/* number of entries */
	unsigned long stroff;	/* file offset of strings */
	unsigned long strsize;	/* size of string table */
	};

/*	symoff is a pointer to a table of these: */
struct nlist {
	char *name;			/* stored as offset from stroff */
	unsigned char type;		/* what this symbol is */
	unsigned char section;	/* ordinal of section it is relocated with */
	short desc;			/* variable type or whatever */
	unsigned value;		/* offset, relocated to section */
	};

/*	There are many different types of symbols.  What type each is is
	defined by the type byte.  When the linker links, all symbols with
	section not zero get their value updated to the relocation of that
	section.
	If NO_SECT appears after a type, then that type's value is not to
	be relocated (it is something other than an address).  This is done
	by forcing the section number to be zero.
	The N_EXT bit is set, then that symbol is external, and cannot be
	duplicated, and an undefined in another file can find it.
	All types >=0x20 are debugger symbols, the linker just relocates
	them and preserves them.  Gnu C does not seem to fill in the fields,
	it stores the type information in the name, and leaves the line
	numbers zero except for the SLINE types.
*/

#define NO_SECT 0
#define N_EXT 0

#define N_UNDF		0x0	/* NO_SECT */
/*	probably not used without N_EXT on.
	if value is zero, a symbol (probably function) declared extern.
	if value is non-zero, a common symbol, value is size in bytes.
*/

#define N_ABS		0x2	/* NO_SECT */
/* symbol has a constant value given in value, section must be zero */

#define N_INDR		0xa	/* NO_SECT */
/* this symbol matches another one, value is index into the symbol table
   of that other one, which will be undefined.  When it becomes defined,
   the linker changes this one to have the same definition */

#define N_SECT		0xe
/* the symbol is defined in this file, value is offset into section */

#define	N_GSYM	0x20	/* NO_SECT ? */
/*	global symbol, Desc gives type (see below) */

#define	N_FNAME	0x22	/* NO_SECT */
/*	procedure name for F77, section is zero? */

#define	N_FUN	0x24
/*	procedure name, desc=source line */

#define	N_STSYM	0x26
/*	static symbol, desc = type */

#define	N_LCSYM	0x28
/*	.lcomm symbol, desc = type */

#define	N_RSYM	0x40	/* NO_SECT */
/*	register symbol, appears after N_FUN, desc = type, value=register */

#define	N_SLINE	0x44
/*	source line, no name, desc = line number */

#define	N_SSYM	0x60	/* NO_SECT */
/*	structure element, desc = type, value = offset.  Not made by Gnu C */

#define	N_SO		0x64
/*	source file name for addresses that follow */

#define	N_LSYM	0x80	/* NO_SECT */
/*	local symbol, appears after N_FUN, desc = type, value = offset in frame */

#define	N_SOL	0x84
/*	#included file name for addresses that follow */

#define	N_PSYM	0xa0	/* NO_SECT */
/*	parameter, appears after N_FUN, desc = type, value = offset */

#define	N_ENTRY	0xa4
/*	alternate entry (?), desc = linenumber */

#define	N_LBRAC	0xc0	/* NO_SECT ? I doubt it but thats what it says */
/*	left bracket, desc = nesting level */

#define	N_RBRAC	0xe0	/* NO_SECT ? */
/*	right bracket, desc = nesting level */

#define	N_BCOMM	0xe2	/* NO_SECT ? */
/*	begin common (?) of name */

#define	N_ECOMM	0xe4
/*	end common (?) of name, note has section while BCOMM does not? */

#define	N_ECOML	0xe8
/*	end common (local name) (?), has section & address? */

#define	N_LENG	0xfe	/* NO_SECT? */
/*	value is length to further enhance previous symbol entry */

#define	N_PC		0x30	/* NO_SECT */
/*	global pascal symbol, desc = subtype, value = line */

#define 	DISASM	0xFE
/*	a symbol used internally, name is how to disassemble it */

/*	Values for the desc field, when the symbol is an actual label.  These
	values are from pcc.h, except I shortened them by deleting a PCCT_
	prefix, and I made perhaps incorrect assumptions about what some
	of them mean.  Hopefully other
	programs will share these values.  GCC always puts zero in the desc,
	so this must be the "unknown" type.
*/

# define	UNKNOWN	0	/* unknown, prints as short data */
# define	CODE		1	/* PCCT_FARG, I use this to point to code */
# define	CHAR		2	/* byte values, use STRTY to get ascii codes */
# define	SHORT	3
# define	INT		4
# define	LONG		5
# define	FLOAT	6
# define	DOUBLE	7
# define	STRTY	8	/* .ascii, make into 0-terminated quoted strings */
# define	FLOAT12	9	/* internal representation for 12byte fp data */
# define	UNIONTY	9	/* points at a structure or union, nyi */
# define	ENUMTY	10	/* enumeration */
# define	MOETY	11	/* member of enum (?) */
# define	UCHAR	12
# define	USHORT	13
# define	UNSIGNED	14
# define	ULONG	15

# define	PTR		020	/* pointer to x, indicates labels */
# define	FTN		040	/* function returning x (indicates code) */
# define	ARY		060	/* array of x */
# define	PCCTM_BASETYPE	017
# define	PCCTM_TYPESHIFT	2

# define	ADDTYPE(t, m)		\
	((((t) &~ PCCTM_BASETYPE) << PCCTM_TYPESHIFT) | \
	(m) | ((t) & PCCTM_BASETYPE))

/*======================= dis globals ==========================*/

typedef struct nlist symbol;

void pushsymbol(void);
void popsymbol(void);
symbol *currentsymbol(void);
symbol *firstsymbol(unsigned address);
symbol *findlabel(unsigned address);
symbol *nextsymbol(void);
symbol *prevsymbol(void);
void addsymbol(symbol *new);
symbol *createlabel(unsigned address,unsigned sn,unsigned type,char *name);

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.