--- /dev/null
+\input texinfo
+@setfilename stabs.info
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* Stabs. The "stabs" representation of debugging infromation.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+This document describes GNU stabs in a.out
+
+Copyright (C) 1992 by ???.
+Contributed by Cygnus Support. Written by Julia Menapace.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy or distribute modified versions of this
+manual under the terms of the GPL (for which purpose this text may be
+regarded as a program in the language TeX).
+@end ifinfo
+
+@setchapternewpage off
+@settitle STABS
+@titlepage
+@title{The "stabs" representation of debugging infromation.}
+@author Julia Menapace
+@author Cygnus Support
+@page
+@tex
+\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
+\xdef\manvers{\$Revision$} % For use in headers, footers too
+{\parskip=0pt
+\hfill Cygnus Support\par
+\hfill \manvers\par
+\hfill \TeX{}info \texinfoversion\par
+}
+@end tex
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1990, 1991 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@end titlepage
+
+@node Top, Overview, (dir), (dir)
+
+This document describes GNU stabs in a.out
+
+@menu
+* Overview:: Overview of stabs
+* Program structure:: Encoding of the structure of the program
+* Simple types::
+* Example:: A comprehensive example in C
+* Variables::
+* Aggregate types::
+* Symbol tables:: Symbol information in symbol tables
+* GNU C++ stabs::
+
+Appendixes:
+* Example2.c:: source code for extended example
+* Example2.s:: assembly code for extended example
+* Quick reference:: Various refernce tables
+* Expanded reference:: by stab type
+* Questions:: Questions and anomolies
+* xcoff-differences:: Differences between GNU stabs in a.out and GNU stabs in xcoff
+* Sun-differences:: Differences between GNU stabs and Sun native stabs
+@end menu
+
+
+@node Overview, Program structure, Top, Top
+@chapter Overview of stabs
+
+@menu
+* Flow:: Overview of debugging information flow
+* Stabs format:: Overview of stab format
+* C example:: A simple example in C source
+* Assembly code:: The simple example at the assembly level
+@end menu
+
+@node Flow, Stabs format, , Overview
+@section Overview of debugging information flow
+
+GCC compiles C source in a .c file into assembly language in a .s
+file, which is translated by the assembler into a .o file, and then
+linked with other .o files and libraries to produce an executable
+file.
+
+When using the -g option, GCC puts additional debugging information in
+the .s file, which is slightly transformed by the assembler and
+linker, and carried through into the final executable. This debugging
+information describes features of the source file like line numbers,
+the types and scopes of variables, and functions, their parameters and
+their scopes.
+
+For some object file formats, the debugging information is
+encapsulated in pseudo-ops to the assembler known as `stab' (symbol
+table) directives, interspersed with the generated code. Stabs are
+the native format for debugging information in the a.out and xcoff
+object file formats. The GNU tools can also emit stabs in the coff
+and ecoff object file formats.
+
+The assembler adds the information from stabs to the symbol
+information it places by default in the symbol table and the string
+table of the .o file it is building. The linker consolidates the .o
+files into one executable file, with one symbol and one string table.
+Debuggers use the symbol and string tables in the executable as a
+source of debugging information about the program.
+
+@node Stabs format, C example, Flow, Overview
+@section Overview of stab format
+
+There are three overall formats for stab assembler directives
+differentiated by the first word of the stab. The first word
+describes what combination of four possible data fields will follow.
+It is either .stabs (string), .stabn (number), or .stabd (dot).
+
+The overall format of each class of stab is:
+
+@example
+.stabs "string",type,0,desc,value
+.stabn type,0,desc,value
+.stabd type,0,desc
+@end example
+
+In general, in .stabs the string field contains name and type
+information. For .stabd the value field is implicit and has the value
+of the current file location. Otherwise the value field often
+contains a relocatable address, frame pointer offset, or register
+number, that maps to the source code element described by the stab.
+
+The real key to decoding the meaning of a stab is the number in its
+type field. Each possible type number defines a different stab type.
+The stab type further defines the exact interpretation of, and
+possible values for, any remaining "string", desc, or value fields
+present in the stab. Table A lists in numeric order the possible type
+field values for stab directives. The reference section that follows
+Table A describes the meaning of the fields for each stab type in
+detail. The examples that follow this overview introduce the stab
+types in terms of the source code elements they describe.
+
+For .stabs the "string" field holds the meat of the debugging
+information. The generally unstructured nature of this field is what
+makes stabs extensible. For some stab types the string field contains
+only a name. For other stab types the contents can be a great deal
+more complex.
+
+The overall format is of the "string" field is:
+
+@example
+"name[:symbol_descriptor][type_number[=type_descriptor...]]"
+@end example
+
+name is the name of the symbol represented by the stab.
+
+The symbol_descriptor following the : is an alphabetic character that
+tells more specifically what kind of symbol the stab represents. If
+the symbol_descriptor is omitted, but type information follows, then
+the stab represents a local variable. See Table C for a list of
+symbol_descriptors.
+
+Type information it is either a type_number, or a type_number=. The
+type_number alone is a type reference, referring directly to a type
+that has already been defined.
+
+The type_number= is a type definition, where the number represents a
+new type which is about to be defined. The type definition may refer
+to other types by number, and those type numbers may be followed by =
+and nested definitions.
+
+In a type definition, if the character that follows the equals sign is
+non-numeric then it is a type_descriptor, and tells what kind of type
+is about to be defined. Any other values following the
+type_descriptor vary, depending on the type_descriptor. If a number
+follows the = then the number is a type_reference. This is described
+more thoroughly in the section on types. See Table D for a list of
+type_descriptors.
+
+All this can make the "string" field quite long. When the "string"
+part of a stab is more than 80 characters, we split the .stabs
+pseudo-op into two .stabs pseudo-ops, both stabs duplicate exactly all
+but the "string" field. The "string" field of the first stab contains
+the first part of the overlong string, marked as continued with a
+double-backslash at the end. The "string" field of the second stab
+holds the second half of the overlong string.
+
+@node C example, Assembly code, Stabs format, Overview
+@section A simple example in C source
+
+To get the flavor of how stabs describe source information for a C
+program, let's look at the simple program:
+
+@example
+main()
+@{
+ printf("Hello world");
+@}
+@end example
+
+When compiled with -g, the program above yields the following .s file.
+Line numbers have been added so it will be easier to refer to parts of
+the .s file in the description of the stabs that follows.
+
+@node Assembly code, , C example, Overview
+@section The simple example at the assembly level
+
+@example
+1 gcc2_compiled.:
+2 .stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0
+3 .stabs "hello.c",100,0,0,Ltext0
+4 .text
+5 Ltext0:
+6 .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
+7 .stabs "char:t2=r2;0;127;",128,0,0,0
+8 .stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
+9 .stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
+10 .stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
+11 .stabs "short int:t6=r1;-32768;32767;",128,0,0,0
+12 .stabs "long long int:t7=r1;0;-1;",128,0,0,0
+13 .stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
+14 .stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
+15 .stabs "signed char:t10=r1;-128;127;",128,0,0,0
+16 .stabs "unsigned char:t11=r1;0;255;",128,0,0,0
+17 .stabs "float:t12=r1;4;0;",128,0,0,0
+18 .stabs "double:t13=r1;8;0;",128,0,0,0
+19 .stabs "long double:t14=r1;8;0;",128,0,0,0
+20 .stabs "void:t15=15",128,0,0,0
+21 .align 4
+22 LC0:
+23 .ascii "Hello, world!\12\0"
+24 .align 4
+25 .global _main
+26 .proc 1
+27 _main:
+28 .stabn 68,0,4,LM1
+29 LM1:
+30 !#PROLOGUE# 0
+31 save %sp,-136,%sp
+32 !#PROLOGUE# 1
+33 call ___main,0
+34 nop
+35 .stabn 68,0,5,LM2
+36 LM2:
+37 LBB2:
+38 sethi %hi(LC0),%o1
+39 or %o1,%lo(LC0),%o0
+40 call _printf,0
+41 nop
+42 .stabn 68,0,6,LM3
+43 LM3:
+44 LBE2:
+45 .stabn 68,0,6,LM4
+46 LM4:
+47 L1:
+48 ret
+49 restore
+50 .stabs "main:F1",36,0,0,_main
+51 .stabn 192,0,0,LBB2
+52 .stabn 224,0,0,LBE2
+@end example
+
+This simple hello world example, demonstrates several of the stab
+types used to describe C language source files.
+
+@node Program structure, Simple types, Overview, Top
+@chapter Encoding of the structure of the program
+
+@menu
+* Source file:: The path and name of the source file
+* Line numbers::
+* Procedures::
+* Block structure::
+@end menu
+
+@node Source file, Line numbers, , Program structure
+@section The path and name of the source file
+
+@example
+.stabs, stab type N_SO
+@end example
+
+The first stabs in the .s file contain the name and path of the source
+file that was compiled to produce the .s file. This information is
+contained in two records of stab type N_SO (100).
+
+@example
+ .stabs "path_name", N_SO, NIL, NIL, Code_address_of_program_start
+ .stabs "file_name:", N_SO, NIL, NIL, Code_address_of_program_start
+@end example
+
+@example
+2 .stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0
+3 .stabs "hello.c",100,0,0,Ltext0
+4 .text
+5 Ltext0:
+@end example
+
+@node Line numbers, Procedures, Source file, Program structure
+@section Line Numbers
+
+@example
+.stabn, stab type N_SLINE
+@end example
+
+The start of source lines is represented by the N_SLINE (68) stab
+type.
+
+@example
+ .stabn N_SLINE, NIL, source_line_number,
+ code_address_for_start_of_source_line
+@end example
+
+@example
+27 _main:
+28 .stabn 68,0,4,LM1
+29 LM1:
+30 !#PROLOGUE# 0
+@end example
+
+@node Procedures, Block structure, Line numbers, Program structure
+@section Procedures
+
+@example
+.stabs, stab type N_FUN,
+ symbol descriptors f (local), F (global)
+@end example
+
+Procedures are described by the N_FUN stab type. The symbol
+descriptor for a procedure is F if the proc is globally scoped and f
+if the procedure is static (locally scoped).
+
+The N_FUN stab representing a procedure is located immediatly
+following the code of the procedure. The N_FUN stab is in turn
+directly followed by a group of other stabs describing elements of the
+procedure. These other stabs describe the procedure's parameters, its
+block local variables and its block structure.
+
+@example
+48 ret
+49 restore
+@end example
+
+@example
+ .stabs "procedure_name:symbol_desc(global proc)return_type_ref(int)",
+ N_FUN, NIL, NIL, Code_address_of_procedure_start
+@end example
+
+@example
+50 .stabs "main:F1",36,0,0,_main
+@end example
+
+@node Block Structure, , Procedures, Program structure
+@section Block Structure
+
+@example
+.stabn, stab types N_LBRAC, N_RRAC
+@end example
+
+The program's block structure is represented by the N_LBRAC (left
+brace) and the N_RBRAC (right brace) stab types. The following code
+range, which is the body of main, is labeled with LBB2: at the
+beginning and LBE2: at the end.
+
+@example
+37 LBB2:
+38 sethi %hi(LC0),%o1
+39 or %o1,%lo(LC0),%o0
+40 call _printf,0
+41 nop
+42 .stabn 68,0,6,LM3
+43 LM3:
+44 LBE2:
+@end example
+
+The N_LBRAC and N_RBRAC stabs that describe the block scope of the
+procedure are located after the N_FUNC stab that represents the
+procedure itself. The N_LBRAC uses the LBB2 label as the code address
+in its value field and the N_RBRAC uses the LBE2.
+
+@example
+50 .stabs "main:F1",36,0,0,_main
+@end example
+
+@example
+ .stabn N_LBRAC, NIL, NIL, Code_Address_for_left_brace
+ .stabn N_RBRAC, NIL, NIL, Code_Address_for_right_brace
+@end example
+
+@example
+51 .stabn 192,0,0,LBB2
+52 .stabn 224,0,0,LBE2
+@end example
+
+@node Simple types, Example, Program structure, Top
+@chapter Simple types
+
+@menu
+* Basic types::
+* Range types:: Range types defined by min and max value
+* Bit-ranges:: Range type defined by number of bits
+@end menu
+
+@node Basic types, Range types, , Simple types
+@section Basic type definitions
+
+@example
+.stabs, stab type N_LSYM,
+ symbol descriptor t
+@end example
+
+The basic types for the language are described using the N_LSYM stab
+type. They are boilerplate and are emited by the compiler for each
+compilation unit. Basic type definitions are not always a complete
+description of the type and are sometimes circular. The debugger
+recognizes the type anyway, and knows how to read bits as that type.
+
+Each language and compiler defines a slightly different set of basic
+types. In this example we are looking at the basic types for C emited
+by the GNU compiler targeting the Sun4. Here the basic types are
+mostly defined as range types.
+
+
+@node Range types, Bit-ranges, Basic types, Simple types
+@section Range types defined by min and max value
+
+type descriptor r
+
+When defining a range type, if the number after the first semicolon is
+smaller than the number after the second one, then the two numbers
+represent the smallest and the largest values in the range.
+
+@example
+4 .text
+5 Ltext0:
+
+ .stabs "name:sym_descriptor(type)type_def(1)=type_desc(range)type_ref(1);\
+ "low_bound;high_bound;",N_LSYM, NIL, NIL, NIL
+
+6 .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
+7 .stabs "char:t2=r2;0;127;",128,0,0,0
+@end example
+
+Here the integer type (1) is defined as a range of the integer type
+(1). Likewise char is a range of char. This part of the definition
+is circular, but at least the high and low bound values of the range
+hold more information about the type.
+
+Here short unsigned int is defined as type number 8 and described as a
+range of type int, with a minimum value of 0 and a maximum of 65535.
+
+@example
+13 .stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
+@end example
+
+@node Bit-ranges, , Range types, Simple types
+@section Range type defined by number of bits
+
+type descriptor r
+
+In a range definition, if the number after the second semicolon is 0,
+then the number after the first semicolon is the number of bits needed
+to represent the type.
+
+@example
+ .stabs "name:sym_desc(type)type_def(12)=type_desc(range)type_ref(int)\
+ ";number_of_bytes;0;", N_LSYM, NIL, NIL, NIL
+
+17 .stabs "float:t12=r1;4;0;",128,0,0,0
+18 .stabs "double:t13=r1;8;0;",128,0,0,0
+19 .stabs "long double:t14=r1;8;0;",128,0,0,0
+@end example
+
+Cosmically enough, the void type is defined directly in terms of
+itself.
+
+@example
+ .stabs "name:symbol_desc(type)type_def(15)=type_ref(15)",N_LSYM,NIL,NIL,NIL
+@end example
+
+@example
+20 .stabs "void:t15=15",128,0,0,0
+@end example
+
+
+@node Example, Variables, Simple types, Top
+@chapter A Comprehensive Example in C
+
+Now we'll examine a second program, example2, which builds on the
+first example to introduce the rest of the stab types, symbol
+descriptors, and type descriptors used in C.
+@xref{Example2.c} for the complete .c source,
+and @pxref{example2.s} for the .s assembly code.
+This description includes parts of those files.
+
+@section Flow of control and nested scopes
+
+.stabn, stab types N_SLINE, N_LBRAC, N_RBRAC (cont.)
+
+Consider the body of main, from example2.c. It shows more about how
+N_SLINE, N_RBRAC, and N_LBRAC stabs are used.
+
+@example
+20 @{
+21 static float s_flap;
+22 int times;
+23 for (times=0; times < s_g_repeat; times++)@{
+24 int inner;
+25 printf ("Hello world\n");
+26 @}
+27 @};
+@end example
+
+Here we have a single source line, the `for' line, that generates
+non-linear flow of control, and non-contiguous code. In this case, an
+N_SLINE stab with the same line number proceeds each block of
+non-contiguous code generated from the same source line.
+
+The example also shows nested scopes. The N_LBRAC and N_LBRAC stabs
+that describe block structure are nested in the same order as the
+corresponding code blocks, those of the for loop inside those for the
+body of main.
+
+ Label for the N_LBRAC (left brace) stab marking the start of `main'.
+
+57 LBB2:
+
+ First code range for source line 23,`for' loop initialize and test
+ <68> N_SLINE - source line number associated with this code
+ .stabn N_SLINE, NIL, line_number, code_address_of_line_start
+
+@example
+58 .stabn 68,0,23,LM2
+59 LM2:
+60 st %g0,[%fp-20]
+61 L2:
+62 sethi %hi(_s_g_repeat),%o0
+63 ld [%fp-20],%o1
+64 ld [%o0+%lo(_s_g_repeat)],%o0
+65 cmp %o1,%o0
+66 bge L3
+67 nop
+@end example
+
+ label for the N_LBRAC (start block) marking the start of `for' loop
+
+@example
+68 LBB3:
+69 .stabn 68,0,25,LM3
+70 LM3:
+71 sethi %hi(LC0),%o1
+72 or %o1,%lo(LC0),%o0
+73 call _printf,0
+74 nop
+75 .stabn 68,0,26,LM4
+76 LM4:
+@end example
+
+ label for the N_RBRAC (end block) stab marking the end of the for loop
+
+@example
+77 LBE3:
+@end example
+
+ Second code range for source line 23, 'for' loop increment and return
+ <68> N_SLINE - source line number associated with this code
+ .stabn, SLINE, NIL, line_number, code_address_of_line_continuation.
+
+@example
+78 .stabn 68,0,23,LM5
+79 LM5:
+80 L4:
+81 ld [%fp-20],%o0
+82 add %o0,1,%o1
+83 st %o1,[%fp-20]
+84 b,a L2
+85 L3:
+86 .stabn 68,0,27,LM6
+87 LM6:
+@end example
+
+ label for the N_RBRAC (end block) stab marking the end of the for loop
+
+@example
+88 LBE2:
+89 .stabn 68,0,27,LM7
+90 LM7:
+91 L1:
+92 ret
+93 restore
+94 .stabs "main:F1",36,0,0,_main
+95 .stabs "argc:p1",160,0,0,68
+96 .stabs "argv:p20=*21=*2",160,0,0,72
+97 .stabs "s_flap:V12",40,0,0,_s_flap.0
+98 .stabs "times:1",128,0,0,-20
+
+ stabs describing nested scopes, the stabs are nested like the scopes are.
+ <192> N_LBRAC - left brace, begin lexical block (scope)
+ .stabn N_LBRAC,NIL,NIL,code_addr_of_block_start
+
+99 .stabn 192,0,0,LBB2 ## begin proc label
+100 .stabs "inner:1",128,0,0,-24
+101 .stabn 192,0,0,LBB3 ## begin for label
+
+ <224> N_RBRAC - right brace, end lexical block (scope)
+ .stabn N_RBRAC,NIL,NIL,code_addr_of_block_end
+
+102 .stabn 224,0,0,LBE3 ## end for label
+103 .stabn 224,0,0,LBE2 ## end proc label
+@end example
+
+
+@node Variables, Aggregate types, Example, Top
+@chapter Variables
+
+@menu
+* Automatic variables:: locally scoped
+* Global variables::
+* Register variables::
+* Initialized statics::
+* Un-initialized statics::
+* Parameters::
+@end menu
+
+@node Automatic variables, Global variables, , Variables
+@section Locally scoped automatic variables
+
+@example
+.stabs, stab type N_LSYM,
+ symbol descriptor none
+@end example
+
+
+In addition to describing types, the N_LSYM stab type also describes
+locally scoped automatic variables. Refer again to the body of main
+in example2.c. It allocates two automatic variables, 'times' is
+scoped to the body of main and 'inner' is scoped to the body of the
+for loop. 's_flap' is locally scoped by not automatic and will be
+discussed later.
+
+@example
+20 @{
+21 static float s_flap;
+22 int times;
+23 for (times=0; times < s_g_repeat; times++)@{
+24 int inner;
+25 printf ("Hello world\n");
+26 @}
+27 @};
+@end example
+
+The N_LSYM stab for an automatic variable is located just before the
+N_LBRAC stab describing the open brace of the block to which it is
+scoped.
+
+@example
+ <128> N_LSYM - automatic variable, scoped locally to main
+ .stabs "name:type_ref(int)", N_LSYM, NIL, NIL, frame_pointer_offset
+
+98 .stabs "times:1",128,0,0,-20
+99 .stabn 192,0,0,LBB2 ## begin `main' N_LBRAC
+
+ <128> N_LSYM - automatic variable, scoped locally to the for loop
+ .stabs "name:type_ref(int)", N_LSYM, NIL, NIL, frame_pointer_offset
+
+100 .stabs "inner:1",128,0,0,-24
+101 .stabn 192,0,0,LBB3 ## begin `for' loop N_LBRAC
+@end example
+
+Since the character in the string field following the colon is not a
+letter, there is no symbol descriptor. This means that the stab
+describes a local variable, and that the number after the colon is a
+type reference. In this case it a a reference to the basic type int.
+Notice also that the frame pointer offset is negative number for
+automatic variables.
+
+
+@node Global Variables, Register variables, Automatic variables, Variables
+@section Global Variables
+
+@example
+.stabs, stab type N_GSYM,
+ symbol descriptor G
+@end example
+
+Global variables are represented by the N_GSYM stab type. The symbol
+descriptor, following the colon in the string field, is G. Following
+the G is a type reference or type definition. In this example it is a
+type reference to the basic C type, char. The first source line in
+example2.c
+
+@example
+1 char g_foo = 'c';
+@end example
+
+yields the following stab. The stab immediatly preceeds the code that
+allocates storage for the variable it describes.
+
+@example
+ <32> N_GSYM - global symbol
+ "name:sym_descriptor(Global)type_ref(char)", N_GSYM, NIL, NIL, NIL
+@end example
+
+@example
+21 .stabs "g_foo:G2",32,0,0,0
+22 .global _g_foo
+23 .data
+24 _g_foo:
+25 .byte 99
+@end example
+
+The address of the variable represented by the N_GSYM is not contained
+in the N_GSYM stab. The debugger gets this information from the
+external symbol for the global variable.
+
+@node Register variables, Initialized statics, Global variables, Variables
+@section Register variables
+
+@example
+.stabs, stab type N_RSYM,
+ symbol descriptor r
+@end example
+
+The following source line defines a global variable, g_bar, which is
+allocated in global register %g5.
+
+@example
+2 register int g_bar asm ("%g5");
+@end example
+
+Register variables have their own stab type, N_RSYM, and their own
+symbol descriptor, r. The stab's value field contains the number of
+the register where the variable data will be stored. Since the
+variable was not initialized in this compilation unit, the stab is
+emited at the end of the object file, with the stabs for other
+uninitialized globals (bcc).
+
+@example
+ <64> N_RSYM - register variable
+ .stabs "name:sym_desc(reg_var)type_ref(int), N_RSYM, NIL, NIL, reg_num
+
+133 .stabs "g_bar:r1",64,0,0,5
+@end example
+
+
+@node Initialized statics, Un-initialized statics, Register variables, Variables
+@section Initialized static variables
+
+@example
+.stabs, stab type N_STSYM,
+ symbol descriptors S (file scope), V (procedure scope)
+@end example
+
+Initialized static variables are represented by the N_STSYM stab type.
+The symbol descriptor part of the string field shows if the variable
+is file scope static (S) or procedure scope static (V). The source
+line:
+
+@example
+3 static int s_g_repeat = 2;
+@end example
+
+yields the following code. The stab is located immediatly preceeding
+the storage for the variable it represents. Since the variable in
+this example is file scope static the symbol descriptor is S.
+
+@example
+ <38> N_STSYM - initialized static variable (data seg w/internal linkage)
+ .stabs "name:sym_desc(static_global)type_ref(int)",N_STSYM,NIL,NIL,var_addr
+@end example
+
+@example
+26 .stabs "s_g_repeat:S1",38,0,0,_s_g_repeat
+27 .align 4
+28 _s_g_repeat:
+29 .word 2
+@end example
+
+
+@node Un-initialized statics, Parameters, Initialized statics, Variables
+@section Un-initialized static variables
+
+@example
+.stabs, stab type N_LCSYM,
+ symbol descriptors S (file scope), V (procedure scope)
+@end example
+
+Un-initilized static variables are represeted by the N_LCSYM stab
+type. The symbol descriptor part of the string shows if the variable
+is file scope static (S) or procedure scope static (V). In this
+example it is procedure scope static. The source line allocating
+s_flap immediatly follows the open brace for the procedure main.
+
+@example
+20 @{
+21 static float s_flap;
+@end example
+
+
+The code that reserves storage for the variable s_flap preceeds the
+body of body of main.
+
+@example
+39 .reserve _s_flap.0,4,"bss",4
+@end example
+
+But since s_flap is scoped locally to main, its stab is located with
+the other stabs representing symbols local to main. The stab for
+s_flap is located just before the N_LBRAC for main.
+
+@example
+ <40> N_LCSYM - un-initialized static var (BSS seg w/internal linkage)
+ .stabs "name:sym_desc(static_local)type_ref(float)", N_LCSYM,
+ NIL, NIL, data_addr
+@end example
+
+@example
+97 .stabs "s_flap:V12",40,0,0,_s_flap.0
+98 .stabs "times:1",128,0,0,-20
+99 .stabn 192,0,0,LBB2 # N_LBRAC for main.
+@end example
+
+@node Parameters, , Un-initialized statics, Variables
+@section Parameters
+
+@example
+.stabs, stab type N_PSYM,
+ symbol descriptor p
+@end example
+
+Procedure parameters are represented by the N_PSYM stab type. The
+following source lines show the parameters of the main routine.
+
+@example
+17 main (argc, argv)
+18 int argc;
+19 char* argv[];
+20 @{
+@end example
+
+The N_PSYM stabs describing parameters to a function directly follow
+the N_FUN stab that represents the procedure itself. The N_FUN stab
+immediatly follows the code of the procedure it describes. Following
+the N_PSYM parameter stabs are any N_LSYM stabs representing local
+variables.
+
+ <36> N_FUN - describing the procedure main
+
+@example
+94 .stabs "main:F1",36,0,0,_main
+
+ <160> N_PSYM - parameters
+ .stabs "name:sym_desc(value_param)type_ref(int)", N_PSYM,
+ NIL, NIL, frame_ptr_offset
+95 .stabs "argc:p1",160,0,0,68
+
+ <160> N_PSYM - parameter
+ .stabs "name:sym_desc(value_param)type_def(20)=ptr_to type_def(21)=
+ ptr_to type_ref(char)
+96 .stabs "argv:p20=*21=*2",160,0,0,72
+@end example
+
+The type definition of argv is interesting because it defines two new
+types in terms of an existing one. The array argv contains character
+pointers. The type of the array name is a pointer to the type the
+array holds. Thus the type of argv is ptr to ptr to char. The stab
+for argv contains nested type_definitions. Type 21 is ptr to type 2
+(char) and argv (type 20) is ptr to type 21.
+
+@node Aggregate Types, Symbol tables, Variables, Top
+@chapter Aggregate Types
+
+Now lets look at some variable definitions involving complex types.
+This involves understanding better how types are described. In the
+examples so far types have been described as references to previously
+defined types or defined in terms of subranges of or pointers to
+previously defined types. The section that follows will talk about
+the various other type descriptors that may follow the = sign in a
+type definition.
+
+@menu
+* Arrays::
+* Enumerations::
+* Structure tags::
+* Typedefs::
+* Unions::
+* Function types::
+@end menu
+
+@node Arrays, Enumerations, , Aggregate Types
+@subsection Array types
+
+.stabs, stab types N_GSYM, N_LSYM,
+ symbol descriptor T, type descriptor ar
+
+As an example of an array type consider the global variable below.
+
+@example
+15 char char_vec[3] = @{'a','b','c'@};
+@end example
+
+Since the array is a global variable, it is described by the N_GSYM
+stab type. The symbol descriptor G, following the colon in stab's
+string field, also says the array is a global variable. Following the
+G is a definition for type (19) as shown by the equals sign after the
+type number.
+
+After the equals sign is a type descriptor, ar, which says that the
+type being defined is an array. Following the type descriptor for an
+array is the type of the index, a null field, the upper bound of the
+array indexing, and the type of the array elements.
+
+The array definition above generates the assembly language that
+follows.
+
+@example
+ <32> N_GSYM - global variable
+ .stabs "name:sym_desc(global)type_def(19)=type_desc(array)
+ index_type_ref(int);NIL;high_bound(2);element_type_ref(char)";
+ N_GSYM, NIL, NIL, NIL
+
+32 .stabs "char_vec:G19=ar1;0;2;2",32,0,0,0
+33 .global _char_vec
+34 .align 4
+35 _char_vec:
+36 .byte 97
+37 .byte 98
+38 .byte 99
+@end example
+
+@node Enumerations, Structure Tags, Arrays, Aggregate Types
+@section Enumerations
+
+.stabs, stab type N_LSYM,
+ symbol descriptor T, type descriptor e
+
+The source line below declares an enumeration type. It is defined at
+file scope between the bodies of main and s_proc in example2.c.
+Because the N_LSYM is located after the N_RBRAC that marks the end of
+the previous procedure's block scope, and before the N_FUN that marks
+the beginning of the next procedure's block scope, the N_LSYM does not
+describe a block local symbol, but a file local one. The source line:
+
+@example
+29 enum e_places @{first,second=3,last@};
+@end example
+
+generates the following stab, located just after the N_RBRAC (close
+brace stab) for main. The type definition is in an N_LSYM stab
+because type definitions are file scope not global scope.
+
+@example
+ <128> N_LSYM - local symbol
+ .stab "name:sym_dec(type)type_def(22)=sym_desc(enum)
+ enum_name:value(0),enum_name:value(3),enum_name:value(4),;",
+ N_LSYM, NIL, NIL, NIL
+@end example
+
+104 .stabs "e_places:T22=efirst:0,second:3,last:4,;",128,0,0,0
+
+The symbol descriptor (T) says that the stab describes a structure,
+enumeration, or type tag. The type descriptor e, following the 22= of
+the type definition narrows it down to an enumeration type. Following
+the e is a list of the elements of the enumeration. The format is
+name:value,. The list of elements ends with a ;.
+
+@node Structure tags, Typedefs, Enumerations, Aggregate Types
+@section Structure Tags
+
+.stabs, stab type N_LSYM,
+ symbol descriptor T, type descriptor s
+
+The following source code declares a structure tag and defines an
+instance of the structure in global scope. Then a typedef equates the
+structure tag with a new type. A seperate stab is generated for the
+structure tag, the structure typedef, and the structure instance. The
+stabs for the tag and the typedef are emited when the definitions are
+encountered. Since the structure elements are not initialized, the
+stab and code for the structure variable itself is located at the end
+of the program in .common.
+
+@example
+6 struct s_tag @{
+7 int s_int;
+8 float s_float;
+9 char s_char_vec[8];
+10 struct s_tag* s_next;
+11 @} g_an_s;
+12
+13 typedef struct s_tag s_typedef;
+@end example
+
+The structure tag is an N_LSYM stab type because, like the enum, the
+symbol is file scope. Like the enum, the symbol descriptor is T, for
+enumeration, struct or tag type. The symbol descriptor s following
+the 16= of the type definition narrows the symbol type to struct.
+
+Following the struct symbol descriptor is the number of bytes the
+struct occupies, followed by a description of each structure element.
+The structure element descriptions are of the form name:type, bit
+offset from the start of the struct, and number of bits in the
+element.
+
+
+ <128> N_LSYM - type definition
+ .stabs "name:sym_desc(struct tag) Type_def(16)=type_desc(struct type)
+ struct_bytes
+ elem_name:type_ref(int),bit_offset,field_bits;
+ elem_name:type_ref(float),bit_offset,field_bits;
+ elem_name:type_def(17)=type_desc(dynamic array) index_type(int);NIL;
+ high_bound(7);element_type(char),bit_offset,field_bits;;",
+ N_LSYM,NIL,NIL,NIL
+
+30 .stabs "s_tag:T16=s20s_int:1,0,32;s_float:12,32,32;
+ s_char_vec:17=ar1;0;7;2,64,64;s_next:18=*16,128,32;;",128,0,0,0
+
+In this example, two of the structure elements are previously defined
+types. For these, the type following the name: part of the element
+description is a simple type reference. The other two structure
+elements are new types. In this case there is a type definition
+embedded after the name:. The type definition for the array element
+looks just like a type definition for a standalone array. The s_next
+field is a pointer to the same kind of structure that the field is an
+element of. So the definition of structure type 16 contains an type
+definition for an element which is a pointer to type 16.
+
+@node Typedefs, Unions, Structure tags, Aggregate Types
+@section Typedefs
+
+.stabs, stab type N_LSYM,
+ symbol descriptor t
+
+Here is the stab for the typedef equating the structure tag with a
+type.
+
+ <128> N_LSYM - type definition
+ .stabs "name:sym_desc(type name)type_ref(struct_tag)",N_LSYM,NIL,NIL,NIL
+
+31 .stabs "s_typedef:t16",128,0,0,0
+
+And here is the code generated for the structure variable.
+
+ <32> N_GSYM - global symbol
+ .stabs "name:sym_desc(global)type_ref(struct_tag)",N_GSYM,NIL,NIL,NIL
+
+@example
+136 .stabs "g_an_s:G16",32,0,0,0
+137 .common _g_an_s,20,"bss"
+@end example
+
+Notice that the structure tag has the same type number as the typedef
+for the structure tag. It is impossible to distinguish between a
+variable of the struct type and one of its typedef by looking at the
+debugging information.
+
+
+@node Unions, Function types, Typedefs, Aggregate Types
+@section Unions
+
+.stabs, stab type N_LSYM,
+ symbol descriptor T, type descriptor u
+
+Next lets look at unions. In example2 this union type is declared
+locally to a procedure and an instance of the union is defined.
+
+@example
+36 union u_tag @{
+37 int u_int;
+38 float u_float;
+39 char* u_char;
+40 @} an_u;
+@end example
+
+This code generates a stab for the union tag and a stab for the union
+variable. Both use the N_LSYM stab type. Since the union variable is
+scoped locally to the procedure in which it is defined, its stab is
+located immediatly preceeding the N_LBRAC for the procedure's block
+start.
+
+The stab for the union tag, however is located preceeding the code for
+the procedure in which it is defined. The stab type is N_LSYM. This
+would seem to imply that the union type is file scope, like the struct
+type s_tag. This is not true. The contents and position of the stab
+for u_type do not convey any infomation about its procedure local
+scope.
+
+ <128> N_LSYM - type
+ .stabs "name:sym_desc(union tag)type_def(22)=type_desc(union)
+ byte_size(4)
+ elem_name:type_ref(int),bit_offset(0),bit_size(32);
+ elem_name:type_ref(float),bit_offset(0),bit_size(32);
+ elem_name:type_ref(ptr to char),bit_offset(0),bit_size(32);;"
+ N_LSYM, NIL, NIL, NIL
+
+105 .stabs "u_tag:T23=u4u_int:1,0,32;u_float:12,0,32;u_char:21,0,32;;",128,0,0,0
+
+The symbol descriptor, T, following the name: means that the stab
+describes an enumeration struct or type tag. The type descriptor u,
+following the 23= of the type definition, narrows it down to a union
+type definition. Following the u is the number of bytes in the union.
+After that is a list of union element descriptions. Their format is
+name:type, bit offset into the union, and number of bytes for the
+element;.
+
+The stab for the union variable follows. Notice that the frame
+pointer offset for local variables is negative.
+
+ <128> N_LSYM - local variable (with no symbol descriptor)
+ .stabs "name:type_ref(u_tag)", N_LSYM, NIL, NIL, frame_ptr_offset
+
+130 .stabs "an_u:23",128,0,0,-20
+
+@node Function types, , Unions, Aggregate Types
+@section Function types
+
+type descriptor f
+
+The last type descriptor in C which remains to be described is used
+for function types. Consider the following source line defining a
+global function pointer.
+
+@example
+4 int (*g_pf)();
+@end example
+
+It generates the following code. Since the variable is not
+initialized, the code is located in the common area at the end of the
+file.
+
+ <32> N_GSYM - global variable
+ .stabs "name:sym_desc(global)type_def(24)=ptr_to(25)=
+ type_def(func)type_ref(int)
+
+134 .stabs "g_pf:G24=*25=f1",32,0,0,0
+135 .common _g_pf,4,"bss"
+
+Since the variable is global, the stab type is N_GSYM and the symbol
+descriptor is G. The variable defines a new type, 24, which is a
+pointer to another new type, 25, which is defined as a function
+returning int.
+
+@node Symbol tables, GNU C++ stabs, Aggregate types, Top
+@chapter Symbol information in symbol tables
+
+This section examines more closely the format of symbol table entries
+and how stab assembler directives map to them. It also describes what
+transformations the assembler and linker make on data from stabs.
+
+Each time the assembler encounters a stab in its input file it puts
+each field of the stab into corresponding fields in a symbol table
+entry of its output file. If the stab contains a string field, the
+symbol table entry for that stab points to a string table entry
+containing the string data from the stab. Assembler labels become
+relocatable addresses. Symbol table entries in a.out have the format:
+
+@example
+struct internal_nlist @{
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ bfd_vma n_value; /* value of symbol */
+@};
+@end example
+
+For .stabs directives, the n_strx field holds the character offset
+from the start of the string table to the string table entry
+containing the "string" field. For other classes of stabs (.stabn and
+.stabd) this field is null.
+
+Symbol table entries with n_type fields containing a value greater or
+equal to 0x20 originated as stabs generated by the compiler (with one
+random exception). Those with n_type values less than 0x20 were
+placed in the symbol table of the executable by the assembler or the
+linker.
+
+The linker concatenates object files and does fixups of externally
+defined symbols. You can see the transformations made on stab data by
+the assembler and linker by examining the symbol table after each pass
+of the build, first the assemble and then the link.
+
+To do this use nm with the -ap options. This dumps the symbol table,
+including debugging information, unsorted. For stab entries the
+columns are: value, other, desc, type, string. For assembler and
+linker symbols, the columns are: value, type, string.
+
+There are a few important things to notice about symbol tables. Where
+the value field of a stab contains a frame pointer offset, or a
+register number, that value is unchanged by the rest of the build.
+
+Where the value field of a stab contains an assembly language label,
+it is transformed by each build step. The assembler turns it into a
+relocatable address and the linker turns it into an absolute address.
+This source line defines a static variable at file scope:
+
+3 static int s_g_repeat
+
+The following stab describes the symbol.
+
+26 .stabs "s_g_repeat:S1",38,0,0,_s_g_repeat
+
+The assembler transforms the stab into this symbol table entry in the
+.o file. The location is expressed as a data segment offset.
+
+21 00000084 - 00 0000 STSYM s_g_repeat:S1
+
+in the symbol table entry from the executable, the linker has made the
+relocatable address absolute.
+
+22 0000e00c - 00 0000 STSYM s_g_repeat:S1
+
+Stabs for global variables do not contain location information. In
+this case the debugger finds location information in the assembler or
+linker symbol table entry describing the variable. The source line:
+
+1 char g_foo = 'c';
+
+generates the stab:
+
+21 .stabs "g_foo:G2",32,0,0,0
+
+The variable is represented by the following two symbol table entries
+in the object file. The first one originated as a stab. The second
+one is an external symbol. The upper case D signifies that the n_type
+field of the symbol table contains 7, N_DATA with local linkage (see
+Table B). The value field following the file's line number is empty
+for the stab entry. For the linker symbol it contains the
+rellocatable address corresponding to the variable.
+
+19 00000000 - 00 0000 GSYM g_foo:G2
+20 00000080 D _g_foo
+
+These entries as transformed by the linker. The linker symbol table
+entry now holds an absolute address.
+
+21 00000000 - 00 0000 GSYM g_foo:G2
+ ...
+215 0000e008 D _g_foo
+
+
+@node Gnu C++ stabs, , Symbol tables, Top
+@chapter Gnu C++ stabs
+
+@menu
+* Basic C++ types::
+* Simple classes::
+* Class instance::
+* Methods:: Method definition
+* Protections::
+* Method Modifiers:: (const, volatile, const volatile)
+* Virtual Methods::
+* Inheritence::
+* Virtual Base Classes::
+* Static Members::
+@end menu
+
+
+@subsection Symbol descriptors added for C++ descriptions:
+
+P - register parameter.
+
+@subsection type descriptors added for C++ descriptions
+
+@table @code
+@item #
+method type (two ## if minimal debug)
+
+@item xs
+cross-reference
+@end table
+
+
+@node Basic C++ types, , , Gnu C++ stabs
+@section Basic types for C++
+
+<< the examples that follow are based on a01.C >>
+
+
+C++ adds two more builtin types to the set defined for C. These are
+the unknown type and the vtable record type. The unknown type, type
+16, is defined in terms of itself like the void type.
+
+The vtable record type, type 17, is defined as a structure type and
+then as a structure tag. The structure has four fields, delta, index,
+pfn, and delta2. pfn is the function pointer.
+
+<< In boilerplate $vtbl_ptr_type, what are the fields delta,
+index, and delta2 used for? >>
+
+This basic type is present in all C++ programs even if there are no
+virtual methods defined.
+
+.stabs "struct_name:sym_desc(type)type_def(17)=type_desc(struct)struct_bytes(8)
+ elem_name(delta):type_ref(short int),bit_offset(0),field_bits(16);
+ elem_name(index):type_ref(short int),bit_offset(16),field_bits(16);
+ elem_name(pfn):type_def(18)=type_desc(ptr to)type_ref(void),
+ bit_offset(32),field_bits(32);
+ elem_name(delta2):type_def(short int);bit_offset(32),field_bits(16);;"
+ N_LSYM, NIL, NIL
+
+.stabs "$vtbl_ptr_type:t17=s8
+ delta:6,0,16;index:6,16,16;pfn:18=*15,32,32;delta2:6,32,16;;"
+ ,128,0,0,0
+
+.stabs "name:sym_dec(struct tag)type_ref($vtbl_ptr_type)",N_LSYM,NIL,NIL,NIL
+
+.stabs "$vtbl_ptr_type:T17",128,0,0,0
+
+@node Simple classes, , , Gnu C++ stabs
+@section Simple class definition
+
+The stabs describing C++ language features are an extension of the
+stabs describing C. Stabs representing C++ class types elaborate
+extensively on the stab format used to describe structure types in C.
+Stabs representing class type variables look just like stabs
+representing C language variables.
+
+Consider the following very simple class definition.
+
+@example
+class baseA @{
+public:
+ int Adat;
+ int Ameth(int in, char other);
+@};
+@end example
+
+The class baseA is represented by two stabs. The first stab describes
+the class as a structure type. The second stab describes a structure
+tag of the class type. Both stabs are of stab type N_LSYM. Since the
+stab is not located between an N_FUN and a N_LBRAC stab this indicates
+that the class is defined at file scope. If it were, then the N_LSYM
+would signify a local variable.
+
+A stab describing a C++ class type is similar in format to a stab
+describing a C struct, with each class member shown as a field in the
+structure. The part of the struct format describing fields is
+expanded to include extra information relevent to C++ class members.
+In addition, if the class has multiple base classes or virtual
+functions the struct format outside of the field parts is also
+augmented.
+
+In this simple example the field part of the C++ class stab
+representing member data looks just like the field part of a C struct
+stab. The section on protections describes how its format is
+sometimes extended for member data.
+
+The field part of a C++ class stab representing a member function
+differs substantially from the field part of a C struct stab. It
+still begins with `name:' but then goes on to define a new type number
+for the member function, describe its return type, its argument types,
+its protection level, any qualifiers applied to the method definition,
+and whether the method is virtual or not. If the method is virtual
+then the method description goes on to give the vtable index of the
+method, and the type number of the first base class defining the
+method.
+
+When the field name is a method name it is followed by two colons
+rather than one. This is followed by a new type definition for the
+method. This is a number followed by an equal sign and then the
+symbol descriptor `##', indicating a method type. This is followed by
+a type reference showing the return type of the method and a
+semi-colon.
+
+The format of an overloaded operator method name differs from that
+of other methods. It is "op$::XXXX." where XXXX is the operator name
+such as + or +=
+
+The next part of the method description represents the arguments to
+the method, preceeded by a colon and ending with a semi-colon. The
+types of the arguments are expressed in the same way argument types
+are expressed in C++ name mangling. In this example an int and a char
+map to `ic'.
+
+This is followed by a number, a letter, and an asterisk or period,
+followed by another semicolon. The number indicates the protections
+that apply to the member function. Here the 2 means public. The
+letter encodes any qualifier applied to the method definition. In
+this case A means that it is a normal function definition. The dot
+shows that the method is not virtual. The sections that follow
+elaborate further on these fields and describe the additional
+information present for virtual methods.
+
+
+.stabs "class_name:sym_desc(type)type_def(20)=type_desc(struct)struct_bytes(4)
+ field_name(Adat):type(int),bit_offset(0),field_bits(32);
+
+ method_name(Ameth)::type_def(21)=type_desc(method)return_type(int);
+ :arg_types(int char);
+ protection(public)qualifier(normal)virtual(no);;"
+ N_LSYM,NIL,NIL,NIL
+
+.stabs "baseA:t20=s4Adat:1,0,32;Ameth::21=##1;:ic;2A.;;",128,0,0,0
+
+.stabs "class_name:sym_desc(struct tag)",N_LSYM,NIL,NIL,NIL
+
+.stabs "baseA:T20",128,0,0,0
+
+@node Class instance, , , Gnu C++ stabs
+@section Class instance
+
+As shown above, describing even a simple C++ class definition is
+accomplished by massively extending the stab format used in C to
+describe structure types. However, once the class is defined, C stabs
+with no modifications can be used to describe class instances. The
+following source:
+
+@example
+main () @{
+ baseA AbaseA;
+@}
+@end example
+
+yeilds the following stab describing the class instance. It looks no
+different from a standard C stab describing a local variable.
+
+.stabs "name:type_ref(baseA)", N_LSYM, NIL, NIL, frame_ptr_offset
+
+.stabs "AbaseA:20",128,0,0,-20
+
+@node Methods, , , Gnu C++ stabs
+@section Method defintion
+
+The class definition shown above declares Ameth. The C++ source below
+defines Ameth:
+
+@example
+int
+baseA::Ameth(int in, char other)
+@{
+ return in;
+@};
+@end example
+
+
+This method definition yields three stabs following the code of the
+method. One stab describes the method itself and following two
+describe its parameters. Although there is only one formal argument
+all methods have an implicit argument which is the `this' pointer.
+The `this' pointer is a pointer to the object on which the method was
+called. Note that the method name is mangled to encode the class name
+and argument types. << Name mangling is not described by this
+document - Is there already such a doc? >>
+
+.stabs "name:symbol_desriptor(global function)return_type(int)",
+ N_FUN, NIL, NIL, code_addr_of_method_start
+
+.stabs "Ameth__5baseAic:F1",36,0,0,_Ameth__5baseAic
+
+Here is the stab for the `this' pointer implicit argument. The name
+of the `this' pointer is always $t. Type 19, the `this' pointer is
+defined as a pointer to type 20, baseA, but a stab defining baseA has
+not yet been emited. Since the compiler knows it will be emited
+shortly, here it just outputs a cross reference to the undefined
+symbol, by prefixing the symbol name with xs.
+
+.stabs "name:sym_desc(register param)type_def(19)=
+ type_desc(ptr to)type_ref(baseA)=
+ type_desc(cross-reference to)baseA:",N_RSYM,NIL,NIL,register_number
+
+.stabs "$t:P19=*20=xsbaseA:",64,0,0,8
+
+The stab for the explicit integer argument looks just like a parameter
+to a C function. The last field of the stab is the offset from the
+argument pointer, which in most systems is the same as the frame
+pointer.
+
+.stabs "name:sym_desc(value parameter)type_ref(int)",
+ N_PSYM,NIL,NIL,offset_from_arg_ptr
+
+.stabs "in:p1",160,0,0,72
+
+<< The examples that follow are based on A1.C >>
+
+@node Protections, , , Gnu C++ stabs
+@section Protections
+
+
+In the simple class definition shown above all member data and
+functions were publicly accessable. The example that follows
+contrasts public, protected and privately accessable fields and shows
+how these protections are encoded in C++ stabs.
+
+Protections for class member data are signified by two characters
+embeded in the stab defining the class type. These characters are
+located after the name: part of the string. /0 means private, /1
+means protected, and /2 means public. If these characters are omited
+this means that the member is public. The following C++ source:
+
+@example
+class all_data @{
+private:
+ int priv_dat;
+protected:
+ char prot_dat;
+public:
+ float pub_dat;
+@};
+@end example
+
+generates the following stab to describe the class type all_data.
+
+.stabs "class_name:sym_desc(type)type_def(19)=type_desc(struct)struct_bytes
+ data_name:/protection(private)type_ref(int),bit_offset,num_bits;
+ data_name:/protection(protected)type_ref(char),bit_offset,num_bits;
+ data_name:(/num omited, private)type_ref(float),bit_offset,num_bits;;"
+ N_LSYM,NIL,NIL,NIL
+
+.stabs "all_data:t19=s12
+ priv_dat:/01,0,32;prot_dat:/12,32,8;pub_dat:12,64,32;;",128,0,0,0
+
+Protections for member functions are signified by one digit embeded in
+the field part of the stab describing the method. The digit is 0 if
+private, 1 if protected and 2 if public. Consider the C++ class
+definition below:
+
+@example
+class all_methods @{
+private:
+ int priv_meth(int in)@{return in;@};
+protected:
+ char protMeth(char in)@{return in;@};
+public:
+ float pubMeth(float in)@{return in;@};
+@};
+@end example
+
+It generates the following stab. The digit in question is to the left
+of an `A' in each case. Notice also that in this case two symbol
+descriptors apply to the class name struct tag and struct type.
+
+.stabs "class_name:sym_desc(struct tag&type)type_def(21)=
+ sym_desc(struct)struct_bytes(1)
+ meth_name::type_def(22)=sym_desc(method)returning(int);
+ :args(int);protection(private)modifier(normal)virtual(no);
+ meth_name::type_def(23)=sym_desc(method)returning(char);
+ :args(char);protection(protected)modifier(normal)virual(no);
+ meth_name::type_def(24)=sym_desc(method)returning(float);
+ :args(float);protection(public)modifier(normal)virtual(no);;",
+ N_LSYM,NIL,NIL,NIL
+
+.stabs "all_methods:Tt21=s1priv_meth::22=##1;:i;0A.;protMeth::23=##2;:c;1A.;
+ pubMeth::24=##12;:f;2A.;;",128,0,0,0
+
+
+@node Method Modifiers, , , Gnu C++ stabs
+Method Modifiers (const, volatile, const volatile)
+
+<< based on a6.C >>
+
+In the class example described above all the methods have the normal
+modifier. This method modifier information is located just after the
+protection information for the method. This field has four possible
+character values. Normal methods use A, const methods use B, volatile
+methods use C, and const volatile methods use D. Consider the class
+definition below:
+
+@example
+class A @{
+public:
+ int ConstMeth (int arg) const @{ return arg; @};
+ char VolatileMeth (char arg) volatile @{ return arg; @};
+ float ConstVolMeth (float arg) const volatile @{return arg; @};
+@};
+@end example
+
+This class is described by the following stab:
+
+.stabs "class(A):sym_desc(struct)type_def(20)=type_desc(struct)struct_bytes(1)
+ meth_name(ConstMeth)::type_def(21)sym_desc(method)
+ returning(int);:arg(int);protection(public)modifier(const)virtual(no);
+ meth_name(VolatileMeth)::type_def(22)=sym_desc(method)
+ returning(char);:arg(char);protection(public)modifier(volatile)virt(no)
+ meth_name(ConstVolMeth)::type_def(23)=sym_desc(method)
+ returning(float);:arg(float);protection(public)modifer(const volatile)
+ virutal(no);;", etc...
+
+
+.stabs "A:T20=s1ConstMeth::21=##1;:i;2B.;VolatileMeth::22=##2;:c;2C.;
+ ConstVolMeth::23=##12;:f;2D.;;",128,0,0,0
+
+
+@node Virtual Methods, , , Gnu C++ stabs
+@section Virtual Methods
+
+<< The following examples are based on a4.C >>
+
+The presence of virtual methods in a class definition adds additional
+data to the class description. The extra data is appended to the
+description of the virtual method and to the end of the class
+description. Consider the class definition below:
+
+@example
+class A @{
+public:
+ int Adat;
+ virtual int A_virt (int arg) @{ return arg; @};
+@};
+@end example
+
+This results in the stab below describing class A. It defines a new
+type (20) which is an 8 byte structure. The first field of the class
+struct is Adat, an integer, starting at structure offset 0 and
+occupying 32 bits.
+
+The second field in the class struct is not explicitly defined by the
+C++ class definition but is implied by the fact that the class
+contains a virtual method. This field is the vtable pointer. The
+name of the vtable pointer field starts with $vf and continues with a
+type reference to the class it is part of. In this example the type
+reference for class A is 20 so the name of its vtable pointer field is
+$vf20, followed by the usual colon.
+
+Next there is a type definition for the vtable pointer type (21).
+This is in turn defined as a pointer to another new type (22).
+
+Type 22 is the vtable itself, which is defined as an array, indexed by
+integers, with a high bound of 1, and elements of type 17. Type 17
+was the vtable record type defined by the boilerplate C++ type
+definitions, as shown earlier.
+
+The bit offset of the vtable pointer field is 32. The number of bits
+in the field are not specified when the field is a vtable pointer.
+
+Next is the method definition for the virtual member function A_virt.
+Its description starts out using the same format as the non-virtual
+member functions described above, except instead of a dot after the
+`A' there is an asterisk, indicating that the function is virtual.
+Since is is virtual some addition information is appended to the end
+of the method description.
+
+The first number represents the vtable index of the method. This is a
+32 bit unsigned number with the high bit set, followed by a
+semi-colon.
+
+The second number is a type reference to the first base class in the
+inheritence hierarchy defining the virtual member function. In this
+case the class stab describes a base class so the virtual function is
+not overriding any other definition of the method. Therefore the
+reference is to the type number of the class that the stab is
+describing (20).
+
+This is followed by three semi-colons. One marks the end of the
+current sub-section, one marks the end of the method field, and the
+third marks the end of the struct definition.
+
+For classes containing virtual functions the very last section of the
+string part of the stab holds a type reference to the first base
+class. This is preceeded by `~%' and followed by a final semi-colon.
+
+.stabs "class_name(A):type_def(20)=sym_desc(struct)struct_bytes(8)
+ field_name(Adat):type_ref(int),bit_offset(0),field_bits(32);
+ field_name(A virt func ptr):type_def(21)=type_desc(ptr to)type_def(22)=
+ sym_desc(array)index_type_ref(int);NIL;elem_type_ref(vtbl elem type);
+ bit_offset(32);
+ meth_name(A_virt)::typedef(23)=sym_desc(method)returning(int);
+ :arg_type(int),protection(public)normal(yes)virtual(yes)
+ vtable_index(1);class_first_defining(A);;;~%first_base(A);",
+ N_LSYM,NIL,NIL,NIL
+
+.stabs "A:t20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
+
+
+@node Inheritence, , , Gnu C++ stabs
+@section Inheritence
+
+Stabs describing C++ derived classes include additional sections that
+describe the inheritence hierarchy of the class. A derived class stab
+also encodes the number of base classes. For each base class it tells
+if the base class is virtual or not, and if the inheritence is private
+or public. It also gives the offset into the object of the portion of
+the object corresponding to each base class.
+
+This additional information is embeded in the class stab following the
+number of bytes in the struct. First the number of base classes
+appears bracketed by an exclamation point and a comma.
+
+Then for each base type there repeats a series: two digits, a number,
+a comma, another number, and a semi-colon.
+
+The first of the two digits is 1 if the base class is virtual and 0 if
+not. The second digit is 2 if the derivation is public and 0 if not.
+
+The number following the first two digits is the offset from the start
+of the object to the part of the object pertaining to the base class.
+
+After the comma, the second number is a type_descriptor for the base
+type. Finally a semi-colon ends the series, which repeats for each
+base class.
+
+The source below defines three base classes A, B, and C and the
+derived class D.
+
+
+@example
+class A @{
+public:
+ int Adat;
+ virtual int A_virt (int arg) @{ return arg; @};
+@};
+
+class B @{
+public:
+ int B_dat;
+ virtual int B_virt (int arg) @{return arg; @};
+@};
+
+class C @{
+public:
+ int Cdat;
+ virtual int C_virt (int arg) @{return arg; @};
+@};
+
+class D : A, virtual B, public C @{
+public:
+ int Ddat;
+ virtual int A_virt (int arg ) @{ return arg+1; @};
+ virtual int B_virt (int arg) @{ return arg+2; @};
+ virtual int C_virt (int arg) @{ return arg+3; @};
+ virtual int D_virt (int arg) @{ return arg; @};
+@};
+@end example
+
+Class stabs similar to the ones described earlier are generated for
+each base class.
+
+.stabs "A:T20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
+
+.stabs "B:Tt25=s8Bdat:1,0,32;$vf25:21,32;B_virt::26=##1;:i;2A*-2147483647;25;;;~%25;",128,0,0,0
+
+.stabs "C:Tt28=s8Cdat:1,0,32;$vf28:21,32;C_virt::29=##1;:i;2A*-2147483647;28;;;~%28;",128,0,0,0
+
+In the stab describing derived class D below, the information about
+the derivation of this class is encoded as follows.
+
+.stabs "derived_class_name:symbol_descriptors(struct tag&type)=
+ type_descriptor(struct)struct_bytes(32)!num_bases(3),
+ base_virtual(no)inheritence_public(no)base_offset(0),
+ base_class_type_ref(A);
+ base_virtual(yes)inheritence_public(no)base_offset(NIL),
+ base_class_type_ref(B);
+ base_virtual(no)inheritence_public(yes)base_offset(64),
+ base_class_type_ref(C); etc...
+
+.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:1,160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt::32:i;2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;28;;D_virt::32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
+
+
+@node Virtual Base Classes, , , Gnu C++ stabs
+@section Virtual Base Classes
+
+A derived class object consists of a concatination in memory of the
+data areas defined by each base class, starting with the leftmost and
+ending with the rightmost in the list of base classes. The exception
+to this rule is for virtual inheritence. In the example above, class
+D inherits virtually from base class B. This means that an instance
+of a D object will not contain it's own B part but merely a pointer to
+a B part, known as a virtual base pointer.
+
+In a derived class stab, the base offset part of the derivation
+information, described above, shows how the base class parts are
+ordered. The base offset for a virtual base class is always given as
+0. Notice that the base offset for B is given as 0 even though B is
+not the first base class. The first base class A starts at offset 0.
+
+The field information part of the stab for class D describes the field
+which is the pointer to the virtual base class B. The vbase pointer
+name is $vb followed by a type reference to the virtual base class.
+Since the type id for B in this example is 25, the vbase pointer name
+is $vb25.
+
+.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:1,160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt::32:i;2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;28;;D_virt::32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
+
+Following the name and a semicolon is a type reference describing the
+type of the virtual base class pointer, in this case 24. Type 24 was
+defined earlier as the type of the B class `this` pointer, $t. The
+`this' pointer for a class is a pointer to the class type.
+
+.stabs "$t:P24=*25=xsB:",64,0,0,8
+
+Finally the field offset part of the vbase pointer field description
+shows that the vbase pointer is the first field in the D object,
+before any data fields defined by the class. The layout of a D class
+object is a follows, Adat at 0, the vtable pointer for A at 32, Cdat
+at 64, the vtable pointer for C at 96, the virtual ase pointer for B
+at 128, and Ddat at 160.
+
+
+@node Static Members, , , Gnu C++ stabs
+@section Static Members
+
+The data area for a class is a concatination of the space used by the
+data members of the class. If the class has virtual methods a vtable
+pointer follows the class data. The field offset part of each field
+description in the class stab shows this ordering.
+
+<< how is this reflected in stabs? >>
+
+@node Example2.c, Example2.s, , Top
+@appendix Example2.c - source code for extended example
+
+@example
+1 char g_foo = 'c';
+2 register int g_bar asm ("%g5");
+3 static int s_g_repeat = 2;
+4 int (*g_pf)();
+5
+6 struct s_tag @{
+7 int s_int;
+8 float s_float;
+9 char s_char_vec[8];
+10 struct s_tag* s_next;
+11 @} g_an_s;
+12
+13 typedef struct s_tag s_typedef;
+14
+15 char char_vec[3] = @{'a','b','c'@};
+16
+17 main (argc, argv)
+18 int argc;
+19 char* argv[];
+20 @{
+21 static float s_flap;
+22 int times;
+23 for (times=0; times < s_g_repeat; times++)@{
+24 int inner;
+25 printf ("Hello world\n");
+26 @}
+27 @};
+28
+29 enum e_places @{first,second=3,last@};
+30
+31 static s_proc (s_arg, s_ptr_arg, char_vec)
+32 s_typedef s_arg;
+33 s_typedef* s_ptr_arg;
+34 char* char_vec;
+35 @{
+36 union u_tag @{
+37 int u_int;
+38 float u_float;
+39 char* u_char;
+40 @} an_u;
+41 @}
+42
+43
+@end example
+
+@node Example2.s, , Example2.c, Top
+@appendix Example2.s - assembly code for extended example
+
+@example
+1 gcc2_compiled.:
+2 .stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0
+3 .stabs "example2.c",100,0,0,Ltext0
+4 .text
+5 Ltext0:
+6 .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
+7 .stabs "char:t2=r2;0;127;",128,0,0,0
+8 .stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
+9 .stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
+10 .stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
+11 .stabs "short int:t6=r1;-32768;32767;",128,0,0,0
+12 .stabs "long long int:t7=r1;0;-1;",128,0,0,0
+13 .stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
+14 .stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
+15 .stabs "signed char:t10=r1;-128;127;",128,0,0,0
+16 .stabs "unsigned char:t11=r1;0;255;",128,0,0,0
+17 .stabs "float:t12=r1;4;0;",128,0,0,0
+18 .stabs "double:t13=r1;8;0;",128,0,0,0
+19 .stabs "long double:t14=r1;8;0;",128,0,0,0
+20 .stabs "void:t15=15",128,0,0,0
+21 .stabs "g_foo:G2",32,0,0,0
+22 .global _g_foo
+23 .data
+24 _g_foo:
+25 .byte 99
+26 .stabs "s_g_repeat:S1",38,0,0,_s_g_repeat
+27 .align 4
+28 _s_g_repeat:
+29 .word 2
+30 .stabs "s_tag:T16=s20s_int:1,0,32;s_float:12,32,32;s_char_vec:17=ar1;0;7;2,64,64;s_next:18=*16,128,32;;",128,0,0,0
+31 .stabs "s_typedef:t16",128,0,0,0
+32 .stabs "char_vec:G19=ar1;0;2;2",32,0,0,0
+33 .global _char_vec
+34 .align 4
+35 _char_vec:
+36 .byte 97
+37 .byte 98
+38 .byte 99
+39 .reserve _s_flap.0,4,"bss",4
+40 .text
+41 .align 4
+42 LC0:
+43 .ascii "Hello world\12\0"
+44 .align 4
+45 .global _main
+46 .proc 1
+47 _main:
+48 .stabn 68,0,20,LM1
+49 LM1:
+50 !#PROLOGUE# 0
+51 save %sp,-144,%sp
+52 !#PROLOGUE# 1
+53 st %i0,[%fp+68]
+54 st %i1,[%fp+72]
+55 call ___main,0
+56 nop
+57 LBB2:
+58 .stabn 68,0,23,LM2
+59 LM2:
+60 st %g0,[%fp-20]
+61 L2:
+62 sethi %hi(_s_g_repeat),%o0
+63 ld [%fp-20],%o1
+64 ld [%o0+%lo(_s_g_repeat)],%o0
+65 cmp %o1,%o0
+66 bge L3
+67 nop
+68 LBB3:
+69 .stabn 68,0,25,LM3
+70 LM3:
+71 sethi %hi(LC0),%o1
+72 or %o1,%lo(LC0),%o0
+73 call _printf,0
+74 nop
+75 .stabn 68,0,26,LM4
+76 LM4:
+77 LBE3:
+78 .stabn 68,0,23,LM5
+79 LM5:
+80 L4:
+81 ld [%fp-20],%o0
+82 add %o0,1,%o1
+83 st %o1,[%fp-20]
+84 b,a L2
+85 L3:
+86 .stabn 68,0,27,LM6
+87 LM6:
+88 LBE2:
+89 .stabn 68,0,27,LM7
+90 LM7:
+91 L1:
+92 ret
+93 restore
+94 .stabs "main:F1",36,0,0,_main
+95 .stabs "argc:p1",160,0,0,68
+96 .stabs "argv:p20=*21=*2",160,0,0,72
+97 .stabs "s_flap:V12",40,0,0,_s_flap.0
+98 .stabs "times:1",128,0,0,-20
+99 .stabn 192,0,0,LBB2
+100 .stabs "inner:1",128,0,0,-24
+101 .stabn 192,0,0,LBB3
+102 .stabn 224,0,0,LBE3
+103 .stabn 224,0,0,LBE2
+104 .stabs "e_places:T22=efirst:0,second:3,last:4,;",128,0,0,0
+105 .stabs "u_tag:T23=u4u_int:1,0,32;u_float:12,0,32;u_char:21,0,32;;",128,0,0,0
+106 .align 4
+107 .proc 1
+108 _s_proc:
+109 .stabn 68,0,35,LM8
+110 LM8:
+111 !#PROLOGUE# 0
+112 save %sp,-120,%sp
+113 !#PROLOGUE# 1
+114 mov %i0,%o0
+115 st %i1,[%fp+72]
+116 st %i2,[%fp+76]
+117 LBB4:
+118 .stabn 68,0,41,LM9
+119 LM9:
+120 LBE4:
+121 .stabn 68,0,41,LM10
+122 LM10:
+123 L5:
+124 ret
+125 restore
+126 .stabs "s_proc:f1",36,0,0,_s_proc
+127 .stabs "s_arg:p16",160,0,0,0
+128 .stabs "s_ptr_arg:p18",160,0,0,72
+129 .stabs "char_vec:p21",160,0,0,76
+130 .stabs "an_u:23",128,0,0,-20
+131 .stabn 192,0,0,LBB4
+132 .stabn 224,0,0,LBE4
+133 .stabs "g_bar:r1",64,0,0,5
+134 .stabs "g_pf:G24=*25=f1",32,0,0,0
+135 .common _g_pf,4,"bss"
+136 .stabs "g_an_s:G16",32,0,0,0
+137 .common _g_an_s,20,"bss"
+@end example
+
+
+@node Quick reference, Expanded reference, , Top
+@appendix Quick reference
+
+@menu
+* Stab types:: Table A: Symbol types from stabs
+* Assembler types:: Table B: Symbol types from assembler and linker
+* Symbol descriptors:: Table C
+* Type Descriptors:: Table D
+@end menu
+
+@node Stab types, Assembler types, , Quick reference
+@section Table A: Symbol types from stabs
+
+Table A lists stab types sorted by type number. Stab type numbers are
+32 and greater. This is the full list of stab numbers, including stab
+types that are used in languages other than C.
+
+The #define names for these stab types are defined in:
+devo/include/aout/stab.def
+
+@example
+type type #define used to describe
+dec hex name source program feature
+-------------------------------------------------------------------------------
+32 0x20 N_GYSM global symbol
+34 0X22 N_FNAME function name (for BSD Fortran)
+36 0x24 N_FUN function name or text segment variable for C
+38 0x26 N_STSYM static symbol (data segment w/internal linkage)
+40 0x28 N_LCSYM .lcomm symbol(BSS-seg variable w/internal linkage)
+42 0x2a N_MAIN Name of main routine (not used in C)
+48 0x30 N_PC global symbol (for Pascal)
+50 0x32 N_NSYMS number of symbols (according to Ultrix V4.0)
+52 0x34 N_NOMAP no DST map for sym (according to Ultrix V4.0)
+64 0x40 N_RSYM register variable
+66 0x42 N_M2C Modula-2 compilation unit
+68 0x44 N_SLINE line number in text segment
+70 0x46 N_DSLINE line number in data segment
+
+72 0x48 N_BSLINE line number in bss segment
+72 0x48 N_BROWS Sun source code browser, path to .cb file
+
+74 0x4a N_DEFD Gnu Modula2 definition module dependency
+
+80 0x50 N_EHDECL Gnu C++ exception variable
+80 0x50 N_MOD2 Modula2 info "for imc" (according to Ultrix V4.0)
+
+84 0x54 N_CATCH Gnu C++ "catch" clause
+96 0x60 N_SSYM structure of union element
+100 0x64 N_SO path and name of source file
+128 0x80 N_LSYM automatic var in the stack (also used for type desc.)
+130 0x82 N_BINCL beginning of an include file (Sun only)
+132 0x84 N_SOL Name of sub-source (#include) file.
+160 0xa0 N_PSYM parameter variable
+162 0xa2 N_EINCL end of an include file
+164 0xa4 N_ENTRY alternate entry point
+192 0xc0 N_LBRAC beginning of a lexical block
+194 0xc2 N_EXCL place holder for a deleted include file
+196 0xc4 N_SCOPE modula2 scope information (Sun linker)
+224 0xe0 N_RBRAC end of a lexical block
+226 0xe2 N_BCOMM begin named common block
+228 0xe4 N_ECOMM end named common block
+232 0xe8 N_ECOML end common (local name)
+
+ << used on Gould systems for non-base registers syms >>
+240 0xf0 N_NBTEXT ??
+242 0xf2 N_NBDATA ??
+244 0xf4 N_NBBSS ??
+246 0xf6 N_NBSTS ??
+248 0xf8 N_NBLCS ??
+@end example
+
+@node Assembler types, Symbol descriptors, Stab types, Quick reference
+@section Table B: Symbol types from assembler and linker
+
+Table B shows the types of symbol table entries that hold assembler
+and linker symbols.
+
+The #define names for these n_types values are defined in
+/include/aout/aout64.h
+
+@example
+dec hex #define
+n_type n_type name used to describe
+-----------------------------------------------------------------------------
+1 0x0 N_UNDF undefined symbol
+2 0x2 N_ABS absolute symbol -- defined at a particular address
+3 0x3 extern " (vs. file scope)
+4 0x4 N_TEXT text symbol -- defined at offset in text segment
+5 0x5 extern " (vs. file scope)
+6 0x6 N_DATA data symbol -- defined at offset in data segment
+7 0x7 extern " (vs. file scope)
+8 0x8 N_BSS BSS symbol -- defined at offset in zero'd segment
+9 extern " (vs. file scope)
+
+12 0x0C N_FN_SEQ func name for Sequent compilers (stab exception)
+
+49 0x12 N_COMM common sym -- visable after shared lib dynamic link
+31 0x1f N_FN file name of a .o file
+@end example
+
+@node Symbol descriptors, Type descriptors, Assembler types, Quick reference
+@section Table C: Symbol descriptors
+
+@example
+descriptor meaning
+-------------------------------------------------
+(empty) local variable
+ f local function
+ F global function
+ G global variable
+ p value parameter
+ r register variable
+ S static global variable
+ t type name
+ T enumeration, struct or type tag
+ V static local variable
+@end example
+
+@node Type Descriptors, , Symbol descriptors, Quick reference
+@section Table D: Type Descriptors
+
+@example
+descriptor meaning
+-------------------------------------
+(empty) type reference
+ a array type
+ e enumeration type
+ f function type
+ r range type
+ s structure type
+ u union specifications
+ * pointer type
+@end example
+
+
+@node Expanded reference, , Quick reference, Top
+@appendix Expanded reference by stab type.
+
+Format of an entry:
+
+The first line is the symbol type expressed in decimal, hexadecimal,
+and as a #define (see devo/include/aout/stab.def).
+
+The second line describes the language constructs the symbol type
+represents.
+
+The third line is the stab format with the significant stab fields
+named and the rest NIL.
+
+Subsequent lines expand upon the meaning and possible values for each
+significant stab field. # stands in for the type descriptor.
+
+Finally, any further information.
+
+----------------------------------------------------------------------
+32 - 0x20 - N_GYSM
+Global variable.
+
+.stabs "name", N_GSYM, NIL, NIL, NIL
+
+"name" -> "symbol_name:#type"
+ # -> G
+
+Only the "name" field is significant. the location of the variable is
+obtained from the corresponding external symbol.
+
+----------------------------------------------------------------------
+34 - 0x22 - N_FNAME
+Function name (for BSD Fortran)
+
+.stabs "name", N_FNAME, NIL, NIL, NIL
+
+"name" -> "function_name"
+
+Only the "name" field is significant. The location of the symbol is
+obtained from the corresponding extern symbol.
+
+----------------------------------------------------------------------
+36 - 0x24 - N_FUN
+Function name or text segment variable for C.
+
+.stabs "name", N_FUN, NIL, desc, value
+
+For functions:
+-------------
+"name" -> "proc_name:#return_type"
+ # -> F (global function)
+ f (local function)
+desc -> line num for proc start. (GCC doesn't set and DBX doesn't miss it.)
+value -> Code address of proc start.
+
+For text segment variables:
+--------------------------
+<<How to create one?>>
+
+----------------------------------------------------------------------
+38 - 0x26 - N_STSYM
+Initialized static symbol (data segment w/internal linkage).
+
+.stabs "name", N_STSYM, NIL, NIL, value
+
+"name" -> "symbol_name#type"
+ # -> S (scope global to compilation unit)
+ -> V (scope local to a procedure)
+value -> Data Address
+
+----------------------------------------------------------------------
+40 - 0x28 - N_LCSYM
+Unitialized static (.lcomm) symbol(BSS segment w/internal linkage).
+
+.stabs "name", N_LCLSYM, NIL, NIL, value
+
+"name" -> "symbol_name#type"
+ # -> S (scope global to compilation unit)
+ -> V (scope local to procedure)
+value -> BSS Address
+
+----------------------------------------------------------------------
+42 - 0x2a - N_MAIN
+Name of main routine (not used in C)
+
+.stabs "name", N_MAIN, NIL, NIL, NIL
+
+"name" -> "name_of_main_routine"
+
+----------------------------------------------------------------------
+48 - 0x30 - N_PC
+Global symbol (for Pascal)
+
+.stabs "name", N_PC, NIL, NIL, value
+
+"name" -> "symbol_name" <<?>>
+value -> supposedly the line number (stab.def is skeptical)
+
+stabdump.c says:
+
+global pascal symbol: name,,0,subtype,line
+<< subtype? >>
+
+----------------------------------------------------------------------
+50 - 0x32 - N_NSYMS
+Number of symbols (according to Ultrix V4.0)
+
+ 0, files,,funcs,lines (stab.def)
+
+----------------------------------------------------------------------
+
+52 - 0x34 - N_NOMAP
+no DST map for sym (according to Ultrix V4.0)
+
+ name, ,0,type,ignored (stab.def)
+----------------------------------------------------------------------
+64 - 0x40 - N_RSYM
+ register variable
+
+.stabs "name:type",N_RSYM,0,RegSize,RegNumber (Sun doc)
+
+----------------------------------------------------------------------
+66 - 0x42 - N_M2C
+Modula-2 compilation unit
+
+.stabs "name", N_M2C, 0, desc, value
+
+"name" -> "unit_name,unit_time_stamp[,code_time_stamp]
+desc -> unit_number
+value -> 0 (main unit)
+ 1 (any other unit)
+
+-----------------------------------------------------------------------
+68 - 0x44 - N_SLINE
+Line number in text segment
+
+.stabn N_SLINE, 0, desc, value
+
+desc -> line_number
+value -> code_address (relocatable addr where the corresponding code starts)
+
+For single source lines that generate discontiguous code, such as flow
+of control statements, there may be more than one N_SLINE stab for the
+same source line. In this case there is a stab at the start of each
+code range, each with the same line number.
+
+-----------------------------------------------------------------------
+70 - 0x46 - N_DSLINE
+Line number in data segment
+
+.stabn N_DSLINE, 0, desc, value
+
+desc -> line_number
+value -> data_address (relocatable addr where the corresponding code starts)
+
+See comment for N_SLINE above.
+
+-------------------------------------------------------------------------
+72 - 0x48 - N_BSLINE
+Line number in bss segment
+
+.stabn N_BSLINE, 0, desc, value
+
+desc -> line_number
+value -> bss_address (relocatable addr where the corresponding code starts)
+
+See comment for N_SLINE above.
+
+-------------------------------------------------------------------------
+72 0x48 N_BROWS
+Sun source code browser, path to .cb file
+
+<<?>>
+"path to associated .cb file"
+
+Note: type field value overlaps with N_BSLINE
+
+-------------------------------------------------------------------------
+74 0x4a N_DEFD
+Gnu Modula2 definition module dependency
+
+GNU Modula-2 definition module dependency. Value is the modification
+time of the definition file. Other is non-zero if it is imported with
+the GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there
+are enough empty fields?
+
+-------------------------------------------------------------------------
+80 0x50 N_EHDECL
+Gnu C++ exception variable <<?>>
+
+"name is variable name"
+
+Note: conflicts with N_MOD2.
+
+-------------------------------------------------------------------------
+80 0x50 N_MOD2 Modula2 info "for imc" (according to Ultrix V4.0)
+
+Note: conflicts with N_EHDECL <<?>>
+
+-------------------------------------------------------------------------
+84 0x54 N_CATCH Gnu C++ "catch" clause
+
+GNU C++ `catch' clause. Value is its address. Desc is nonzero if
+this entry is immediately followed by a CAUGHT stab saying what
+exception was caught. Multiple CAUGHT stabs means that multiple
+exceptions can be caught here. If Desc is 0, it means all exceptions
+are caught here.
+
+-------------------------------------------------------------------------
+96 - 0x60 - N_SSYM
+Structure or union element
+
+Value is offset in the structure. <<?looking at structs and unions in C
+I didn't see these>>
+
+-------------------------------------------------------------------------
+100 - 0x64 - N_SO
+Path and name of source file containing main routine
+
+.stabs "name", N_SO, NIL, NIL, value
+
+"name" -> /path/to/source/file
+ -> source_file_terminal_name
+
+value -> the starting text address of the compilation.
+
+These are found two in a row. The name field of the first N_SO
+contains the path to the source file. The name field of the second
+N_SO contains the terminal name of the source file itself.
+
+-------------------------------------------------------------------------
+128 - 0x80 - N_LSYM
+Automatic var in the stack (also used for type descriptors.)
+
+.stabs "name" N_LSYM, NIL, NIL, value
+
+For stack based local variables:
+--------------------------------
+
+"name" -> name of the variable
+value -> offset from frame pointer (negative)
+
+For type descriptors:
+---------------------
+
+"name" -> "name_of_the_type:#type"
+ # -> t
+
+type -> type_ref (or) type_def
+
+type_ref -> type_number
+type_def -> type_number=type_desc etc.
+
+Type may be either a type reference or a type definition. A type
+reference is a number that refers to a previously defined type. A
+type definition is the number that will refer to this type, followed
+by an equals sign, a type descriptor and the additional data that
+defines the type. See the Table D for type descriptors and the
+section on types for what data follows each type descriptor.
+
+-------------------------------------------------------------------------
+130 - 0x82 - N_BINCL
+
+Beginning of an include file (Sun only)
+
+Beginning of an include file. Only Sun uses this. In an object file,
+only the name is significant. The Sun linker puts data into some of
+the other fields.
+
+-------------------------------------------------------------------------
+132 - 0x84 - N_SOL
+
+Name of a sub-source file (#include file). Value is starting address
+of the compilation.
+<<?>>
+
+-------------------------------------------------------------------------
+160 - 0xa0 - N_PSYM
+
+Parameter variable
+
+stabs. "name", N_PSYM, NIL, NIL, value
+
+"name" -> "param_name:#type"
+ # -> p (value parameter)
+ -> i (value parameter by reference, indirect access)
+ -> v (variable parameter by reference)
+ -> C ( read-only parameter, conformant array bound)
+ -> x (confomant array value parameter)
+ -> pP (<<??>>)
+ -> pF (<<??>>)
+ -> X (function result variable)
+ -> b (based variable)
+
+value -> offset from the argument pointer (positive).
+
+On most machines the argument pointer is the same as the frame
+pointer.
+
+-------------------------------------------------------------------------
+162 - 0xa2 - N_EINCL
+
+End of an include file. This and N_BINCL act as brackets around the
+file's output. In an ojbect file, there is no significant data in
+this entry. The Sun linker p8uts data into some of the fields.
+<<?>>
+
+-------------------------------------------------------------------------
+164 - 0xa4 - N_ENTRY
+
+Alternate entry point.
+Value is its address.
+<<?>>
+
+-------------------------------------------------------------------------
+192 - 0xc0 - N_LBRAC
+
+Beginning of a lexical block (left brace). The variable defined
+inside the block precede the N_LBRAC symbol. Or can they follow as
+well as long as a new N_FUNC was not encountered. <<?>>
+
+.stabn N_LBRAC, NIL, NIL, value
+
+value -> code address of block start.
+
+-------------------------------------------------------------------------
+194 - 0xc2 - N_EXCL
+
+Place holder for a deleted include file. Replaces a N_BINCL and
+everything up to the corresponding N_EINCL. The Sun linker generates
+these when it finds multiple indentical copies of the symbols from an
+included file. This appears only in output from the Sun linker.
+<<?>>
+
+-------------------------------------------------------------------------
+196 - 0xc4 - N_SCOPE
+
+Modula2 scope information (Sun linker)
+<<?>>
+
+-------------------------------------------------------------------------
+224 - 0xe0 - N_RBRAC
+
+End of a lexical block (right brace)
+
+.stabn N_RBRAC, NIL, NIL, value
+
+value -> code address of the end of the block.
+
+-------------------------------------------------------------------------
+226 - 0xe2 - N_BCOMM
+
+Begin named common block.
+
+Only the name is significant.
+<<?>>
+
+-------------------------------------------------------------------------
+228 - 0xe4 - N_ECOMM
+
+End named common block.
+
+Only the name is significant and it should match the N_BCOMM
+<<?>>
+
+-------------------------------------------------------------------------
+ 232 - 0xe8 - N_ECOML
+
+End common (local name)
+
+value is address.
+<<?>>
+
+-------------------------------------------------------------------------
+<< used on Gould systems for non-base registers syms, values assigned
+at random, need real info from Gould. >>
+<<?>>
+
+240 0xf0 N_NBTEXT ??
+242 0xf2 N_NBDATA ??
+244 0xf4 N_NBBSS ??
+246 0xf6 N_NBSTS ??
+248 0xf8 N_NBLCS ??
+
+-------------------------------------------------------------------------
+ - 0xfe - N_LENG
+
+Second symbol entry containing a length-value for the preceding entry.
+The value is the length.
+
+@node Questions, , , Top
+@appendix Questions and anomolies
+
+@itemize @bullet
+@item
+For GNU C stabs defining local and global variables (N_LSYM and
+N_GSYM), the desc field is supposed to contain the source line number
+on which the variable is defined. In reality the desc field is always
+0. (This behavour is defined in dbxout.c and putting a line number in
+desc is controlled by #ifdef WINNING_GDB which defaults to false). Gdb
+supposedly uses this information if you say 'list var'. In reality
+var can be a variable defined in the program and gdb says `function
+var not defined'
+
+@item
+In Gnu C stabs there seems to be no way to differentiate tag types:
+structures, unions, and enums (symbol descriptor T) and typedefs
+(symbol descriptor t) defined at file scope from types defined locally
+to a procedure or other more local scope. They all use the N_LSYM
+stab type. Types defined at procedure scope are emited after the
+N_RBRAC of the preceeding function and before the code of the
+procedure in which they are defined. This is exactly the same as
+types defined in the source file between the two procedure bodies.
+GDB overcompensates by placing all types in block #1 the block for
+symbols of file scope. This is true for default, -ansi and
+-traditional compiler options. (p0001063-gcc, p0001066-gdb)
+
+@item
+What ends the procedure scope? Is it the proc block's N_RBRAC or the
+next N_FUN? (I believe its the first.)
+
+@item
+The comment in xcoff.h says DBX_STATIC_CONST_VAR_CODE is used for
+static const variables. DBX_STATIC_CONST_VAR_CODE is set to N_FUN by
+default, in dbxout.c. If included, xcoff.h redefines it to N_STSYM.
+But testing the default behaviour, my Sun4 native example shows
+N_STSYM not N_FUN is used to describe file static initialized
+variables. (the code tests for TREE_READONLY(decl) &&
+!TREE_THIS_VOLATILE(decl) and if true uses DBX_STATIC_CONST_VAR_CODE).
+
+@item
+Global variable stabs don't have location information. This comes
+from the external symbol for the same variable. The external symbol
+has a leading underbar on the _name of the variable and the stab does
+not. How do we know these two symbol table entries are talking about
+the same symbol when their names are different?
+
+@item
+Can gcc be configured to output stabs the way the Sun compiler
+does, so that their native debugging tools work? <NO?> It doesn't by
+default. GDB reads either format of stab. (gcc or SunC). How about
+dbx?
+@end itemize
+
+@node xcoff-differences, Sun-differences, , Top
+@appendix Differences between GNU stabs in a.out and GNU stabs in xcoff
+
+(The AIX/RS6000 native object file format is xcoff with stabs)
+
+@itemize @bullet
+@item
+Instead of .stabs, xcoff uses .stabx.
+
+@item
+The data fields of an xcoff .stabx are in a different order than an
+a.out .stabs. The order is: string, value, type. The desc and null
+fields present in a.out stabs are missing in xcoff stabs. For N_GSYM
+the value field is the name of the symbol.
+
+@item
+BSD a.out stab types map to AIX xcoff storage classes. In general the
+mapping is N_STABTYPE becomes C_STABTYPE. Some stab types in a.out
+are not supported in xcoff. See Table E. for full mappings.
+
+exception:
+initialised static N_STSYM and un-initialized static N_LCSYM both map
+to the C_STSYM storage class. But the destinction is preserved
+because in xcoff N_STSYM and N_LCSYM must be emited in a named static
+block. Begin the block with .bs s[RW] data_section_name for N_STSYM
+or .bs s bss_section_name for N_LCSYM. End the block with .es
+
+@item
+xcoff stabs describing tags and typedefs use the N_DECL (0x8c)instead
+of N_LSYM stab type.
+
+@item
+xcoff uses N_RPSYM (0x8e) instead of the N_RSYM stab type for register
+variables. If the register variable is also a value parameter, then
+use R instead of P for the symbol descriptor.
+
+6.
+xcoff uses negative numbers as type references to the basic types.
+There are no boilerplate type definitions emited for these basic
+types. << make table of basic types and type numbers for C >>
+
+@item
+xcoff .stabx sometimes don't have the name part of the string field.
+
+@item
+xcoff uses a .file stab type to represent the source file name. There
+is no stab for the path to the source file.
+
+@item
+xcoff uses a .line stab type to represent source lines. The format
+is: .line line_number.
+
+@item
+xcoff emits line numbers relative to the start of the current
+function. The start of a function is marked by .bf. If a function
+includes lines from a seperate file, then those line numbers are
+absolute line numbers in the <<sub-?>> file being compiled.
+
+@item
+The start of current include file is marked with: .bi "filename" and
+the end marked with .ei "filename"
+
+@item
+If the xcoff stab is a N_FUN (C_FUN) then follow the string field with
+,. instead of just ,
+
+@item
+The symbol descriptor for register parameters is P for a.out and R for
+xcoff.
+@end itemize
+
+
+(I think that's it for .s file differences. They could stand to be
+better presented. This is just a list of what I have noticed so far.
+There are a *lot* of differences in the information in the symbol
+tables of the executable and object files.)
+
+Table E: mapping a.out stab types to xcoff storage classes
+
+@example
+stab type storage class
+-------------------------------
+N_GSYM C_GSYM
+N_FNAME unknown
+N_FUN C_FUN
+N_STSYM C_STSYM
+N_LCSYM C_STSYM
+N_MAIN unkown
+N_PC unknown
+N_RSYM C_RSYM
+N_RPSYM (0x8e) C_RPSYM
+N_M2C unknown
+N_SLINE unknown
+N_DSLINE unknown
+N_BSLINE unknown
+N_BROWSE unchanged
+N_CATCH unknown
+N_SSYM unknown
+N_SO unknown
+N_LSYM C_LSYM
+N_DECL (0x8c) C_DECL
+N_BINCL unknown
+N_SOL unknown
+N_PSYM C_PSYM
+N_EINCL unknown
+N_ENTRY C_ENTRY
+N_LBRAC unknown
+N_EXCL unknown
+N_SCOPE unknown
+N_RBRAC unknown
+N_BCOMM C_BCOMM
+N_ECOMM C_ECOMM
+N_ECOML C_ECOML
+
+N_LENG unknown
+@end example
+
+@node Sun-differences, , xcoff-differences, Top
+@appendix Differences between GNU stabs and Sun native stabs.
+
+@itemize @bullet
+@item
+Gnu C stabs define *all* types, file or procedure scope, as
+N_LSYM. Sun doc talks about using N_GSYM too.
+
+@item
+Gnu C stabs use `ar' as type descriptor when defining arrays vs. just
+`a' in Sun doc.
+
+@item
+Stabs describing block scopes, N_LBRAC and N_RBRAC are supposed to
+contain the nesting level of the block in the desc field, re Sun doc.
+GNU stabs always have 0 in that field.
+
+@item
+Sun C stabs use type number pairs in the format (a,b) where a is a
+number starting with 1 and incremented for each sub-source file in the
+compilation. b is a number starting with 1 and incremented for each
+new type defined in the compilation. Gnu C stabs use the type number
+alone, with no source file number.
+@end itemize
+
+@contents
+@bye