diff options
-rw-r--r-- | gdb/doc/.Sanitize | 1 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/doc/stabs.texinfo | 2727 |
4 files changed, 2736 insertions, 0 deletions
diff --git a/gdb/doc/.Sanitize b/gdb/doc/.Sanitize index b7b68c7..740b632 100644 --- a/gdb/doc/.Sanitize +++ b/gdb/doc/.Sanitize @@ -45,6 +45,7 @@ pretex.m4 psrc.sed refcard.tex sparc.m4 +stabs.texinfo vax.m4 Do-last: diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 7da38f2..ed6459e 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +Sat Aug 15 20:52:24 1992 Per Bothner (bothner@rtl.cygnus.com) + + * stabs.texinfo: Stabs documentation, written by Julia Menapace. + First pass at converting it to texinfo. + Sat Aug 15 03:14:59 1992 John Gilmore (gnu@cygnus.com) * gdb.texinfo, refcard.tex: Document mult args on `info reg'. diff --git a/gdb/doc/Makefile.in b/gdb/doc/Makefile.in index ba97376..0f4bdd8 100644 --- a/gdb/doc/Makefile.in +++ b/gdb/doc/Makefile.in @@ -294,6 +294,9 @@ gdb-internals: gdbint.info gdbint.info: gdbint.texinfo $(MAKEINFO) -o gdbint.info $(srcdir)/gdbint.texinfo +stabs.info: stabs.texinfo + $(MAKEINFO) -o stabs.info $(srcdir)/stabs.texinfo + force: Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag) diff --git a/gdb/doc/stabs.texinfo b/gdb/doc/stabs.texinfo new file mode 100644 index 0000000..c71f7bb --- /dev/null +++ b/gdb/doc/stabs.texinfo @@ -0,0 +1,2727 @@ +\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 |