mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-29 15:00:34 +00:00
ded6bcab5c
NF_LDOUBLE means. (Stab Types): Include Solaris stab types. (Procedures): Document Solaris extensions.
3915 lines
127 KiB
Plaintext
3915 lines
127 KiB
Plaintext
\input texinfo
|
|
@setfilename stabs.info
|
|
|
|
@ifinfo
|
|
@format
|
|
START-INFO-DIR-ENTRY
|
|
* Stabs:: The "stabs" debugging information format.
|
|
END-INFO-DIR-ENTRY
|
|
@end format
|
|
@end ifinfo
|
|
|
|
@ifinfo
|
|
This document describes the stabs debugging symbol tables.
|
|
|
|
Copyright 1992 Free Software Foundation, Inc.
|
|
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 odd
|
|
@settitle STABS
|
|
@titlepage
|
|
@title The ``stabs'' debug format
|
|
@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{} 1992 Free Software Foundation, Inc.
|
|
Contributed by Cygnus Support.
|
|
|
|
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
|
|
|
|
@ifinfo
|
|
@node Top
|
|
@top The "stabs" representation of debugging information
|
|
|
|
This document describes the GNU stabs debugging format in a.out files.
|
|
|
|
@menu
|
|
* Overview:: Overview of stabs
|
|
* Program structure:: Encoding of the structure of the program
|
|
* Constants:: Constants
|
|
* Example:: A comprehensive example in C
|
|
* Variables::
|
|
* Types:: Type definitions
|
|
* Symbol Tables:: Symbol information in symbol tables
|
|
* Cplusplus::
|
|
|
|
Appendixes:
|
|
* Example2.c:: Source code for extended example
|
|
* Example2.s:: Assembly code for extended example
|
|
* Stab Types:: Symbol types in a.out files
|
|
* Symbol Descriptors:: Table of Symbol Descriptors
|
|
* Type Descriptors:: Table of Symbol Descriptors
|
|
* Expanded reference:: Reference information 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
|
|
@end ifinfo
|
|
|
|
|
|
@node Overview
|
|
@chapter Overview of stabs
|
|
|
|
@dfn{Stabs} refers to a format for information that describes a program
|
|
to a debugger. This format was apparently invented by
|
|
@c FIXME! <<name of inventor>> at
|
|
the University of California at Berkeley, for the @code{pdx} Pascal
|
|
debugger; the format has spread widely since then.
|
|
|
|
This document is one of the few published sources of documentation on
|
|
stabs. It is believed to be completely comprehensive for stabs used by
|
|
C. The lists of symbol descriptors (@pxref{Symbol Descriptors}) and
|
|
type descriptors (@pxref{Type Descriptors}) are believed to be completely
|
|
comprehensive. There are known to be stabs for C++ and COBOL which are
|
|
poorly documented here. Stabs specific to other languages (e.g. Pascal,
|
|
Modula-2) are probably not as well documented as they should be.
|
|
|
|
Other sources of information on stabs are @cite{dbx and dbxtool
|
|
interfaces}, 2nd edition, by Sun, circa 1988, and @cite{AIX Version 3.2
|
|
Files Reference}, Fourth Edition, September 1992, "dbx Stabstring
|
|
Grammar" in the a.out section, page 2-31. This document is believed to
|
|
incorporate the information from those two sources except where it
|
|
explictly directs you to them for more information.
|
|
|
|
@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
|
|
@section Overview of debugging information flow
|
|
|
|
The GNU C compiler compiles C source in a @file{.c} file into assembly
|
|
language in a @file{.s} file, which is translated by the assembler into
|
|
a @file{.o} file, and then linked with other @file{.o} files and
|
|
libraries to produce an executable file.
|
|
|
|
With the @samp{-g} option, GCC puts additional debugging information in
|
|
the @file{.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 assembler directives known collectively 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
|
|
@file{.o} file it is building. The linker consolidates the @file{.o}
|
|
files into one executable file, with one symbol table 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
|
|
@section Overview of stab format
|
|
|
|
There are three overall formats for stab assembler directives
|
|
differentiated by the first word of the stab. The name of the directive
|
|
describes what combination of four possible data fields will follow. It
|
|
is either @code{.stabs} (string), @code{.stabn} (number), or
|
|
@code{.stabd} (dot). IBM's xcoff uses @code{.stabx} (and some other
|
|
directives such as @code{.file} and @code{.bi}) instead of
|
|
@code{.stabs}, @code{.stabn} or @code{.stabd}.
|
|
|
|
The overall format of each class of stab is:
|
|
|
|
@example
|
|
.stabs "@var{string}",@var{type},0,@var{desc},@var{value}
|
|
.stabx "@var{string}",@var{value},@var{type},@var{sdb-type}
|
|
.stabn @var{type},0,@var{desc},@var{value}
|
|
.stabd @var{type},0,@var{desc}
|
|
@end example
|
|
|
|
@c what is the correct term for "current file location"? My AIX
|
|
@c assembler manual calls it "the value of the current location counter".
|
|
For @code{.stabn} and @code{.stabd}, there is no string (the
|
|
@code{n_strx} field is zero, @pxref{Symbol Tables}). For @code{.stabd}
|
|
the value field is implicit and has the value of the current file
|
|
location. The @var{sdb-type} field to @code{.stabx} is unused for stabs
|
|
and can always be set to 0.
|
|
|
|
The number in the type field gives some basic information about what
|
|
type of stab this is (or whether it @emph{is} a stab, as opposed to an
|
|
ordinary symbol). Each possible type number defines a different stab
|
|
type. The stab type further defines the exact interpretation of, and
|
|
possible values for, any remaining @code{"@var{string}"}, @var{desc}, or
|
|
@var{value} fields present in the stab. @xref{Stab Types}, for a list
|
|
in numeric order of the possible type field values for stab directives.
|
|
|
|
For @code{.stabs} the @code{"@var{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 @code{"@var{string}"} field is:
|
|
|
|
@example
|
|
"@var{name}:@var{symbol-descriptor} @var{type-information}"
|
|
@end example
|
|
|
|
@var{name} is the name of the symbol represented by the stab.
|
|
@var{name} can be omitted, which means the stab represents an unnamed
|
|
object. For example, @samp{:t10=*2} defines type 10 as a pointer to
|
|
type 2, but does not give the type a name. Omitting the @var{name}
|
|
field is supported by AIX dbx and GDB after about version 4.8, but not
|
|
other debuggers. GCC sometimes uses a single space as the name instead
|
|
of omitting the name altogether; apparently that is supported by most
|
|
debuggers.
|
|
|
|
The @var{symbol_descriptor} following the @samp{:} is an alphabetic
|
|
character that tells more specifically what kind of symbol the stab
|
|
represents. If the @var{symbol_descriptor} is omitted, but type
|
|
information follows, then the stab represents a local variable. For a
|
|
list of symbol descriptors, see @ref{Symbol Descriptors,,Table C: Symbol
|
|
descriptors}.
|
|
|
|
The @samp{c} symbol descriptor is an exception in that it is not
|
|
followed by type information. @xref{Constants}.
|
|
|
|
Type information is either a @var{type_number}, or a
|
|
@samp{@var{type_number}=}. The @var{type_number} alone is a type
|
|
reference, referring directly to a type that has already been defined.
|
|
|
|
The @samp{@var{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 @samp{=} and nested definitions.
|
|
|
|
In a type definition, if the character that follows the equals sign is
|
|
non-numeric then it is a @var{type_descriptor}, and tells what kind of
|
|
type is about to be defined. Any other values following the
|
|
@var{type_descriptor} vary, depending on the @var{type_descriptor}. If
|
|
a number follows the @samp{=} then the number is a @var{type_reference}.
|
|
This is described more thoroughly in the section on types. @xref{Type
|
|
Descriptors,,Table D: Type Descriptors}, for a list of
|
|
@var{type_descriptor} values.
|
|
|
|
There is an AIX extension for type attributes. Following the @samp{=}
|
|
is any number of type attributes. Each one starts with @samp{@@} and
|
|
ends with @samp{;}. Debuggers, including AIX's dbx, skip any type
|
|
attributes they do not recognize. GDB 4.9 does not do this---it will
|
|
ignore the entire symbol containing a type attribute. Hopefully this
|
|
will be fixed in the next GDB release. Because of a conflict with C++
|
|
(@pxref{Cplusplus}), new attributes should not be defined which begin
|
|
with a digit, @samp{(}, or @samp{-}; GDB may be unable to distinguish
|
|
those from the C++ type descriptor @samp{@@}. The attributes are:
|
|
|
|
@table @code
|
|
@item a@var{boundary}
|
|
@var{boundary} is an integer specifying the alignment. I assume it
|
|
applies to all variables of this type.
|
|
|
|
@item s@var{size}
|
|
Size in bits of a variable of this type.
|
|
|
|
@item p@var{integer}
|
|
Pointer class (for checking). Not sure what this means, or how
|
|
@var{integer} is interpreted.
|
|
|
|
@item P
|
|
Indicate this is a packed type, meaning that structure fields or array
|
|
elements are placed more closely in memory, to save memory at the
|
|
expense of speed.
|
|
@end table
|
|
|
|
All this can make the @code{"@var{string}"} field quite long. All
|
|
versions of GDB, and some versions of DBX, can handle arbitrarily long
|
|
strings. But many versions of DBX cretinously limit the strings to
|
|
about 80 characters, so compilers which must work with such DBX's need
|
|
to split the @code{.stabs} directive into several @code{.stabs}
|
|
directives. Each stab duplicates exactly all but the
|
|
@code{"@var{string}"} field. The @code{"@var{string}"} field of
|
|
every stab except the last is marked as continued with a
|
|
double-backslash at the end. Removing the backslashes and concatenating
|
|
the @code{"@var{string}"} fields of each stab produces the original,
|
|
long string.
|
|
|
|
@node C example
|
|
@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 @samp{-g}, the program above yields the following
|
|
@file{.s} file. Line numbers have been added to make it easier to refer
|
|
to parts of the @file{.s} file in the description of the stabs that
|
|
follows.
|
|
|
|
@node Assembly code
|
|
@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
|
|
@chapter Encoding for the structure of the program
|
|
|
|
@menu
|
|
* Source Files:: The path and name of the source file
|
|
* Line Numbers::
|
|
* Procedures::
|
|
* Block Structure::
|
|
@end menu
|
|
|
|
@node Source Files
|
|
@section The path and name of the source files
|
|
|
|
Before any other stabs occur, there must be a stab specifying the source
|
|
file. This information is contained in a symbol of stab type
|
|
@code{N_SO}; the string contains the name of the file. The value of the
|
|
symbol is the start address of portion of the text section corresponding
|
|
to that file.
|
|
|
|
With the Sun Solaris2 compiler, the @code{desc} field contains a
|
|
source-language code.
|
|
|
|
Some compilers (for example, gcc2 and SunOS4 @file{/bin/cc}) also
|
|
include the directory in which the source was compiled, in a second
|
|
@code{N_SO} symbol preceding the one containing the file name. This
|
|
symbol can be distinguished by the fact that it ends in a slash. Code
|
|
from the cfront C++ compiler can have additional @code{N_SO} symbols for
|
|
nonexistent source files after the @code{N_SO} for the real source file;
|
|
these are believed to contain no useful information.
|
|
|
|
For example:
|
|
|
|
@example
|
|
.stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0 ; 100 is N_SO
|
|
.stabs "hello.c",100,0,0,Ltext0
|
|
.text
|
|
Ltext0:
|
|
@end example
|
|
|
|
Instead of @code{N_SO} symbols, XCOFF uses a @code{.file} assembler
|
|
directive which assembles to a standard COFF @code{.file} symbol;
|
|
explaining this in detail is outside the scope of this document.
|
|
|
|
There are several different schemes for dealing with include files: the
|
|
traditional @code{N_SOL} approach, Sun's @code{N_BINCL} scheme, and the
|
|
XCOFF @code{C_BINCL} (which despite the similar name has little in
|
|
common with @code{N_BINCL}).
|
|
|
|
An @code{N_SOL} symbol specifies which include file subsequent symbols
|
|
refer to. The string field is the name of the file and the value is the
|
|
text address corresponding to the start of the previous include file and
|
|
the start of this one. To specify the main source file again, use an
|
|
@code{N_SOL} symbol with the name of the main source file.
|
|
|
|
A @code{N_BINCL} symbol specifies the start of an include file. In an
|
|
object file, only the name is significant. The Sun linker puts data
|
|
into some of the other fields. The end of the include file is marked by
|
|
a @code{N_EINCL} symbol (which has no name field). In an ojbect file,
|
|
there is no significant data in the @code{N_EINCL} symbol; the Sun
|
|
linker puts data into some of the fields. @code{N_BINCL} and
|
|
@code{N_EINCL} can be nested. If the linker detects that two source
|
|
files have identical stabs with a @code{N_BINCL} and @code{N_EINCL} pair
|
|
(as will generally be the case for a header file), then it only puts out
|
|
the stabs once. Each additional occurance is replaced by an
|
|
@code{N_EXCL} symbol. I believe the Sun (SunOS4, not sure about
|
|
Solaris) linker is the only one which supports this feature.
|
|
|
|
For the start of an include file in XCOFF, use the @file{.bi} assembler
|
|
directive which generates a @code{C_BINCL} symbol. A @file{.ei}
|
|
directive, which generates a @code{C_EINCL} symbol, denotes the end of
|
|
the include file. Both directives are followed by the name of the
|
|
source file in quotes, which becomes the string for the symbol. The
|
|
value of each symbol, produced automatically by the assembler and
|
|
linker, is an offset into the executable which points to the beginning
|
|
(inclusive, as you'd expect) and end (inclusive, as you would not
|
|
expect) of the portion of the COFF linetable which corresponds to this
|
|
include file. @code{C_BINCL} and @code{C_EINCL} do not nest.
|
|
|
|
@node Line Numbers
|
|
@section Line Numbers
|
|
|
|
A @code{N_SLINE} symbol represents the start of a source line. The
|
|
@var{desc} field contains the line number and the @var{value} field
|
|
contains the code address for the start of that source line.
|
|
|
|
GNU documents @code{N_DSLINE} and @code{N_BSLINE} symbols for line
|
|
numbers in the data or bss segments, respectively. They are identical
|
|
to @code{N_SLINE} but are relocated differently by the linker. They
|
|
were intended to be used to describe the source location of a variable
|
|
declaration, but I believe that gcc2 actually puts the line number in
|
|
the desc field of the stab for the variable itself. GDB has been
|
|
ignoring these symbols (unless they contain a string field) at least
|
|
since GDB 3.5.
|
|
|
|
XCOFF uses COFF line numbers instead, which are outside the scope of
|
|
this document, ammeliorated by adequate marking of include files
|
|
(@pxref{Source Files}).
|
|
|
|
For single source lines that generate discontiguous code, such as flow
|
|
of control statements, there may be more than one line number entry for
|
|
the same source line. In this case there is a line number entry at the
|
|
start of each code range, each with the same line number.
|
|
|
|
@node Procedures
|
|
@section Procedures
|
|
|
|
All of the following stabs use the @samp{N_FUN} symbol type.
|
|
|
|
A function is represented by a @samp{F} symbol descriptor for a global
|
|
(extern) function, and @samp{f} for a static (local) function. The next
|
|
@samp{N_SLINE} symbol can be used to find the line number of the start
|
|
of the function. The value field is the address of the start of the
|
|
function. The type information of the stab represents the return type
|
|
of the function; thus @samp{foo:f5} means that foo is a function
|
|
returning type 5.
|
|
|
|
The type information of the stab is optionally followed by type
|
|
information for each argument, with each argument preceded by @samp{;}.
|
|
An argument type of 0 means that additional arguments are being passed,
|
|
whose types and number may vary (@samp{...} in ANSI C). This extension
|
|
is used by Sun's Solaris compiler. GDB has tolerated it (i.e. at least
|
|
parsed the syntax, if not necessarily used the information) at least
|
|
since version 4.8; I don't know whether all versions of dbx will
|
|
tolerate it. The argument types given here are not merely redundant
|
|
with the symbols for the arguments themselves (@pxref{Parameters}), they
|
|
are the types of the arguments as they are passed, before any
|
|
conversions might take place. For example, if a C function which is
|
|
declared without a prototype takes a @code{float} argument, the value is
|
|
passed as a @code{double} but then converted to a @code{float}.
|
|
Debuggers need to use the types given in the arguments when printing
|
|
values, but if calling the function they need to use the types given in
|
|
the symbol defining the function.
|
|
|
|
If the return type and types of arguments of a function which is defined
|
|
in another source file are specified (i.e. a function prototype in ANSI
|
|
C), traditionally compilers emit no stab; the only way for the debugger
|
|
to find the information is if the source file where the function is
|
|
defined was also compiled with debugging symbols. As an extension the
|
|
Solaris compiler uses symbol descriptor @samp{P} followed by the return
|
|
type of the function, followed by the arguments, each preceded by
|
|
@samp{;}, as in a stab with symbol descriptor @samp{f} or @samp{F}.
|
|
This use of symbol descriptor @samp{P} can be distinguished from its use
|
|
for register parameters (@pxref{Parameters}) by the fact that it has
|
|
symbol type @code{N_FUN}.
|
|
|
|
The AIX documentation also defines symbol descriptor @samp{J} as an
|
|
internal function. I assume this means a function nested within another
|
|
function. It also says Symbol descriptor @samp{m} is a module in
|
|
Modula-2 or extended Pascal.
|
|
|
|
Procedures (functions which do not return values) are represented as
|
|
functions returning the void type in C. I don't see why this couldn't
|
|
be used for all languages (inventing a void type for this purpose if
|
|
necessary), but the AIX documentation defines @samp{I}, @samp{P}, and
|
|
@samp{Q} for internal, global, and static procedures, respectively.
|
|
These symbol descriptors are unusual in that they are not followed by
|
|
type information.
|
|
|
|
For any of the above symbol descriptors, after the symbol descriptor and
|
|
the type information, there is optionally a comma, followed by the name
|
|
of the procedure, followed by a comma, followed by a name specifying the
|
|
scope. The first name is local to the scope specified. I assume then
|
|
that the name of the symbol (before the @samp{:}), if specified, is some
|
|
sort of global name. I assume the name specifying the scope is the name
|
|
of a function specifying that scope. This feature is an AIX extension,
|
|
and this information is based on the manual; I haven't actually tried
|
|
it.
|
|
|
|
The stab representing a procedure is located immediately following the
|
|
code of the procedure. This 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
|
|
|
|
The @code{.stabs} entry after this code fragment shows the @var{name} of
|
|
the procedure (@code{main}); the type descriptor @var{desc} (@code{F},
|
|
for a global procedure); a reference to the predefined type @code{int}
|
|
for the return type; and the starting @var{address} of the procedure.
|
|
|
|
Here is an exploded summary (with whitespace introduced for clarity),
|
|
followed by line 50 of our sample assembly output, which has this form:
|
|
|
|
@example
|
|
.stabs "@var{name}:
|
|
@var{desc} @r{(global proc @samp{F})}
|
|
@var{return_type_ref} @r{(int)}
|
|
",N_FUN, NIL, NIL,
|
|
@var{address}
|
|
@end example
|
|
|
|
@example
|
|
50 .stabs "main:F1",36,0,0,_main
|
|
@end example
|
|
|
|
@node Block Structure
|
|
@section Block Structure
|
|
|
|
@table @strong
|
|
@item Directive:
|
|
@code{.stabn}
|
|
@item Types:
|
|
@code{N_LBRAC}, @code{N_RBRAC}
|
|
@end table
|
|
|
|
The program's block structure is represented by the @code{N_LBRAC} (left
|
|
brace) and the @code{N_RBRAC} (right brace) stab types. The following code
|
|
range, which is the body of @code{main}, is labeled with @samp{LBB2:} at the
|
|
beginning and @samp{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 @code{N_LBRAC} and @code{N_RBRAC} stabs that describe the block
|
|
scope of the procedure are located after the @code{N_FUNC} stab that
|
|
represents the procedure itself. The @code{N_LBRAC} uses the
|
|
@code{LBB2} label as the code address in its value field, and the
|
|
@code{N_RBRAC} uses @code{LBE2}.
|
|
|
|
@example
|
|
50 .stabs "main:F1",36,0,0,_main
|
|
@end example
|
|
|
|
@example
|
|
.stabn N_LBRAC, NIL, NIL, @var{left-brace-address}
|
|
.stabn N_RBRAC, NIL, NIL, @var{right-brace-address}
|
|
@end example
|
|
|
|
@example
|
|
51 .stabn 192,0,0,LBB2
|
|
52 .stabn 224,0,0,LBE2
|
|
@end example
|
|
|
|
@node Constants
|
|
@chapter Constants
|
|
|
|
The @samp{c} symbol descriptor indicates that this stab represents a
|
|
constant. This symbol descriptor is an exception to the general rule
|
|
that symbol descriptors are followed by type information. Instead, it
|
|
is followed by @samp{=} and one of the following:
|
|
|
|
@table @code
|
|
@item b @var{value}
|
|
Boolean constant. @var{value} is a numeric value; I assume it is 0 for
|
|
false or 1 for true.
|
|
|
|
@item c @var{value}
|
|
Character constant. @var{value} is the numeric value of the constant.
|
|
|
|
@item e @var{type-information} , @var{value}
|
|
Constant whose value can be represented as integral.
|
|
@var{type-information} is the type of the constant, as it would appear
|
|
after a symbol descriptor (@pxref{Stabs Format}). @var{value} is the
|
|
numeric value of the constant. GDB 4.9 does not actually get the right
|
|
value if @var{value} does not fit in a host @code{int}, but it does not
|
|
do anything violent, and future debuggers could be extended to accept
|
|
integers of any size (whether unsigned or not). This constant type is
|
|
usually documented as being only for enumeration constants, but GDB has
|
|
never imposed that restriction; I don't know about other debuggers.
|
|
|
|
@item i @var{value}
|
|
Integer constant. @var{value} is the numeric value. The type is some
|
|
sort of generic integer type (for GDB, a host @code{int}); to specify
|
|
the type explicitly, use @samp{e} instead.
|
|
|
|
@item r @var{value}
|
|
Real constant. @var{value} is the real value, which can be @samp{INF}
|
|
(optionally preceded by a sign) for infinity, @samp{QNAN} for a quiet
|
|
NaN (not-a-number), or @samp{SNAN} for a signalling NaN. If it is a
|
|
normal number the format is that accepted by the C library function
|
|
@code{atof}.
|
|
|
|
@item s @var{string}
|
|
String constant. @var{string} is a string enclosed in either @samp{'}
|
|
(in which case @samp{'} characters within the string are represented as
|
|
@samp{\'} or @samp{"} (in which case @samp{"} characters within the
|
|
string are represented as @samp{\"}).
|
|
|
|
@item S @var{type-information} , @var{elements} , @var{bits} , @var{pattern}
|
|
Set constant. @var{type-information} is the type of the constant, as it
|
|
would appear after a symbol descriptor (@pxref{Stabs Format}).
|
|
@var{elements} is the number of elements in the set (Does this means
|
|
how many bits of @var{pattern} are actually used, which would be
|
|
redundant with the type, or perhaps the number of bits set in
|
|
@var{pattern}? I don't get it), @var{bits} is the number of bits in the
|
|
constant (meaning it specifies the length of @var{pattern}, I think),
|
|
and @var{pattern} is a hexadecimal representation of the set. AIX
|
|
documentation refers to a limit of 32 bytes, but I see no reason why
|
|
this limit should exist. This form could probably be used for arbitrary
|
|
constants, not just sets; the only catch is that @var{pattern} should be
|
|
understood to be target, not host, byte order and format.
|
|
@end table
|
|
|
|
The boolean, character, string, and set constants are not supported by
|
|
GDB 4.9, but it will ignore them. GDB 4.8 and earlier gave an error
|
|
message and refused to read symbols from the file containing the
|
|
constants.
|
|
|
|
This information is followed by @samp{;}.
|
|
|
|
@node Example
|
|
@chapter A Comprehensive Example in C
|
|
|
|
Now we'll examine a second program, @code{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 @file{.c} source,
|
|
and @pxref{Example2.s} for the @file{.s} assembly code.
|
|
This description includes parts of those files.
|
|
|
|
@section Flow of control and nested scopes
|
|
|
|
@table @strong
|
|
@item Directive:
|
|
@code{.stabn}
|
|
@item Types:
|
|
@code{N_SLINE}, @code{N_LBRAC}, @code{N_RBRAC} (cont.)
|
|
@end table
|
|
|
|
Consider the body of @code{main}, from @file{example2.c}. It shows more
|
|
about how @code{N_SLINE}, @code{N_RBRAC}, and @code{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 @samp{for} line, that generates
|
|
non-linear flow of control, and non-contiguous code. In this case, an
|
|
@code{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 @code{N_LBRAC} and
|
|
@code{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.
|
|
|
|
@noindent
|
|
This is the label for the @code{N_LBRAC} (left brace) stab marking the
|
|
start of @code{main}.
|
|
|
|
@example
|
|
57 LBB2:
|
|
@end example
|
|
|
|
@noindent
|
|
In the first code range for C source line 23, the @code{for} loop
|
|
initialize and test, @code{N_SLINE} (68) records the line number:
|
|
|
|
@example
|
|
.stabn N_SLINE, NIL,
|
|
@var{line},
|
|
@var{address}
|
|
|
|
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
|
|
|
|
@exdent label for the @code{N_LBRAC} (start block) marking the start of @code{for} loop
|
|
|
|
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:
|
|
|
|
@exdent label for the @code{N_RBRAC} (end block) stab marking the end of the @code{for} loop
|
|
|
|
77 LBE3:
|
|
@end example
|
|
|
|
@noindent
|
|
Now we come to the second code range for source line 23, the @code{for}
|
|
loop increment and return. Once again, @code{N_SLINE} (68) records the
|
|
source line number:
|
|
|
|
@example
|
|
.stabn, N_SLINE, NIL,
|
|
@var{line},
|
|
@var{address}
|
|
|
|
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:
|
|
|
|
@exdent label for the @code{N_RBRAC} (end block) stab marking the end of the @code{for} loop
|
|
|
|
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
|
|
@end example
|
|
|
|
@noindent
|
|
Here is an illustration of stabs describing nested scopes. The scope
|
|
nesting is reflected in the nested bracketing stabs (@code{N_LBRAC},
|
|
192, appears here).
|
|
|
|
@example
|
|
.stabn N_LBRAC,NIL,NIL,
|
|
@var{block-start-address}
|
|
|
|
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
|
|
@end example
|
|
|
|
@noindent
|
|
@code{N_RBRAC} (224), ``right brace'' ends a lexical block (scope).
|
|
|
|
@example
|
|
.stabn N_RBRAC,NIL,NIL,
|
|
@var{block-end-address}
|
|
|
|
102 .stabn 224,0,0,LBE3 ## end for label
|
|
103 .stabn 224,0,0,LBE2 ## end proc label
|
|
@end example
|
|
|
|
@node Variables
|
|
@chapter Variables
|
|
|
|
@menu
|
|
* Automatic variables:: locally scoped
|
|
* Global Variables::
|
|
* Register variables::
|
|
* Initialized statics::
|
|
* Un-initialized statics::
|
|
* Parameters::
|
|
@end menu
|
|
|
|
@node Automatic variables
|
|
@section Locally scoped automatic variables
|
|
|
|
@table @strong
|
|
@item Directive:
|
|
@code{.stabs}
|
|
@item Type:
|
|
@code{N_LSYM}
|
|
@item Symbol Descriptor:
|
|
none
|
|
@end table
|
|
|
|
In addition to describing types, the @code{N_LSYM} stab type also
|
|
describes locally scoped automatic variables. Refer again to the body
|
|
of @code{main} in @file{example2.c}. It allocates two automatic
|
|
variables: @samp{times} is scoped to the body of @code{main}, and
|
|
@samp{inner} is scoped to the body of the @code{for} loop.
|
|
@samp{s_flap} is locally scoped but 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 @code{N_LSYM} stab for an automatic variable is located just before the
|
|
@code{N_LBRAC} stab describing the open brace of the block to which it is
|
|
scoped.
|
|
|
|
@example
|
|
@exdent @code{N_LSYM} (128): automatic variable, scoped locally to @code{main}
|
|
|
|
.stabs "@var{name}:
|
|
@var{type information}",
|
|
N_LSYM, NIL, NIL,
|
|
@var{frame-pointer-offset}
|
|
|
|
98 .stabs "times:1",128,0,0,-20
|
|
99 .stabn 192,0,0,LBB2 ## begin `main' N_LBRAC
|
|
|
|
@exdent @code{N_LSYM} (128): automatic variable, scoped locally to the @code{for} loop
|
|
|
|
.stabs "@var{name}:
|
|
@var{type information}",
|
|
N_LSYM, NIL, NIL,
|
|
@var{frame-pointer-offset}
|
|
|
|
100 .stabs "inner:1",128,0,0,-24
|
|
101 .stabn 192,0,0,LBB3 ## begin `for' loop N_LBRAC
|
|
@end example
|
|
|
|
The symbol descriptor is omitted for automatic variables. Since type
|
|
information should being with a digit, @samp{-}, or @samp{(}, only
|
|
digits, @samp{-}, and @samp{(} are precluded from being used for symbol
|
|
descriptors by this fact. However, the Acorn RISC machine (ARM) is said
|
|
to get this wrong: it puts out a mere type definition here, without the
|
|
preceding @code{@var{typenumber}=}. This is a bad idea; there is no
|
|
guarantee that type descriptors are distinct from symbol descriptors.
|
|
|
|
@node Global Variables
|
|
@section Global Variables
|
|
|
|
@table @strong
|
|
@item Directive:
|
|
@code{.stabs}
|
|
@item Type:
|
|
@code{N_GSYM}
|
|
@item Symbol Descriptor:
|
|
@code{G}
|
|
@end table
|
|
|
|
Global variables are represented by the @code{N_GSYM} stab type. The symbol
|
|
descriptor, following the colon in the string field, is @samp{G}. Following
|
|
the @samp{G} is a type reference or type definition. In this example it is a
|
|
type reference to the basic C type, @code{char}. The first source line in
|
|
@file{example2.c},
|
|
|
|
@example
|
|
1 char g_foo = 'c';
|
|
@end example
|
|
|
|
@noindent
|
|
yields the following stab. The stab immediately precedes the code that
|
|
allocates storage for the variable it describes.
|
|
|
|
@example
|
|
@exdent @code{N_GSYM} (32): global symbol
|
|
|
|
.stabs "@var{name}:
|
|
@var{descriptor}
|
|
@var{type-ref}",
|
|
N_GSYM, NIL, NIL, NIL
|
|
|
|
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 @code{N_GSYM} is not contained
|
|
in the @code{N_GSYM} stab. The debugger gets this information from the
|
|
external symbol for the global variable.
|
|
|
|
@node Register variables
|
|
@section Register variables
|
|
|
|
@c According to an old version of this manual, AIX uses C_RPSYM instead
|
|
@c of C_RSYM. I am skeptical; this should be verified.
|
|
Register variables have their own stab type, @code{N_RSYM}, and their
|
|
own symbol descriptor, @code{r}. The stab's value field contains the
|
|
number of the register where the variable data will be stored.
|
|
|
|
The value is the register number.
|
|
|
|
AIX defines a separate symbol descriptor @samp{d} for floating point
|
|
registers. This seems incredibly stupid---why not just just give
|
|
floating point registers different register numbers? I have not
|
|
verified whether the compiler actually uses @samp{d}.
|
|
|
|
If the register is explicitly allocated to a global variable, but not
|
|
initialized, as in
|
|
|
|
@example
|
|
register int g_bar asm ("%g5");
|
|
@end example
|
|
|
|
the stab may be emitted at the end of the object file, with
|
|
the other bss symbols.
|
|
|
|
@node Initialized statics
|
|
@section Initialized static variables
|
|
|
|
@table @strong
|
|
@item Directive:
|
|
@code{.stabs}
|
|
@item Type:
|
|
@code{N_STSYM}
|
|
@item Symbol Descriptors:
|
|
@code{S} (file scope), @code{V} (procedure scope)
|
|
@end table
|
|
|
|
Initialized static variables are represented by the @code{N_STSYM} stab
|
|
type. The symbol descriptor part of the string field shows if the
|
|
variable is file scope static (@samp{S}) or procedure scope static
|
|
(@samp{V}). The source line
|
|
|
|
@example
|
|
3 static int s_g_repeat = 2;
|
|
@end example
|
|
|
|
@noindent
|
|
yields the following code. The stab is located immediately preceding
|
|
the storage for the variable it represents. Since the variable in
|
|
this example is file scope static the symbol descriptor is @samp{S}.
|
|
|
|
@example
|
|
@exdent @code{N_STSYM} (38): initialized static variable (data seg w/internal linkage)
|
|
|
|
.stabs "@var{name}:
|
|
@var{descriptor}
|
|
@var{type-ref}",
|
|
N_STSYM,NIL,NIL,
|
|
@var{address}
|
|
|
|
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
|
|
@section Un-initialized static variables
|
|
|
|
@table @strong
|
|
@item Directive:
|
|
@code{.stabs}
|
|
@item Type:
|
|
@code{N_LCSYM}
|
|
@item Symbol Descriptors:
|
|
@code{S} (file scope), @code{V} (procedure scope)
|
|
@end table
|
|
|
|
Un-initialized static variables are represented by the @code{N_LCSYM}
|
|
stab type. The symbol descriptor part of the string shows if the
|
|
variable is file scope static (@samp{S}) or procedure scope static
|
|
(@samp{V}). In this example it is procedure scope static. The source
|
|
line allocating @code{s_flap} immediately follows the open brace for the
|
|
procedure @code{main}.
|
|
|
|
@example
|
|
20 @{
|
|
21 static float s_flap;
|
|
@end example
|
|
|
|
The code that reserves storage for the variable @code{s_flap} precedes the
|
|
body of body of @code{main}.
|
|
|
|
@example
|
|
39 .reserve _s_flap.0,4,"bss",4
|
|
@end example
|
|
|
|
But since @code{s_flap} is scoped locally to @code{main}, its stab is
|
|
located with the other stabs representing symbols local to @code{main}.
|
|
The stab for @code{s_flap} is located just before the @code{N_LBRAC} for
|
|
@code{main}.
|
|
|
|
@example
|
|
@exdent @code{N_LCSYM} (40): uninitialized static var (BSS seg w/internal linkage)
|
|
|
|
.stabs "@var{name}:
|
|
@var{descriptor}
|
|
@var{type-ref}",
|
|
N_LCSYM, NIL, NIL,
|
|
@var{address}
|
|
|
|
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
|
|
|
|
@c ............................................................
|
|
|
|
@node Parameters
|
|
@section Parameters
|
|
|
|
The symbol descriptor @samp{p} is used to refer to parameters which are
|
|
in the arglist. Symbols have symbol type @samp{N_PSYM}. The value of
|
|
the symbol is the offset relative to the argument list.
|
|
|
|
If the parameter is passed in a register, then the traditional way to do
|
|
this is to provide two symbols for each argument:
|
|
|
|
@example
|
|
.stabs "arg:p1" . . . ; N_PSYM
|
|
.stabs "arg:r1" . . . ; N_RSYM
|
|
@end example
|
|
|
|
Debuggers are expected to use the second one to find the value, and the
|
|
first one to know that it is an argument.
|
|
|
|
Because this is kind of ugly, some compilers use symbol descriptor
|
|
@samp{P} or @samp{R} to indicate an argument which is in a register.
|
|
The symbol value is the register number. @samp{P} and @samp{R} mean the
|
|
same thing, the difference is that @samp{P} is a GNU invention and
|
|
@samp{R} is an IBM (xcoff) invention. As of version 4.9, GDB should
|
|
handle either one. Symbol type @samp{C_RPSYM} is used with @samp{R} and
|
|
@samp{N_RSYM} is used with @samp{P}.
|
|
|
|
AIX, according to the documentation, uses @samp{D} for a parameter
|
|
passed in a floating point register. This strikes me as incredibly
|
|
bogus---why doesn't it just use @samp{R} with a register number which
|
|
indicates that it's a floating point register? I haven't verified
|
|
whether the system actually does what the documentation indicates.
|
|
|
|
There is at least one case where GCC uses a @samp{p}/@samp{r} pair
|
|
rather than @samp{P}; this is where the argument is passed in the
|
|
argument list and then loaded into a register.
|
|
|
|
On the sparc and hppa, for a @samp{P} symbol whose type is a structure
|
|
or union, the register contains the address of the structure. On the
|
|
sparc, this is also true of a @samp{p}/@samp{r} pair (using Sun cc) or a
|
|
@samp{p} symbol. However, if a (small) structure is really in a
|
|
register, @samp{r} is used. And, to top it all off, on the hppa it
|
|
might be a structure which was passed on the stack and loaded into a
|
|
register and for which there is a @samp{p}/@samp{r} pair! I believe
|
|
that symbol descriptor @samp{i} is supposed to deal with this case, (it
|
|
is said to mean "value parameter by reference, indirect access", I don't
|
|
know the source for this information) but I don't know details or what
|
|
compilers or debuggers use it, if any (not GDB or GCC). It is not clear
|
|
to me whether this case needs to be dealt with differently than
|
|
parameters passed by reference (see below).
|
|
|
|
There is another case similar to an argument in a register, which is an
|
|
argument which is actually stored as a local variable. Sometimes this
|
|
happens when the argument was passed in a register and then the compiler
|
|
stores it as a local variable. If possible, the compiler should claim
|
|
that it's in a register, but this isn't always done. Some compilers use
|
|
the pair of symbols approach described above ("arg:p" followed by
|
|
"arg:"); this includes gcc1 (not gcc2) on the sparc when passing a small
|
|
structure and gcc2 (sometimes) when the argument type is float and it is
|
|
passed as a double and converted to float by the prologue (in the latter
|
|
case the type of the "arg:p" symbol is double and the type of the "arg:"
|
|
symbol is float). GCC, at least on the 960, uses a single @samp{p}
|
|
symbol descriptor for an argument which is stored as a local variable
|
|
but uses @samp{N_LSYM} instead of @samp{N_PSYM}. In this case the value
|
|
of the symbol is an offset relative to the local variables for that
|
|
function, not relative to the arguments (on some machines those are the
|
|
same thing, but not on all).
|
|
|
|
If the parameter is passed by reference (e.g. Pascal VAR parameters),
|
|
then type symbol descriptor is @samp{v} if it is in the argument list,
|
|
or @samp{a} if it in a register. Other than the fact that these contain
|
|
the address of the parameter other than the parameter itself, they are
|
|
identical to @samp{p} and @samp{R}, respectively. I believe @samp{a} is
|
|
an AIX invention; @samp{v} is supported by all stabs-using systems as
|
|
far as I know.
|
|
|
|
@c Is this paragraph correct? It is based on piecing together patchy
|
|
@c information and some guesswork
|
|
Conformant arrays refer to a feature of Modula-2, and perhaps other
|
|
languages, in which the size of an array parameter is not known to the
|
|
called function until run-time. Such parameters have two stabs, a
|
|
@samp{x} for the array itself, and a @samp{C}, which represents the size
|
|
of the array. The value of the @samp{x} stab is the offset in the
|
|
argument list where the address of the array is stored (it this right?
|
|
it is a guess); the value of the @samp{C} stab is the offset in the
|
|
argument list where the size of the array (in elements? in bytes?) is
|
|
stored.
|
|
|
|
The following are also said to go with @samp{N_PSYM}:
|
|
|
|
@example
|
|
"name" -> "param_name:#type"
|
|
-> pP (<<??>>)
|
|
-> pF FORTRAN function parameter
|
|
-> X (function result variable)
|
|
-> b (based variable)
|
|
|
|
value -> offset from the argument pointer (positive).
|
|
@end example
|
|
|
|
As a simple example, the code
|
|
|
|
@example
|
|
main (argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
@{
|
|
@end example
|
|
|
|
produces the stabs
|
|
|
|
@example
|
|
.stabs "main:F1",36,0,0,_main ; 36 is N_FUN
|
|
.stabs "argc:p1",160,0,0,68 ; 160 is N_PSYM
|
|
.stabs "argv:p20=*21=*2",160,0,0,72
|
|
@end example
|
|
|
|
The type definition of argv is interesting because it contains several
|
|
type definitions. Type 21 is pointer to type 2 (char) and argv (type 20) is
|
|
pointer to type 21.
|
|
|
|
@node Types
|
|
@chapter Type Definitions
|
|
|
|
Now let's 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
|
|
* Builtin types:: Integers, floating point, void, etc.
|
|
* Miscellaneous Types:: Pointers, sets, files, etc.
|
|
* Cross-references:: Referring to a type not yet defined.
|
|
* Subranges:: A type with a specific range.
|
|
* Arrays:: An aggregate type of same-typed elements.
|
|
* Strings:: Like an array but also has a length.
|
|
* Enumerations:: Like an integer but the values have names.
|
|
* Structures:: An aggregate type of different-typed elements.
|
|
* Typedefs:: Giving a type a name.
|
|
* Unions:: Different types sharing storage.
|
|
* Function Types::
|
|
@end menu
|
|
|
|
@node Builtin types
|
|
@section Builtin types
|
|
|
|
Certain types are built in (@code{int}, @code{short}, @code{void},
|
|
@code{float}, etc.); the debugger recognizes these types and knows how
|
|
to handle them. Thus don't be surprised if some of the following ways
|
|
of specifying builtin types do not specify everything that a debugger
|
|
would need to know about the type---in some cases they merely specify
|
|
enough information to distinguish the type from other types.
|
|
|
|
The traditional way to define builtin types is convolunted, so new ways
|
|
have been invented to describe them. Sun's ACC uses the @samp{b} and
|
|
@samp{R} type descriptors, and IBM uses negative type numbers. GDB can
|
|
accept all three, as of version 4.8; dbx just accepts the traditional
|
|
builtin types and perhaps one of the other two formats.
|
|
|
|
@menu
|
|
* Traditional Builtin Types:: Put on your seatbelts and prepare for kludgery
|
|
* Builtin Type Descriptors:: Builtin types with special type descriptors
|
|
* Negative Type Numbers:: Builtin types using negative type numbers
|
|
@end menu
|
|
|
|
@node Traditional Builtin Types
|
|
@subsection Traditional Builtin types
|
|
|
|
Often types are defined as subranges of themselves. If the array bounds
|
|
can fit within an @code{int}, then they are given normally. For example:
|
|
|
|
@example
|
|
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0 ; 128 is N_LSYM
|
|
.stabs "char:t2=r2;0;127;",128,0,0,0
|
|
@end example
|
|
|
|
Builtin types can also be described as subranges of @code{int}:
|
|
|
|
@example
|
|
.stabs "unsigned short:t6=r1;0;65535;",128,0,0,0
|
|
@end example
|
|
|
|
If the lower bound of a subrange is 0 and the upper bound is -1, it
|
|
means that the type is an unsigned integral type whose bounds are too
|
|
big to describe in an int. Traditionally this is only used for
|
|
@code{unsigned int} and @code{unsigned long}; GCC also sometimes uses it
|
|
for @code{long long} and @code{unsigned long long}, and the only way to
|
|
tell those types apart is to look at their names. On other machines GCC
|
|
puts out bounds in octal, with a leading 0. In this case a negative
|
|
bound consists of a number which is a 1 bit followed by a bunch of 0
|
|
bits, and a positive bound is one in which a bunch of bits are 1.
|
|
|
|
@example
|
|
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
|
|
.stabs "long long int:t7=r1;0;-1;",128,0,0,0
|
|
@end example
|
|
|
|
If the lower bound of a subrange is 0 and the upper bound is negative,
|
|
it means that it is an unsigned integral type whose size in bytes is the
|
|
absolute value of the upper bound. I believe this is a Convex
|
|
convention for @code{unsigned long long}.
|
|
|
|
If the lower bound of a subrange is negative and the upper bound is 0,
|
|
it means that the type is a signed integral type whose size in bytes is
|
|
the absolute value of the lower bound. I believe this is a Convex
|
|
convention for @code{long long}. To distinguish this from a legitimate
|
|
subrange, the type should be a subrange of itself. I'm not sure whether
|
|
this is the case for Convex.
|
|
|
|
If the upper bound of a subrange is 0, it means that this is a floating
|
|
point type, and the lower bound of the subrange indicates the number of
|
|
bytes in the type:
|
|
|
|
@example
|
|
.stabs "float:t12=r1;4;0;",128,0,0,0
|
|
.stabs "double:t13=r1;8;0;",128,0,0,0
|
|
@end example
|
|
|
|
However, GCC writes @code{long double} the same way it writes
|
|
@code{double}; the only way to distinguish them is by the name:
|
|
|
|
@example
|
|
.stabs "long double:t14=r1;8;0;",128,0,0,0
|
|
@end example
|
|
|
|
Complex types are defined the same way as floating-point types; the only
|
|
way to distinguish a single-precision complex from a double-precision
|
|
floating-point type is by the name.
|
|
|
|
The C @code{void} type is defined as itself:
|
|
|
|
@example
|
|
.stabs "void:t15=15",128,0,0,0
|
|
@end example
|
|
|
|
I'm not sure how a boolean type is represented.
|
|
|
|
@node Builtin Type Descriptors
|
|
@subsection Defining Builtin Types using Builtin Type Descriptors
|
|
|
|
There are various type descriptors to define builtin types:
|
|
|
|
@table @code
|
|
@c FIXME: clean up description of width and offset, once we figure out
|
|
@c what they mean
|
|
@item b @var{signed} @var{char-flag} @var{width} ; @var{offset} ; @var{nbits} ;
|
|
Define an integral type. @var{signed} is @samp{u} for unsigned or
|
|
@samp{s} for signed. @var{char-flag} is @samp{c} which indicates this
|
|
is a character type, or is omitted. I assume this is to distinguish an
|
|
integral type from a character type of the same size, for example it
|
|
might make sense to set it for the C type @code{wchar_t} so the debugger
|
|
can print such variables differently (Solaris does not do this). Sun
|
|
sets it on the C types @code{signed char} and @code{unsigned char} which
|
|
arguably is wrong. @var{width} and @var{offset} appear to be for small
|
|
objects stored in larger ones, for example a @code{short} in an
|
|
@code{int} register. @var{width} is normally the number of bytes in the
|
|
type. @var{offset} seems to always be zero. @var{nbits} is the number
|
|
of bits in the type.
|
|
|
|
Note that type descriptor @samp{b} used for builtin types conflicts with
|
|
its use for Pascal space types (@pxref{Miscellaneous Types}); they can
|
|
be distinguished because the character following the type descriptor
|
|
will be a digit, @samp{(}, or @samp{-} for a Pascal space type, or
|
|
@samp{u} or @samp{s} for a builtin type.
|
|
|
|
@item w
|
|
Documented by AIX to define a wide character type, but their compiler
|
|
actually uses negative type numbers (@pxref{Negative Type Numbers}).
|
|
|
|
@item R @var{fp_type} ; @var{bytes} ;
|
|
Define a floating point type. @var{fp_type} has one of the following values:
|
|
|
|
@table @code
|
|
@item 1 (NF_SINGLE)
|
|
IEEE 32-bit (single precision) floating point format.
|
|
|
|
@item 2 (NF_DOUBLE)
|
|
IEEE 64-bit (double precision) floating point format.
|
|
|
|
@item 3 (NF_COMPLEX)
|
|
@item 4 (NF_COMPLEX16)
|
|
@item 5 (NF_COMPLEX32)
|
|
@c "GDB source" really means @file{include/aout/stab_gnu.h}, but trying
|
|
@c to put that here got an overfull hbox.
|
|
These are for complex numbers. A comment in the GDB source describes
|
|
them as Fortran complex, double complex, and complex*16, respectively,
|
|
but what does that mean? (i.e. Single precision? Double precison?).
|
|
|
|
@item 6 (NF_LDOUBLE)
|
|
Long double. This should probably only be used for Sun format long
|
|
double, and new codes should be used for other floating point formats
|
|
(NF_DOUBLE can be used if a long double is really just an IEEE double,
|
|
of course).
|
|
@end table
|
|
|
|
@var{bytes} is the number of bytes occupied by the type. This allows a
|
|
debugger to perform some operations with the type even if it doesn't
|
|
understand @var{fp_code}.
|
|
|
|
@item g @var{type-information} ; @var{nbits}
|
|
Documented by AIX to define a floating type, but their compiler actually
|
|
uses negative type numbers (@pxref{Negative Type Numbers}).
|
|
|
|
@item c @var{type-information} ; @var{nbits}
|
|
Documented by AIX to define a complex type, but their compiler actually
|
|
uses negative type numbers (@pxref{Negative Type Numbers}).
|
|
@end table
|
|
|
|
The C @code{void} type is defined as a signed integral type 0 bits long:
|
|
@example
|
|
.stabs "void:t19=bs0;0;0",128,0,0,0
|
|
@end example
|
|
The Solaris compiler seems to omit the trailing semicolon in this case.
|
|
Getting sloppy in this way is not a swift move because if a type is
|
|
embedded in a more complex expression it is necessary to be able to tell
|
|
where it ends.
|
|
|
|
I'm not sure how a boolean type is represented.
|
|
|
|
@node Negative Type Numbers
|
|
@subsection Negative Type numbers
|
|
|
|
Since the debugger knows about the builtin types anyway, the idea of
|
|
negative type numbers is simply to give a special type number which
|
|
indicates the built in type. There is no stab defining these types.
|
|
|
|
I'm not sure whether anyone has tried to define what this means if
|
|
@code{int} can be other than 32 bits (or other types can be other than
|
|
their customary size). If @code{int} has exactly one size for each
|
|
architecture, then it can be handled easily enough, but if the size of
|
|
@code{int} can vary according the compiler options, then it gets hairy.
|
|
I guess the consistent way to do this would be to define separate
|
|
negative type numbers for 16-bit @code{int} and 32-bit @code{int};
|
|
therefore I have indicated below the customary size (and other format
|
|
information) for each type. The information below is currently correct
|
|
because AIX on the RS6000 is the only system which uses these type
|
|
numbers. If these type numbers start to get used on other systems, I
|
|
suspect the correct thing to do is to define a new number in cases where
|
|
a type does not have the size and format indicated below.
|
|
|
|
Also note that part of the definition of the negative type number is
|
|
the name of the type. Types with identical size and format but
|
|
different names have different negative type numbers.
|
|
|
|
@table @code
|
|
@item -1
|
|
@code{int}, 32 bit signed integral type.
|
|
|
|
@item -2
|
|
@code{char}, 8 bit type holding a character. Both GDB and dbx on AIX
|
|
treat this as signed. GCC uses this type whether @code{char} is signed
|
|
or not, which seems like a bad idea. The AIX compiler (xlc) seems to
|
|
avoid this type; it uses -5 instead for @code{char}.
|
|
|
|
@item -3
|
|
@code{short}, 16 bit signed integral type.
|
|
|
|
@item -4
|
|
@code{long}, 32 bit signed integral type.
|
|
|
|
@item -5
|
|
@code{unsigned char}, 8 bit unsigned integral type.
|
|
|
|
@item -6
|
|
@code{signed char}, 8 bit signed integral type.
|
|
|
|
@item -7
|
|
@code{unsigned short}, 16 bit unsigned integral type.
|
|
|
|
@item -8
|
|
@code{unsigned int}, 32 bit unsigned integral type.
|
|
|
|
@item -9
|
|
@code{unsigned}, 32 bit unsigned integral type.
|
|
|
|
@item -10
|
|
@code{unsigned long}, 32 bit unsigned integral type.
|
|
|
|
@item -11
|
|
@code{void}, type indicating the lack of a value.
|
|
|
|
@item -12
|
|
@code{float}, IEEE single precision.
|
|
|
|
@item -13
|
|
@code{double}, IEEE double precision.
|
|
|
|
@item -14
|
|
@code{long double}, IEEE double precision. The compiler claims the size
|
|
will increase in a future release, and for binary compatibility you have
|
|
to avoid using @code{long double}. I hope when they increase it they
|
|
use a new negative type number.
|
|
|
|
@item -15
|
|
@code{integer}. 32 bit signed integral type.
|
|
|
|
@item -16
|
|
@code{boolean}. Only one bit is used, not sure about the actual size of the
|
|
type.
|
|
|
|
@item -17
|
|
@code{short real}. IEEE single precision.
|
|
|
|
@item -18
|
|
@code{real}. IEEE double precision.
|
|
|
|
@item -19
|
|
@code{stringptr}. @xref{Strings}.
|
|
|
|
@item -20
|
|
@code{character}, 8 bit unsigned type.
|
|
|
|
@item -21
|
|
@code{logical*1}, 8 bit unsigned integral type.
|
|
|
|
@item -22
|
|
@code{logical*2}, 16 bit unsigned integral type.
|
|
|
|
@item -23
|
|
@code{logical*4}, 32 bit unsigned integral type.
|
|
|
|
@item -24
|
|
@code{logical}, 32 bit unsigned integral type.
|
|
|
|
@item -25
|
|
@code{complex}. A complex type consisting of two IEEE single-precision
|
|
floating point values.
|
|
|
|
@item -26
|
|
@code{complex}. A complex type consisting of two IEEE double-precision
|
|
floating point values.
|
|
|
|
@item -27
|
|
@code{integer*1}, 8 bit signed integral type.
|
|
|
|
@item -28
|
|
@code{integer*2}, 16 bit signed integral type.
|
|
|
|
@item -29
|
|
@code{integer*4}, 32 bit signed integral type.
|
|
|
|
@item -30
|
|
@code{wchar}. Wide character, 16 bits wide (Unicode format?). This is
|
|
not used for the C type @code{wchar_t}.
|
|
@end table
|
|
|
|
@node Miscellaneous Types
|
|
@section Miscellaneous Types
|
|
|
|
@table @code
|
|
@item b @var{type-information} ; @var{bytes}
|
|
Pascal space type. This is documented by IBM; what does it mean?
|
|
|
|
Note that this use of the @samp{b} type descriptor can be distinguished
|
|
from its use for builtin integral types (@pxref{Builtin Type
|
|
Descriptors}) because the character following the type descriptor is
|
|
always a digit, @samp{(}, or @samp{-}.
|
|
|
|
@item B @var{type-information}
|
|
A volatile-qualified version of @var{type-information}. This is a Sun
|
|
extension. A volatile-qualified type means that references and stores
|
|
to a variable of that type must not be optimized or cached; they must
|
|
occur as the user specifies them.
|
|
|
|
@item d @var{type-information}
|
|
File of type @var{type-information}. As far as I know this is only used
|
|
by Pascal.
|
|
|
|
@item k @var{type-information}
|
|
A const-qualified version of @var{type-information}. This is a Sun
|
|
extension. A const-qualified type means that a variable of this type
|
|
cannot be modified.
|
|
|
|
@item M @var{type-information} ; @var{length}
|
|
Multiple instance type. The type seems to composed of @var{length}
|
|
repetitions of @var{type-information}, for example @code{character*3} is
|
|
represented by @samp{M-2;3}, where @samp{-2} is a reference to a
|
|
character type (@pxref{Negative Type Numbers}). I'm not sure how this
|
|
differs from an array. This appears to be a FORTRAN feature.
|
|
@var{length} is a bound, like those in range types, @xref{Subranges}.
|
|
|
|
@item S @var{type-information}
|
|
Pascal set type. @var{type-information} must be a small type such as an
|
|
enumeration or a subrange, and the type is a bitmask whose length is
|
|
specified by the number of elements in @var{type-information}.
|
|
|
|
@item * @var{type-information}
|
|
Pointer to @var{type-information}.
|
|
@end table
|
|
|
|
@node Cross-references
|
|
@section Cross-references to other types
|
|
|
|
If a type is used before it is defined, one common way to deal with this
|
|
is just to use a type reference to a type which has not yet been
|
|
defined. The debugger is expected to be able to deal with this.
|
|
|
|
Another way is with the @samp{x} type descriptor, which is followed by
|
|
@samp{s} for a structure tag, @samp{u} for a union tag, or @samp{e} for
|
|
a enumerator tag, followed by the name of the tag, followed by @samp{:}.
|
|
for example the following C declarations:
|
|
|
|
@example
|
|
struct foo;
|
|
struct foo *bar;
|
|
@end example
|
|
|
|
produce
|
|
|
|
@example
|
|
.stabs "bar:G16=*17=xsfoo:",32,0,0,0
|
|
@end example
|
|
|
|
Not all debuggers support the @samp{x} type descriptor, so on some
|
|
machines GCC does not use it. I believe that for the above example it
|
|
would just emit a reference to type 17 and never define it, but I
|
|
haven't verified that.
|
|
|
|
Modula-2 imported types, at least on AIX, use the @samp{i} type
|
|
descriptor, which is followed by the name of the module from which the
|
|
type is imported, followed by @samp{:}, followed by the name of the
|
|
type. There is then optionally a comma followed by type information for
|
|
the type (This differs from merely naming the type (@pxref{Typedefs}) in
|
|
that it identifies the module; I don't understand whether the name of
|
|
the type given here is always just the same as the name we are giving
|
|
it, or whether this type descriptor is used with a nameless stab
|
|
(@pxref{Stabs Format}), or what). The symbol ends with @samp{;}.
|
|
|
|
@node Subranges
|
|
@section Subrange types
|
|
|
|
The @samp{r} type descriptor defines a type as a subrange of another
|
|
type. It is followed by type information for the type which it is a
|
|
subrange of, a semicolon, an integral lower bound, a semicolon, an
|
|
integral upper bound, and a semicolon. The AIX documentation does not
|
|
specify the trailing semicolon, in an effort to specify array indexes
|
|
more cleanly, but a subrange which is not an array index has always
|
|
included a trailing semicolon (@pxref{Arrays}).
|
|
|
|
Instead of an integer, either bound can be one of the following:
|
|
|
|
@table @code
|
|
@item A @var{offset}
|
|
The bound is passed by reference on the stack at offset @var{offset}
|
|
from the argument list. @xref{Parameters}, for more information on such
|
|
offsets.
|
|
|
|
@item T @var{offset}
|
|
The bound is passed by value on the stack at offset @var{offset} from
|
|
the argument list.
|
|
|
|
@item a @var{register-number}
|
|
The bound is pased by reference in register number
|
|
@var{register-number}.
|
|
|
|
@item t @var{register-number}
|
|
The bound is passed by value in register number @var{register-number}.
|
|
|
|
@item J
|
|
There is no bound.
|
|
@end table
|
|
|
|
Subranges are also used for builtin types, @xref{Traditional Builtin Types}.
|
|
|
|
@node Arrays
|
|
@section Array types
|
|
|
|
Arrays use the @samp{a} type descriptor. Following the type descriptor
|
|
is the type of the index and the type of the array elements. If the
|
|
index type is a range type, it will end in a semicolon; if it is not a
|
|
range type (for example, if it is a type reference), there does not
|
|
appear to be any way to tell where the types are separated. In an
|
|
effort to clean up this mess, IBM documents the two types as being
|
|
separated by a semicolon, and a range type as not ending in a semicolon
|
|
(but this is not right for range types which are not array indexes,
|
|
@pxref{Subranges}). I think probably the best solution is to specify
|
|
that a semicolon ends a range type, and that the index type and element
|
|
type of an array are separated by a semicolon, but that if the index
|
|
type is a range type, the extra semicolon can be omitted. GDB (at least
|
|
through version 4.9) doesn't support any kind of index type other than a
|
|
range anyway; I'm not sure about dbx.
|
|
|
|
It is well established, and widely used, that the type of the index,
|
|
unlike most types found in the stabs, is merely a type definition, not
|
|
type information (@pxref{Stabs Format}) (that is, it need not start with
|
|
@var{type-number}@code{=} if it is defining a new type). According to a
|
|
comment in GDB, this is also true of the type of the array elements; it
|
|
gives @samp{ar1;1;10;ar1;1;10;4} as a legitimate way to express a two
|
|
dimensional array. According to AIX documentation, the element type
|
|
must be type information. GDB accepts either.
|
|
|
|
The type of the index is often a range type, expressed as the letter r
|
|
and some parameters. It defines the size of the array. In the example
|
|
below, the range @code{r1;0;2;} defines an index type which is a
|
|
subrange of type 1 (integer), with a lower bound of 0 and an upper bound
|
|
of 2. This defines the valid range of subscripts of a three-element C
|
|
array.
|
|
|
|
For example, the definition
|
|
|
|
@example
|
|
char char_vec[3] = @{'a','b','c'@};
|
|
@end example
|
|
|
|
@noindent
|
|
produces the output
|
|
|
|
@example
|
|
.stabs "char_vec:G19=ar1;0;2;2",32,0,0,0
|
|
.global _char_vec
|
|
.align 4
|
|
_char_vec:
|
|
.byte 97
|
|
.byte 98
|
|
.byte 99
|
|
@end example
|
|
|
|
If an array is @dfn{packed}, it means that the elements are spaced more
|
|
closely than normal, saving memory at the expense of speed. For
|
|
example, an array of 3-byte objects might, if unpacked, have each
|
|
element aligned on a 4-byte boundary, but if packed, have no padding.
|
|
One way to specify that something is packed is with type attributes
|
|
(@pxref{Stabs Format}), in the case of arrays another is to use the
|
|
@samp{P} type descriptor instead of @samp{a}. Other than specifying a
|
|
packed array, @samp{P} is identical to @samp{a}.
|
|
|
|
@c FIXME-what is it? A pointer?
|
|
An open array is represented by the @samp{A} type descriptor followed by
|
|
type information specifying the type of the array elements.
|
|
|
|
@c FIXME: what is the format of this type? A pointer to a vector of pointers?
|
|
An N-dimensional dynamic array is represented by
|
|
|
|
@example
|
|
D @var{dimensions} ; @var{type-information}
|
|
@end example
|
|
|
|
@c Does dimensions really have this meaning? The AIX documentation
|
|
@c doesn't say.
|
|
@var{dimensions} is the number of dimensions; @var{type-information}
|
|
specifies the type of the array elements.
|
|
|
|
@c FIXME: what is the format of this type? A pointer to some offsets in
|
|
@c another array?
|
|
A subarray of an N-dimensional array is represented by
|
|
|
|
@example
|
|
E @var{dimensions} ; @var{type-information}
|
|
@end example
|
|
|
|
@c Does dimensions really have this meaning? The AIX documentation
|
|
@c doesn't say.
|
|
@var{dimensions} is the number of dimensions; @var{type-information}
|
|
specifies the type of the array elements.
|
|
|
|
@node Strings
|
|
@section Strings
|
|
|
|
Some languages, like C or the original Pascal, do not have string types,
|
|
they just have related things like arrays of characters. But most
|
|
Pascals and various other languages have string types, which are
|
|
indicated as follows:
|
|
|
|
@table @code
|
|
@item n @var{type-information} ; @var{bytes}
|
|
@var{bytes} is the maximum length. I'm not sure what
|
|
@var{type-information} is; I suspect that it means that this is a string
|
|
of @var{type-information} (thus allowing a string of integers, a string
|
|
of wide characters, etc., as well as a string of characters). Not sure
|
|
what the format of this type is. This is an AIX feature.
|
|
|
|
@item z @var{type-information} ; @var{bytes}
|
|
Just like @samp{n} except that this is a gstring, not an ordinary
|
|
string. I don't know the difference.
|
|
|
|
@item N
|
|
Pascal Stringptr. What is this? This is an AIX feature.
|
|
@end table
|
|
|
|
@node Enumerations
|
|
@section Enumerations
|
|
|
|
Enumerations are defined with the @samp{e} type descriptor.
|
|
|
|
@c FIXME: Where does this information properly go? Perhaps it is
|
|
@c redundant with something we already explain.
|
|
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.
|
|
The type definition 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. Therefore it does not
|
|
describe a block local symbol, but a file local one.
|
|
|
|
The source line:
|
|
|
|
@example
|
|
enum e_places @{first,second=3,last@};
|
|
@end example
|
|
|
|
@noindent
|
|
generates the following stab
|
|
|
|
@example
|
|
.stabs "e_places:T22=efirst:0,second:3,last:4,;",128,0,0,0
|
|
@end example
|
|
|
|
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 ;.
|
|
|
|
There is no standard way to specify the size of an enumeration type; it
|
|
is determined by the architecture (normally all enumerations types are
|
|
32 bits). There should be a way to specify an enumeration type of
|
|
another size; type attributes would be one way to do this @xref{Stabs
|
|
Format}.
|
|
|
|
@node Structures
|
|
@section Structures
|
|
|
|
@table @strong
|
|
@item Directive:
|
|
@code{.stabs}
|
|
@item Type:
|
|
@code{N_LSYM} or @code{C_DECL}
|
|
@item Symbol Descriptor:
|
|
@code{T}
|
|
@item Type Descriptor:
|
|
@code{s}
|
|
@end table
|
|
|
|
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.
|
|
|
|
|
|
@example
|
|
<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(array)
|
|
index_type(range of int from 0 to 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
|
|
@end example
|
|
|
|
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
|
|
@section Giving a type a name
|
|
|
|
To give a type a name, use the @samp{t} symbol descriptor. For example,
|
|
|
|
@example
|
|
.stabs "s_typedef:t16",128,0,0,0
|
|
@end example
|
|
|
|
specifies that @code{s_typedef} refers to type number 16. Such stabs
|
|
have symbol type @code{N_LSYM} or @code{C_DECL}.
|
|
|
|
If instead, you are specifying the tag name for a structure, union, or
|
|
enumeration, use the @samp{T} symbol descriptor instead. I believe C is
|
|
the only language with this feature.
|
|
|
|
If the type is an opaque type (I believe this is a Modula-2 feature),
|
|
AIX provides a type descriptor to specify it. The type descriptor is
|
|
@samp{o} and is followed by a name. I don't know what the name
|
|
means---is it always the same as the name of the type, or is this type
|
|
descriptor used with a nameless stab (@pxref{Stabs Format})? There
|
|
optionally follows a comma followed by type information which defines
|
|
the type of this type. If omitted, a semicolon is used in place of the
|
|
comma and the type information, and, the type is much like a generic
|
|
pointer type---it has a known size but little else about it is
|
|
specified.
|
|
|
|
@node Unions
|
|
@section Unions
|
|
|
|
Next let's 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 immediately preceding the N_LBRAC for the procedure's block
|
|
start.
|
|
|
|
The stab for the union tag, however is located preceding 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.
|
|
|
|
@display
|
|
<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
|
|
@end display
|
|
|
|
@smallexample
|
|
105 .stabs "u_tag:T23=u4u_int:1,0,32;u_float:12,0,32;u_char:21,0,32;;",
|
|
128,0,0,0
|
|
@end smallexample
|
|
|
|
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.
|
|
|
|
@display
|
|
<128> N_LSYM - local variable (with no symbol descriptor)
|
|
.stabs "name:type_ref(u_tag)", N_LSYM, NIL, NIL, frame_ptr_offset
|
|
@end display
|
|
|
|
@example
|
|
130 .stabs "an_u:23",128,0,0,-20
|
|
@end example
|
|
|
|
@node Function Types
|
|
@section Function types
|
|
|
|
There are various types for function variables. These types are not
|
|
used in defining functions; see symbol descriptor @samp{f}; they are
|
|
used for things like pointers to functions.
|
|
|
|
The simple, traditional, type is type descriptor @samp{f} is followed by
|
|
type information for the return type of the function, followed by a
|
|
semicolon.
|
|
|
|
This does not deal with functions the number and type of whose
|
|
parameters are part of their type, as found in Modula-2 or ANSI C. AIX
|
|
provides extensions to specify these, using the @samp{f}, @samp{F},
|
|
@samp{p}, and @samp{R} type descriptors.
|
|
|
|
First comes the type descriptor. Then, if it is @samp{f} or @samp{F},
|
|
this is a function, and the type information for the return type of the
|
|
function follows, followed by a comma. Then comes the number of
|
|
parameters to the function and a semicolon. Then, for each parameter,
|
|
there is the name of the parameter followed by a colon (this is only
|
|
present for type descriptors @samp{R} and @samp{F} which represent
|
|
Pascal function or procedure parameters), type information for the
|
|
parameter, a comma, @samp{0} if passed by reference or @samp{1} if
|
|
passed by value, and a semicolon. The type definition ends with a
|
|
semicolon.
|
|
|
|
For example,
|
|
|
|
@example
|
|
int (*g_pf)();
|
|
@end example
|
|
|
|
@noindent
|
|
generates the following code:
|
|
|
|
@example
|
|
.stabs "g_pf:G24=*25=f1",32,0,0,0
|
|
.common _g_pf,4,"bss"
|
|
@end example
|
|
|
|
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
|
|
@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:
|
|
|
|
@example
|
|
3 static int s_g_repeat
|
|
@end example
|
|
|
|
@noindent
|
|
The following stab describes the symbol.
|
|
|
|
@example
|
|
26 .stabs "s_g_repeat:S1",38,0,0,_s_g_repeat
|
|
@end example
|
|
|
|
@noindent
|
|
The assembler transforms the stab into this symbol table entry in the
|
|
@file{.o} file. The location is expressed as a data segment offset.
|
|
|
|
@example
|
|
21 00000084 - 00 0000 STSYM s_g_repeat:S1
|
|
@end example
|
|
|
|
@noindent
|
|
in the symbol table entry from the executable, the linker has made the
|
|
relocatable address absolute.
|
|
|
|
@example
|
|
22 0000e00c - 00 0000 STSYM s_g_repeat:S1
|
|
@end example
|
|
|
|
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:
|
|
|
|
@example
|
|
1 char g_foo = 'c';
|
|
@end example
|
|
|
|
@noindent
|
|
generates the stab:
|
|
|
|
@example
|
|
21 .stabs "g_foo:G2",32,0,0,0
|
|
@end example
|
|
|
|
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.
|
|
|
|
@example
|
|
19 00000000 - 00 0000 GSYM g_foo:G2
|
|
20 00000080 D _g_foo
|
|
@end example
|
|
|
|
@noindent
|
|
These entries as transformed by the linker. The linker symbol table
|
|
entry now holds an absolute address.
|
|
|
|
@example
|
|
21 00000000 - 00 0000 GSYM g_foo:G2
|
|
@dots{}
|
|
215 0000e008 D _g_foo
|
|
@end example
|
|
|
|
@node Cplusplus
|
|
@chapter GNU C++ stabs
|
|
|
|
@menu
|
|
* Basic Cplusplus 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 type descriptors added for C++ descriptions
|
|
|
|
@table @code
|
|
@item #
|
|
method type (two ## if minimal debug)
|
|
|
|
@item @@
|
|
Member (class and variable) type. It is followed by type information
|
|
for the offset basetype, a comma, and type information for the type of
|
|
the field being pointed to. (FIXME: this is acknowledged to be
|
|
gibberish. Can anyone say what really goes here?).
|
|
|
|
Note that there is a conflict between this and type attributes
|
|
(@pxref{Stabs Format}); both use type descriptor @samp{@@}.
|
|
Fortunately, the @samp{@@} type descriptor used in this C++ sense always
|
|
will be followed by a digit, @samp{(}, or @samp{-}, and type attributes
|
|
never start with those things.
|
|
@end table
|
|
|
|
@node Basic Cplusplus types
|
|
@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.
|
|
|
|
@display
|
|
.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
|
|
@end display
|
|
|
|
@smallexample
|
|
.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
|
|
@end smallexample
|
|
|
|
@display
|
|
.stabs "name:sym_dec(struct tag)type_ref($vtbl_ptr_type)",N_LSYM,NIL,NIL,NIL
|
|
@end display
|
|
|
|
@example
|
|
.stabs "$vtbl_ptr_type:T17",128,0,0,0
|
|
@end example
|
|
|
|
@node Simple classes
|
|
@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 name ends with a period, and any characters except
|
|
the period can occur in the XXXX string.
|
|
|
|
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.
|
|
|
|
|
|
@display
|
|
.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
|
|
@end display
|
|
|
|
@smallexample
|
|
.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
|
|
@end smallexample
|
|
|
|
@node Class instance
|
|
@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
|
|
|
|
@noindent
|
|
yields the following stab describing the class instance. It looks no
|
|
different from a standard C stab describing a local variable.
|
|
|
|
@display
|
|
.stabs "name:type_ref(baseA)", N_LSYM, NIL, NIL, frame_ptr_offset
|
|
@end display
|
|
|
|
@example
|
|
.stabs "AbaseA:20",128,0,0,-20
|
|
@end example
|
|
|
|
@node Methods
|
|
@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? >>
|
|
|
|
@example
|
|
.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
|
|
@end example
|
|
|
|
Here is the stab for the `this' pointer implicit argument. The name
|
|
of the `this' pointer is always `this.' 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.
|
|
|
|
@example
|
|
.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 "this:P19=*20=xsbaseA:",64,0,0,8
|
|
@end example
|
|
|
|
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.
|
|
|
|
@example
|
|
.stabs "name:sym_desc(value parameter)type_ref(int)",
|
|
N_PSYM,NIL,NIL,offset_from_arg_ptr
|
|
|
|
.stabs "in:p1",160,0,0,72
|
|
@end example
|
|
|
|
<< The examples that follow are based on A1.C >>
|
|
|
|
@node Protections
|
|
@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
|
|
|
|
@noindent
|
|
generates the following stab to describe the class type all_data.
|
|
|
|
@display
|
|
.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
|
|
@end display
|
|
|
|
@smallexample
|
|
.stabs "all_data:t19=s12
|
|
priv_dat:/01,0,32;prot_dat:/12,32,8;pub_dat:12,64,32;;",128,0,0,0
|
|
@end smallexample
|
|
|
|
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.
|
|
|
|
@display
|
|
.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
|
|
@end display
|
|
|
|
@smallexample
|
|
.stabs "all_methods:Tt21=s1priv_meth::22=##1;:i;0A.;protMeth::23=##2;:c;1A.;
|
|
pubMeth::24=##12;:f;2A.;;",128,0,0,0
|
|
@end smallexample
|
|
|
|
@node Method Modifiers
|
|
@section 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:
|
|
|
|
@display
|
|
.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)
|
|
virtual(no);;", @dots{}
|
|
@end display
|
|
|
|
@example
|
|
.stabs "A:T20=s1ConstMeth::21=##1;:i;2B.;VolatileMeth::22=##2;:c;2C.;
|
|
ConstVolMeth::23=##12;:f;2D.;;",128,0,0,0
|
|
@end example
|
|
|
|
@node Virtual Methods
|
|
@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
|
|
a range of integers between 0 and 1, and whose elements are 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.
|
|
|
|
@display
|
|
.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(range of int from 0 to 1);
|
|
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
|
|
@end display
|
|
|
|
@c FIXME: bogus line break.
|
|
@example
|
|
.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
|
|
@end example
|
|
|
|
@node Inheritence
|
|
@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.
|
|
|
|
@c FIXME!!! the linebreaks in the following example probably make the
|
|
@c examples literally unusable, but I don't know any other way to get
|
|
@c them on the page.
|
|
@c One solution would be to put some of the type definitions into
|
|
@c separate stabs, even if that's not exactly what the compiler actually
|
|
@c emits.
|
|
@smallexample
|
|
.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
|
|
@end smallexample
|
|
|
|
In the stab describing derived class D below, the information about
|
|
the derivation of this class is encoded as follows.
|
|
|
|
@display
|
|
.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); @dots{}
|
|
@end display
|
|
|
|
@c FIXME! fake linebreaks.
|
|
@smallexample
|
|
.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
|
|
@end smallexample
|
|
|
|
@node Virtual Base Classes
|
|
@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.
|
|
|
|
@c FIXME!! fake linebreaks below
|
|
@smallexample
|
|
.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
|
|
@end smallexample
|
|
|
|
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. The
|
|
`this' pointer for a class is a pointer to the class type.
|
|
|
|
@example
|
|
.stabs "this:P24=*25=xsB:",64,0,0,8
|
|
@end example
|
|
|
|
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
|
|
@section Static Members
|
|
|
|
The data area for a class is a concatenation 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? See Cygnus bug #677 for some info. >>
|
|
|
|
@node Example2.c
|
|
@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
|
|
@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
|
|
@c FIXME! fake linebreak in line 30
|
|
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
|
|
@c FIXME: fake linebreak in line 105
|
|
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 Stab Types
|
|
@appendix Values for the Stab Type Field
|
|
|
|
These are all the possible values for the stab type field, for
|
|
@code{a.out} files. This does not apply to XCOFF.
|
|
|
|
The following types are used by the linker and assembler; there is
|
|
nothing stabs-specific about them. Since this document does not attempt
|
|
to describe aspects of object file format other than the debugging
|
|
format, no details are given.
|
|
|
|
@c Try to get most of these to fit on a single line.
|
|
@iftex
|
|
@tableindent=1.5in
|
|
@end iftex
|
|
|
|
@table @code
|
|
@item 0x0 N_UNDF
|
|
Undefined symbol
|
|
|
|
@item 0x2 N_ABS
|
|
File scope absolute symbol
|
|
|
|
@item 0x3 N_ABS | N_EXT
|
|
External absolute symbol
|
|
|
|
@item 0x4 N_TEXT
|
|
File scope text symbol
|
|
|
|
@item 0x5 N_TEXT | N_EXT
|
|
External text symbol
|
|
|
|
@item 0x6 N_DATA
|
|
File scope data symbol
|
|
|
|
@item 0x7 N_DATA | N_EXT
|
|
External data symbol
|
|
|
|
@item 0x8 N_BSS
|
|
File scope BSS symbol
|
|
|
|
@item 0x9 N_BSS | N_EXT
|
|
External BSS symbol
|
|
|
|
@item 0x0c N_FN_SEQ
|
|
Same as N_FN, for Sequent compilers
|
|
|
|
@item 0x0a N_INDR
|
|
Symbol is indirected to another symbol
|
|
|
|
@item 0x12 N_COMM
|
|
Common sym -- visable after shared lib dynamic link
|
|
|
|
@item 0x14 N_SETA
|
|
Absolute set element
|
|
|
|
@item 0x16 N_SETT
|
|
Text segment set element
|
|
|
|
@item 0x18 N_SETD
|
|
Data segment set element
|
|
|
|
@item 0x1a N_SETB
|
|
BSS segment set element
|
|
|
|
@item 0x1c N_SETV
|
|
Pointer to set vector
|
|
|
|
@item 0x1e N_WARNING
|
|
Print a warning message during linking
|
|
|
|
@item 0x1f N_FN
|
|
File name of a .o file
|
|
@end table
|
|
|
|
The following symbol types indicate that this is a stab. This is the
|
|
full list of stab numbers, including stab types that are used in
|
|
languages other than C.
|
|
|
|
@table @code
|
|
@item 0x20 N_GSYM
|
|
Global symbol, @xref{N_GSYM}.
|
|
|
|
@item 0x22 N_FNAME
|
|
Function name (for BSD Fortran), @xref{N_FNAME}.
|
|
|
|
@item 0x24 N_FUN
|
|
Function name or text segment variable for C, @xref{N_FUN}.
|
|
|
|
@item 0x26 N_STSYM
|
|
Static symbol (data segment variable with internal linkage), @xref{N_STSYM}.
|
|
|
|
@item 0x28 N_LCSYM
|
|
.lcomm symbol (BSS segment variable with internal linkage), @xref{N_LCSYM}.
|
|
|
|
@item 0x2a N_MAIN
|
|
Name of main routine (not used in C), @xref{N_MAIN}.
|
|
|
|
@c FIXME: discuss this in the main body of the text where we talk about
|
|
@c using N_FUN for variables.
|
|
@item 0x2c N_ROSYM
|
|
Read-only data symbol (Solaris2). Most systems use N_FUN for this.
|
|
|
|
@item 0x30 N_PC
|
|
Global symbol (for Pascal), @xref{N_PC}.
|
|
|
|
@item 0x32 N_NSYMS
|
|
Number of symbols (according to Ultrix V4.0), @xref{N_NSYMS}.
|
|
|
|
@item 0x34 N_NOMAP
|
|
No DST map for sym (according to Ultrix V4.0), @xref{N_NOMAP}.
|
|
|
|
@c FIXME: describe this solaris feature in the body of the text (see
|
|
@c comments in include/aout/stab.def).
|
|
@item 0x38 N_OBJ
|
|
Object file (Solaris2).
|
|
|
|
@c See include/aout/stab.def for (a little) more info.
|
|
@item 0x3c N_OPT
|
|
Debugger options (Solaris2).
|
|
|
|
@item 0x40 N_RSYM
|
|
Register variable, @xref{N_RSYM}.
|
|
|
|
@item 0x42 N_M2C
|
|
Modula-2 compilation unit, @xref{N_M2C}.
|
|
|
|
@item 0x44 N_SLINE
|
|
Line number in text segment, @xref{Line Numbers}.
|
|
|
|
@item 0x46 N_DSLINE
|
|
Line number in data segment, @xref{Line Numbers}.
|
|
|
|
@item 0x48 N_BSLINE
|
|
Line number in bss segment, @xref{Line Numbers}.
|
|
|
|
@item 0x48 N_BROWS
|
|
Sun source code browser, path to .cb file, @xref{N_BROWS}.
|
|
|
|
@item 0x4a N_DEFD
|
|
Gnu Modula2 definition module dependency, @xref{N_DEFD}.
|
|
|
|
@item 0x4c N_FLINE
|
|
Function start/body/end line numbers (Solaris2).
|
|
|
|
@item 0x50 N_EHDECL
|
|
Gnu C++ exception variable, @xref{N_EHDECL}.
|
|
|
|
@item 0x50 N_MOD2
|
|
Modula2 info "for imc" (according to Ultrix V4.0), @xref{N_MOD2}.
|
|
|
|
@item 0x54 N_CATCH
|
|
Gnu C++ "catch" clause, @xref{N_CATCH}.
|
|
|
|
@item 0x60 N_SSYM
|
|
Structure of union element, @xref{N_SSYM}.
|
|
|
|
@item 0x62 N_ENDM
|
|
Last stab for module (Solaris2).
|
|
|
|
@item 0x64 N_SO
|
|
Path and name of source file , @xref{Source Files}.
|
|
|
|
@item 0x80 N_LSYM
|
|
Automatic var in the stack or type definition, @xref{N_LSYM}, @xref{Typedefs}.
|
|
|
|
@item 0x82 N_BINCL
|
|
Beginning of an include file (Sun only), @xref{Source Files}.
|
|
|
|
@item 0x84 N_SOL
|
|
Name of sub-source (#include) file., @xref{Source Files}.
|
|
|
|
@item 0xa0 N_PSYM
|
|
Parameter variable, @xref{Parameters}.
|
|
|
|
@item 0xa2 N_EINCL
|
|
End of an include file, @xref{Source Files}.
|
|
|
|
@item 0xa4 N_ENTRY
|
|
Alternate entry point, @xref{N_ENTRY}.
|
|
|
|
@item 0xc0 N_LBRAC
|
|
Beginning of a lexical block, @xref{N_LBRAC}.
|
|
|
|
@item 0xc2 N_EXCL
|
|
Place holder for a deleted include file, @xref{Source Files}.
|
|
|
|
@item 0xc4 N_SCOPE
|
|
Modula2 scope information (Sun linker), @xref{N_SCOPE}.
|
|
|
|
@item 0xe0 N_RBRAC
|
|
End of a lexical block, @xref{N_RBRAC}.
|
|
|
|
@item 0xe2 N_BCOMM
|
|
Begin named common block, @xref{N_BCOMM}.
|
|
|
|
@item 0xe4 N_ECOMM
|
|
End named common block, @xref{N_ECOMM}.
|
|
|
|
@item 0xe8 N_ECOML
|
|
End common (local name), @xref{N_ECOML}.
|
|
|
|
@c FIXME: How does this really work? Move it to main body of document.
|
|
@item 0xea N_WITH
|
|
Pascal @code{with} statement: type,,0,0,offset (Solaris2).
|
|
|
|
@item 0xf0 N_NBTEXT
|
|
Gould non-base registers, @xref{Gould}.
|
|
|
|
@item 0xf2 N_NBDATA
|
|
Gould non-base registers, @xref{Gould}.
|
|
|
|
@item 0xf4 N_NBBSS
|
|
Gould non-base registers, @xref{Gould}.
|
|
|
|
@item 0xf6 N_NBSTS
|
|
Gould non-base registers, @xref{Gould}.
|
|
|
|
@item 0xf8 N_NBLCS
|
|
Gould non-base registers, @xref{Gould}.
|
|
@end table
|
|
|
|
@c Restore the default table indent
|
|
@iftex
|
|
@tableindent=.8in
|
|
@end iftex
|
|
|
|
@node Symbol Descriptors
|
|
@appendix Table of Symbol Descriptors
|
|
|
|
@c Please keep this alphabetical
|
|
@table @code
|
|
@c In TeX, this looks great, digit is in italics. But makeinfo insists
|
|
@c on putting it in `', not realizing that @var should override @code.
|
|
@c I don't know of any way to make makeinfo do the right thing. Seems
|
|
@c like a makeinfo bug to me.
|
|
@item @var{digit}
|
|
@itemx (
|
|
@itemx -
|
|
Local variable, @xref{Automatic variables}.
|
|
|
|
@item a
|
|
Parameter passed by reference in register, @xref{Parameters}.
|
|
|
|
@item c
|
|
Constant, @xref{Constants}.
|
|
|
|
@item C
|
|
Conformant array bound (Pascal, maybe other languages),
|
|
@xref{Parameters}. Name of a caught exception (GNU C++). These can be
|
|
distinguished because the latter uses N_CATCH and the former uses
|
|
another symbol type.
|
|
|
|
@item d
|
|
Floating point register variable, @xref{Register variables}.
|
|
|
|
@item D
|
|
Parameter in floating point register, @xref{Parameters}.
|
|
|
|
@item f
|
|
Static function, @xref{Procedures}.
|
|
|
|
@item F
|
|
Global function, @xref{Procedures}.
|
|
|
|
@item G
|
|
Global variable, @xref{Global Variables}.
|
|
|
|
@item i
|
|
@xref{Parameters}.
|
|
|
|
@item I
|
|
Internal (nested) procedure, @xref{Procedures}.
|
|
|
|
@item J
|
|
Internal (nested) function, @xref{Procedures}.
|
|
|
|
@item L
|
|
Label name (documented by AIX, no further information known).
|
|
|
|
@item m
|
|
Module, @xref{Procedures}.
|
|
|
|
@item p
|
|
Argument list parameter, @xref{Parameters}.
|
|
|
|
@item pP
|
|
@xref{Parameters}.
|
|
|
|
@item pF
|
|
FORTRAN Function parameter, @xref{Parameters}.
|
|
|
|
@item P
|
|
Unfortunately, three separate meanings have been independently invented
|
|
for this symbol descriptor. At least the GNU and Sun uses can be
|
|
distinguished by the symbol type. Global Procedure (AIX) (symbol type
|
|
used unknown), @xref{Procedures}. Register parameter (GNU) (symbol type
|
|
N_PSYM), @xref{Parameters}. Prototype of function referenced by this
|
|
file (Sun acc) (symbol type N_FUN).
|
|
|
|
@item Q
|
|
Static Procedure, @xref{Procedures}.
|
|
|
|
@item R
|
|
Register parameter @xref{Parameters}.
|
|
|
|
@item r
|
|
Register variable, @xref{Register variables}.
|
|
|
|
@item S
|
|
Static file scope variable @xref{Initialized statics},
|
|
@xref{Un-initialized statics}.
|
|
|
|
@item t
|
|
Type name, @xref{Typedefs}.
|
|
|
|
@item T
|
|
enumeration, struct or union tag, @xref{Typedefs}.
|
|
|
|
@item v
|
|
Parameter passed by reference, @xref{Parameters}.
|
|
|
|
@item V
|
|
Static procedure scope variable @xref{Initialized statics},
|
|
@xref{Un-initialized statics}.
|
|
|
|
@item x
|
|
Conformant array, @xref{Parameters}.
|
|
|
|
@item X
|
|
Function return variable, @xref{Parameters}.
|
|
@end table
|
|
|
|
@node Type Descriptors
|
|
@appendix Table of Type Descriptors
|
|
|
|
@table @code
|
|
@item @var{digit}
|
|
@itemx (
|
|
Type reference, @xref{Stabs Format}.
|
|
|
|
@item -
|
|
Reference to builtin type, @xref{Negative Type Numbers}.
|
|
|
|
@item #
|
|
Method (C++), @xref{Cplusplus}.
|
|
|
|
@item *
|
|
Pointer, @xref{Miscellaneous Types}.
|
|
|
|
@item &
|
|
Reference (C++).
|
|
|
|
@item @@
|
|
Type Attributes (AIX), @xref{Stabs Format}. Member (class and variable)
|
|
type (GNU C++), @xref{Cplusplus}.
|
|
|
|
@item a
|
|
Array, @xref{Arrays}.
|
|
|
|
@item A
|
|
Open array, @xref{Arrays}.
|
|
|
|
@item b
|
|
Pascal space type (AIX), @xref{Miscellaneous Types}. Builtin integer
|
|
type (Sun), @xref{Builtin Type Descriptors}.
|
|
|
|
@item B
|
|
Volatile-qualified type, @xref{Miscellaneous Types}.
|
|
|
|
@item c
|
|
Complex builtin type, @xref{Builtin Type Descriptors}.
|
|
|
|
@item C
|
|
COBOL Picture type. See AIX documentation for details.
|
|
|
|
@item d
|
|
File type, @xref{Miscellaneous Types}.
|
|
|
|
@item D
|
|
N-dimensional dynamic array, @xref{Arrays}.
|
|
|
|
@item e
|
|
Enumeration type, @xref{Enumerations}.
|
|
|
|
@item E
|
|
N-dimensional subarray, @xref{Arrays}.
|
|
|
|
@item f
|
|
Function type, @xref{Function Types}.
|
|
|
|
@item F
|
|
Pascal function parameter, @xref{Function Types}
|
|
|
|
@item g
|
|
Builtin floating point type, @xref{Builtin Type Descriptors}.
|
|
|
|
@item G
|
|
COBOL Group. See AIX documentation for details.
|
|
|
|
@item i
|
|
Imported type, @xref{Cross-references}.
|
|
|
|
@item k
|
|
Const-qualified type, @xref{Miscellaneous Types}.
|
|
|
|
@item K
|
|
COBOL File Descriptor. See AIX documentation for details.
|
|
|
|
@item M
|
|
Multiple instance type, @xref{Miscellaneous Types}.
|
|
|
|
@item n
|
|
String type, @xref{Strings}.
|
|
|
|
@item N
|
|
Stringptr, @xref{Strings}.
|
|
|
|
@item o
|
|
Opaque type, @xref{Typedefs}.
|
|
|
|
@item p
|
|
Procedure, @xref{Function Types}.
|
|
|
|
@item P
|
|
Packed array, @xref{Arrays}.
|
|
|
|
@item r
|
|
Range type, @xref{Subranges}.
|
|
|
|
@item R
|
|
Builtin floating type, @xref{Builtin Type Descriptors} (Sun). Pascal
|
|
subroutine parameter, @xref{Function Types} (AIX). Detecting this
|
|
conflict is possible with careful parsing (hint: a Pascal subroutine
|
|
parameter type will always contain a comma, and a builtin type
|
|
descriptor never will).
|
|
|
|
@item s
|
|
Structure type, @xref{Structures}.
|
|
|
|
@item S
|
|
Set type, @xref{Miscellaneous Types}.
|
|
|
|
@item u
|
|
Union, @xref{Unions}.
|
|
|
|
@item v
|
|
Variant record. This is a Pascal and Modula-2 feature which is like a
|
|
union within a struct in C. See AIX documentation for details.
|
|
|
|
@item w
|
|
Wide character, @xref{Builtin Type Descriptors}.
|
|
|
|
@item x
|
|
Cross-reference, @xref{Cross-references}.
|
|
|
|
@item z
|
|
gstring, @xref{Strings}.
|
|
@end table
|
|
|
|
@node Expanded reference
|
|
@appendix Expanded reference by stab type.
|
|
|
|
@c FIXME: This appendix should go away, see N_PSYM or N_SO for an example.
|
|
|
|
For a full list of stab types, and cross-references to where they are
|
|
described, @xref{Stab Types}. This appendix just duplicates certain
|
|
information from the main body of this document; eventually the
|
|
information will all be in one place.
|
|
|
|
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.
|
|
|
|
@menu
|
|
* N_GSYM:: Global variable
|
|
* N_FNAME:: Function name (BSD Fortran)
|
|
* N_FUN:: C Function name or text segment variable
|
|
* N_STSYM:: Initialized static symbol
|
|
* N_LCSYM:: Uninitialized static symbol
|
|
* N_MAIN:: Name of main routine (not for C)
|
|
* N_PC:: Pascal global symbol
|
|
* N_NSYMS:: Number of symbols
|
|
* N_NOMAP:: No DST map
|
|
* N_RSYM:: Register variable
|
|
* N_M2C:: Modula-2 compilation unit
|
|
* N_BROWS:: Path to .cb file for Sun source code browser
|
|
* N_DEFD:: GNU Modula2 definition module dependency
|
|
* N_EHDECL:: GNU C++ exception variable
|
|
* N_MOD2:: Modula2 information "for imc"
|
|
* N_CATCH:: GNU C++ "catch" clause
|
|
* N_SSYM:: Structure or union element
|
|
* N_LSYM:: Automatic variable
|
|
* N_ENTRY:: Alternate entry point
|
|
* N_LBRAC:: Beginning of lexical block
|
|
* N_SCOPE:: Modula2 scope information (Sun only)
|
|
* N_RBRAC:: End of lexical block
|
|
* N_BCOMM:: Begin named common block
|
|
* N_ECOMM:: End named common block
|
|
* N_ECOML:: End common
|
|
* Gould:: non-base register symbols used on Gould systems
|
|
* N_LENG:: Length of preceding entry
|
|
@end menu
|
|
|
|
@node N_GSYM
|
|
@section 32 - 0x20 - N_GYSM
|
|
|
|
@display
|
|
Global variable.
|
|
|
|
.stabs "name", N_GSYM, NIL, NIL, NIL
|
|
@end display
|
|
|
|
@example
|
|
"name" -> "symbol_name:#type"
|
|
# -> G
|
|
@end example
|
|
|
|
Only the "name" field is significant. The location of the variable is
|
|
obtained from the corresponding external symbol.
|
|
|
|
@node N_FNAME
|
|
@section 34 - 0x22 - N_FNAME
|
|
Function name (for BSD Fortran)
|
|
|
|
@display
|
|
.stabs "name", N_FNAME, NIL, NIL, NIL
|
|
@end display
|
|
|
|
@example
|
|
"name" -> "function_name"
|
|
@end example
|
|
|
|
Only the "name" field is significant. The location of the symbol is
|
|
obtained from the corresponding extern symbol.
|
|
|
|
@node N_FUN
|
|
@section 36 - 0x24 - N_FUN
|
|
|
|
Function name (@pxref{Procedures}) or text segment variable
|
|
(@pxref{Variables}).
|
|
@example
|
|
@exdent @emph{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.
|
|
|
|
@exdent @emph{For text segment variables:}
|
|
<<How to create one?>>
|
|
@end example
|
|
|
|
@node N_STSYM
|
|
@section 38 - 0x26 - N_STSYM
|
|
Initialized static symbol (data segment w/internal linkage).
|
|
|
|
@display
|
|
.stabs "name", N_STSYM, NIL, NIL, value
|
|
@end display
|
|
|
|
@example
|
|
"name" -> "symbol_name#type"
|
|
# -> S (scope global to compilation unit)
|
|
-> V (scope local to a procedure)
|
|
value -> Data Address
|
|
@end example
|
|
|
|
@node N_LCSYM
|
|
@section 40 - 0x28 - N_LCSYM
|
|
Unitialized static (.lcomm) symbol(BSS segment w/internal linkage).
|
|
|
|
@display
|
|
.stabs "name", N_LCLSYM, NIL, NIL, value
|
|
@end display
|
|
|
|
@example
|
|
"name" -> "symbol_name#type"
|
|
# -> S (scope global to compilation unit)
|
|
-> V (scope local to procedure)
|
|
value -> BSS Address
|
|
@end example
|
|
|
|
@node N_MAIN
|
|
@section 42 - 0x2a - N_MAIN
|
|
Name of main routine (not used in C)
|
|
|
|
@display
|
|
.stabs "name", N_MAIN, NIL, NIL, NIL
|
|
@end display
|
|
|
|
@example
|
|
"name" -> "name_of_main_routine"
|
|
@end example
|
|
|
|
@node N_PC
|
|
@section 48 - 0x30 - N_PC
|
|
Global symbol (for Pascal)
|
|
|
|
@display
|
|
.stabs "name", N_PC, NIL, NIL, value
|
|
@end display
|
|
|
|
@example
|
|
"name" -> "symbol_name" <<?>>
|
|
value -> supposedly the line number (stab.def is skeptical)
|
|
@end example
|
|
|
|
@display
|
|
stabdump.c says:
|
|
|
|
global pascal symbol: name,,0,subtype,line
|
|
<< subtype? >>
|
|
@end display
|
|
|
|
@node N_NSYMS
|
|
@section 50 - 0x32 - N_NSYMS
|
|
Number of symbols (according to Ultrix V4.0)
|
|
|
|
@display
|
|
0, files,,funcs,lines (stab.def)
|
|
@end display
|
|
|
|
@node N_NOMAP
|
|
@section 52 - 0x34 - N_NOMAP
|
|
no DST map for sym (according to Ultrix V4.0)
|
|
|
|
@display
|
|
name, ,0,type,ignored (stab.def)
|
|
@end display
|
|
|
|
@node N_RSYM
|
|
@section 64 - 0x40 - N_RSYM
|
|
register variable
|
|
|
|
@display
|
|
.stabs "name:type",N_RSYM,0,RegSize,RegNumber (Sun doc)
|
|
@end display
|
|
|
|
@node N_M2C
|
|
@section 66 - 0x42 - N_M2C
|
|
Modula-2 compilation unit
|
|
|
|
@display
|
|
.stabs "name", N_M2C, 0, desc, value
|
|
@end display
|
|
|
|
@example
|
|
"name" -> "unit_name,unit_time_stamp[,code_time_stamp]
|
|
desc -> unit_number
|
|
value -> 0 (main unit)
|
|
1 (any other unit)
|
|
@end example
|
|
|
|
@node N_BROWS
|
|
@section 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
|
|
|
|
@node N_DEFD
|
|
@section 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?
|
|
|
|
@node N_EHDECL
|
|
@section 80 - 0x50 - N_EHDECL
|
|
GNU C++ exception variable <<?>>
|
|
|
|
"name is variable name"
|
|
|
|
Note: conflicts with N_MOD2.
|
|
|
|
@node N_MOD2
|
|
@section 80 - 0x50 - N_MOD2
|
|
Modula2 info "for imc" (according to Ultrix V4.0)
|
|
|
|
Note: conflicts with N_EHDECL <<?>>
|
|
|
|
@node N_CATCH
|
|
@section 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.
|
|
|
|
@node N_SSYM
|
|
@section 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>>
|
|
|
|
@node N_LSYM
|
|
@section 128 - 0x80 - N_LSYM
|
|
Automatic var in the stack (also used for type descriptors.)
|
|
|
|
@display
|
|
.stabs "name" N_LSYM, NIL, NIL, value
|
|
@end display
|
|
|
|
@example
|
|
@exdent @emph{For stack based local variables:}
|
|
|
|
"name" -> name of the variable
|
|
value -> offset from frame pointer (negative)
|
|
|
|
@exdent @emph{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.
|
|
@end example
|
|
|
|
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.
|
|
|
|
@node N_ENTRY
|
|
@section 164 - 0xa4 - N_ENTRY
|
|
|
|
Alternate entry point.
|
|
Value is its address.
|
|
<<?>>
|
|
|
|
@node N_LBRAC
|
|
@section 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. <<?>>
|
|
|
|
@display
|
|
.stabn N_LBRAC, NIL, NIL, value
|
|
@end display
|
|
|
|
@example
|
|
value -> code address of block start.
|
|
@end example
|
|
|
|
@node N_SCOPE
|
|
@section 196 - 0xc4 - N_SCOPE
|
|
|
|
Modula2 scope information (Sun linker)
|
|
<<?>>
|
|
|
|
@node N_RBRAC
|
|
@section 224 - 0xe0 - N_RBRAC
|
|
|
|
End of a lexical block (right brace)
|
|
|
|
@display
|
|
.stabn N_RBRAC, NIL, NIL, value
|
|
@end display
|
|
|
|
@example
|
|
value -> code address of the end of the block.
|
|
@end example
|
|
|
|
@node N_BCOMM
|
|
@section 226 - 0xe2 - N_BCOMM
|
|
|
|
Begin named common block.
|
|
|
|
Only the name is significant.
|
|
<<?>>
|
|
|
|
@node N_ECOMM
|
|
@section 228 - 0xe4 - N_ECOMM
|
|
|
|
End named common block.
|
|
|
|
Only the name is significant and it should match the N_BCOMM
|
|
<<?>>
|
|
|
|
@node N_ECOML
|
|
@section 232 - 0xe8 - N_ECOML
|
|
|
|
End common (local name)
|
|
|
|
value is address.
|
|
<<?>>
|
|
|
|
@node Gould
|
|
@section Non-base registers on Gould systems
|
|
|
|
These are used on Gould systems for non-base registers syms.
|
|
|
|
However, the following values are not the values used by Gould; they are
|
|
the values which GNU has been documenting for these values for a long
|
|
time, without actually checking what Gould uses. I include these values
|
|
only because perhaps some someone actually did something with the GNU
|
|
information (I hope not, why GNU knowingly assigned wrong values to
|
|
these in the header file is a complete mystery to me).
|
|
|
|
@example
|
|
240 0xf0 N_NBTEXT ??
|
|
242 0xf2 N_NBDATA ??
|
|
244 0xf4 N_NBBSS ??
|
|
246 0xf6 N_NBSTS ??
|
|
248 0xf8 N_NBLCS ??
|
|
@end example
|
|
|
|
@node N_LENG
|
|
@section - 0xfe - N_LENG
|
|
|
|
Second symbol entry containing a length-value for the preceding entry.
|
|
The value is the length.
|
|
|
|
@node Questions
|
|
@appendix Questions and anomalies
|
|
|
|
@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 preceding 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. (Bugs gcc/1063, gdb/1066.)
|
|
|
|
@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
|
|
@appendix Differences between GNU stabs in a.out and GNU stabs in xcoff
|
|
|
|
@c FIXME: Merge *all* these into the main body of the document.
|
|
(The AIX/RS6000 native object file format is xcoff with stabs). This
|
|
appendix only covers those differences which are not covered in the main
|
|
body of this document.
|
|
|
|
@itemize @bullet
|
|
@item
|
|
BSD a.out stab types correspond 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
|
|
If the xcoff stab is a N_FUN (C_FUN) then follow the string field with
|
|
,. instead of just ,
|
|
@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
|
|
@appendix Differences between GNU stabs and Sun native stabs.
|
|
|
|
@c FIXME: Merge all this stuff into the main body of the document.
|
|
|
|
@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
|
|
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. dbx seems not to care.
|
|
|
|
@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
|