.so /usr/lib/tmac/tmac.s
.MF
.TL 
Symbol Table Format for Sdb
.ft R
.br
.ps -2
Case: 39394  File 39394
.ps +2
.ft R
.AU
H.P. Katseff
.AI
.HO
.NH
Introduction.
.PP
A symbolic debugger, sdb,
has been implemented for the UNIX/32V operating system.
This document describes modifications made to 
the C compiler to generate additional
information about the compiled program and to the
assembler and loader to process the information.
It also describes information recognized by the assembler, the loader
and sdb which are intended for use by compilers for other languages
such as F77.
.NH
The C Compiler
.PP
The C compiler was modified to generate additional symbol table
information describing a compiled program.
Two new types of symbol table entries are made.
One describes the variables, giving
their class (local, register, parameter, global, etc.),
their declared type in the program
and their address or offset.
An additional entry is made for structures giving their size.
The other type of entry provides a mapping between the source program
and the object program.
There is an entry for each source line, procedure and source file
giving their addresses in the object file.
All line numbers are relative to the beginning of
the source file.
.PP
All entries are generated with the new assembler pseudo-operation
`.stab'.
It always takes 12 arguments of which the first eight usually
represent the name of the symbol as declared in the C program.
An underscore is
.ul
not
prepended to the name as in some other symbol table entries.
A typical entry would be
.DS C
\&.stab	'e,'r,'r,'f,'l,'g,0,0,046,0,05,_errflg
.DE
For expository convenience,
names in .stab entries will be listed as one word instead of
eight separate characters.
.NH 2
External symbols defined with .comm
.PP
The following entry is made for each external symbol which is
defined with a .comm pseudo-op.
.DS C
\&.stab	name,040,0,type,0
.DE
The type is a 16-bit value describing the variable's declared type.
This field is described in section 2.13.
The debugger determines the variable's address
from the entry made with the .comm.
It assumes that the name for this entry is _name.
.NH 2
Symbols defined within .data areas
.PP
The following entry is made for each symbol which is defined 
as a label in a data area.
.DS C
\&.stab	name,046,0,type,address
.DE
The type is the variable's declared type.
The address is given symbolically as the label.
.NH 2
Symbols defined with .lcomm
.PP
The following entry is made for each symbol which is defined with 
a .lcomm pseudo-op.
.DS C
\&.stab	name,048,0,type,address
.DE
The type is the variable's declared type.
The address is given symbolically as the label.
The specification of an octal constant with an 8 occurs for historical
reasons.
.NH 2
Register symbols
.PP
The following entry is made for each variable whose value
is in a register.
.DS C
\&.stab	name,0100,0,type,register
.DE
The type is the variable's declared type. 
The register is the register number assigned to the variable.
.NH 2
Local non-register symbols
.PP
The following entry is made for each local, non-register variable.
.DS C
\&.stab	name,0200,0,type,offset
.DE
The type is the variable's declared type.
The offset is a positive number indicating its offset in bytes for the
frame pointer.
.NH 2
Parameter symbols
.PP
The following entry is made for each procedure parameter.
.DS C
\&.stab	name,0240,0,type,offset
.DE
The type is the variable's declared type.
The offset is a positive number indicating its offset in bytes from
the stack pointer.
.NH 2
Structure elements
.PP
The following entry is made for each structure element.
.DS C
\&.stab	name,0140,0,type,offset
.DE
The type is the element's declared type.
The offset is its offset within the structure in bytes.
.NH 2
Structure symbols
.PP
An additional entry is made for structures giving their size in bytes.
It immediately follows their defining .stab entry.
It is of the form
.DS C
\&.stab	name,0376,0,0,length
.DE
.NH 2
Common blocks
.PP
The following sequence of entries is used to describe elements of
Fortran equivalence and common blocks.
The first is of the form
.DS C
\&.stab	0,0342,0,0,0
.DE
The entries for each element of the block should then appear
as if they were structure elements.
Finally, one of the following
two entries is used depending on the type of common
or equivalence block.
If the block is defined as a .globl symbol, use the entry
.DS C
\&.stab	name,0344,0,0,0
.DE
where name is the name of the block defined in the .globl statement.
It the block is defined in some other way, use
.DS C
\&.stab	0,0348,0,0,address
.DE
.NH 2
Brackets
.PP
Since C is a block-structured language,
it is necessary to know the extent of each block containing symbol definitions.
An entry is made for each right and left bracket which encloses
a block with definitions.
The following entries are for left and right brackets respectively.
.DS C
\&.stab	0,0300,0,nesting level,address
\&.stab	0,0340,0,nesting level,address
.DE
The nesting level is the static nesting level of the block.
It is currently ignored by the debugger.
The address is the address of the first byte of code for the block
for the left brackets and the first byte following the block
for right brackets.
.NH 2
Procedures
.PP
The following entry is made for each procedure.
.DS C
\&.stab	name,044,0,linenumber,address
.DE
The linenumber is the number of the first line of the procedure in the
source file.
The address is the address of the first byte of the procedure.
.NH 2
Lines
.PP
The following entry is made for each line in the source program.
.DS C
\&.stab	0,0104,0,linenumber,address
.DE
The linenumber is its number.
The address is the address of the first byte of code for the line.
For each block of the program,
the linenumber entries for that block should follow the entries
for the variables of that block.
.NH 2
Source files
.PP
The following entries are made for each source file.
.DS C
\&.stab	name1,0144,0,0,address
\&.stab	name2,0144,0,0,address
\&...
\&.stab	namen,0144,0,0,address
.DE
Each entry contains 8 successive bytes of the name of the source file.
The name is terminated by a null byte.
All bytes following this one should also be null.
The address is the address of the first byte of code for the first
procedure of the file.
.NH 2
Included source files
.PP
The following entry is made for each included source file which
generates code.
.DS C
\&.stab	name1,0204,0,0,address
\&.stab	name2,0204,0,0,address
\&...
\&.stab	namen,0204,0,0,address
.DE
This entry should appear each time the file is included.
A similar entry giving the name of the original file should be
made at the end of the include.
The format of the name is identical to that for files.
This feature is heavily used by programs generated by yacc and lex.
.NH 2
Format of types.
.PP
This 16 bit quantity type describes the declared type of a variable.
We use the same scheme as in S.C. Johnson's Portable C Compiler
[Johnson, 1978].
The type is divided into the following fields:
.DS
	struct {
		short basic:4;
			d1:2,
			d2:2,
			d3:2,
			d4:2,
			d5:2,
			d6:2,
	}
.DE
There are four derived types:
.DS
	0  none
	1  pointer
	2  function
	3  array
.DE
They are indicated in the two bit fields d1, d2, d3, d4, d5 and d6.
The four bit field basic indicates the basic type as follows:
.DS
	 0  undefined
	 1  function argument
	 2  character
	 3  short
	 4  int
	 5  long
	 6  float
	 7  double
	 8  structure
	 9  union
	10  enumerated type
	11  member of enumerated type
	12  unsigned character
	13  unsigned short
	14  unsigned
	15  unsigned long
.DE
.NH 1
The assembler and loader
.PP
Each .stab pseudo-operation generates one entry in the symbol table.
The entry is of the form:
.DS
	struct {
		char	name[8];
		char	type;
		char	other;
		short	desc;
		unsigned value;
	}
.DE
.PP
The loader uses the four least significant bits of the type field
to determine how to relocate the .stab entry.
The following are currently used.
.DS
	0  none
	4  text
	6  data
.DE
.PP
It is necessary for the assembler and loader to preserve the order
of symbol table entries produced by .stab pseudo-ops.
.SH
Reference
.LP
Johnson, S.C., "A Portable Compiler: Theory and Practice",
.I
Proc. 5th ACM Symp. on Principles of Programming Languages,
.R
January 1978.
.bp
.SH 
Appendix
.PP
The following definitions are extracted from the file /usr/include/a.out.h.
.sp 1
.nf
.na
struct	nlist { /* symbol table entry */
	char	n_name[8];	/* symbol name */
	char	n_type;		/* type flag */
	char	n_other;
	short	n_desc;
	unsigned n_value;	/* value */
};

	/* values for type flag */
#define	N_UNDF	0		/* undefined */
#define	N_ABS	02		/* absolute */
#define	N_TEXT	04		/* text */
#define	N_DATA	06		/* data */
#define	N_BSS	08
#define	N_TYPE	037
#define	N_FN	037		/* file name symbol */

#define	N_GSYM	0040		/* global sym: name,,type,0 */
#define	N_FUN	0044		/* function: name,,linenumber,address */
#define	N_STSYM 0046		/* static symbol: name,,type,address */
#define	N_LCSYM 0048		/* .lcomm symbol: name,,type,address */
#define	N_RSYM	0100		/* register sym: name,,register,offset */
#define	N_SLINE	0104		/* src line: ,,linenumber,address */
#define	N_SSYM	0140		/* structure elt: name,,type,struct_offset */
#define	N_SO	0144		/* source file name: name,,,address */
#define	N_LSYM	0200		/* local sym: name,,type,offset */
#define	N_SOL	0204		/* #line source filename: name,,,address */
#define	N_PSYM	0240		/* parameter: name,,type,offset */
#define	N_LBRAC	0300		/* left bracket: ,,nesting level,address */
#define	N_RBRAC	0340		/* right bracket: ,,nesting level,address */
#define N_BCOMM 0342		/* begin common: name,,, */
#define N_ECOMM 0344		/* end common: name,,, */
#define N_ECOML 0348		/* end common (local name): ,,,address */
#define	N_LENG	0376		/* second stab entry with length information */

#define	N_EXT	01		/* external bit, or'ed in */

#define	FORMAT	"%08x"

#define	STABTYPES	0340
.fi
.ad
.SG HO-1353-HPK-sdb
.sp 2
Copy to
.br
R.W. Lucky
.br
C.S. Roberts
