This commit is the last in the series removing GDB's support for stabs.
It removes the stabsread.{c|h} files, and removes the last usage of
stabsread stuff in buildsym. Notably, the header file gdb-stabs.h
remains in the tree as it is misnamed at this point - it is used for
reading dbx objfiles. It (and dbxread) will be removed in a future
commit.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
source.c \
source-cache.c \
split-name.c \
- stabsread.c \
stack.c \
std-regs.c \
symfile.c \
sparc-ravenscar-thread.h \
sparc-tdep.h \
split-name.h \
- stabsread.h \
stack.h \
stap-probe.h \
svr4-tls-tdep.h \
subsequent runs of the inferior will use the same arguments as the
first run.
+* Support for stabs debug information has been removed.
+
* New targets
GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux*
return 0;
}
-int
-default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
- return 0;
-}
-
int
generic_instruction_nullified (struct gdbarch *gdbarch,
struct regcache *regcache)
extern int generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
struct type *type);
-extern int default_stabs_argument_has_addr (struct gdbarch *gdbarch,
- struct type *type);
-
extern int generic_instruction_nullified (struct gdbarch *gdbarch,
struct regcache *regcache);
#include "dictionary.h"
#include <algorithm>
-/* For cleanup_undefined_stabs_types and finish_global_stabs (somewhat
- questionable--see comment where we call them). */
-
-#include "stabsread.h"
-
/* List of blocks already made (lexical contexts already closed).
This is used at the end to make the blockvector. */
pb->block = barray[i++];
}
- /* Cleanup any undefined types that have been left hanging around
- (this needs to be done before the finish_blocks so that
- file_symbols is still good).
-
- Both cleanup_undefined_stabs_types and finish_global_stabs are stabs
- specific, but harmless for other symbol readers, since on gdb
- startup or when finished reading stabs, the state is set so these
- are no-ops. FIXME: Is this handled right in case of QUIT? Can
- we make this cleaner? */
-
- cleanup_undefined_stabs_types (m_objfile);
- finish_global_stabs (m_objfile);
-
if (!required
&& m_pending_blocks == NULL
&& m_file_symbols == NULL
}
#endif
\f
+
+const registry<objfile>::key<dbx_symfile_info> dbx_objfile_data_key;
+
+/* This could leak memory, but it will be removed soon, so it
+ shouldn't have a large impact. */
+dbx_symfile_info::~dbx_symfile_info ()
+{
+}
+
/* Scan and build partial symbols for a symbol file.
We have been initialized by a call to dbx_symfile_init, which
put all the relevant info into a "struct dbx_symfile_info",
TEXINPUTS=${TEXIDIR}:.:$(srcdir):$(READLINE_DIR):$(GDBMI_DIR):$$TEXINPUTS
# Files which should be generated via 'info' and installed by 'install-info'
-INFO_DEPS = gdb.info stabs.info annotate.info
+INFO_DEPS = gdb.info annotate.info
# Files which should be generated via 'dvi' and installed by 'install-dvi'
-DVIFILES = gdb.dvi stabs.dvi refcard.dvi annotate.dvi
+DVIFILES = gdb.dvi refcard.dvi annotate.dvi
# Files which should be generated via 'pdf' and installed by 'install-pdf'
-PDFFILES = gdb.pdf stabs.pdf refcard.pdf annotate.pdf
+PDFFILES = gdb.pdf refcard.pdf annotate.pdf
# Files which should be generated via 'html' and installed by 'install-html'
-HTMLFILES = gdb/index.html stabs/index.html annotate/index.html
-HTMLFILES_INSTALL = gdb stabs annotate
+HTMLFILES = gdb/index.html annotate/index.html
+HTMLFILES_INSTALL = gdb annotate
# There may be alternate predefined collections of switches to configure
# the GDB manual. Normally this is not done in synch with the software
$(GDB_DOC_SOURCE_INCLUDES) \
$(GDB_DOC_BUILD_INCLUDES)
-# Stabs manual: All files
-STABS_DOC_SOURCE_INCLUDES = \
- $(srcdir)/fdl.texi
-STABS_DOC_BUILD_INCLUDES = \
- gdb-cfg.texi \
- GDBvn.texi
-STABS_DOC_FILES = \
- $(srcdir)/stabs.texinfo \
- $(STABS_DOC_SOURCE_INCLUDES) \
- $(STABS_DOC_BUILD_INCLUDES)
-
# Annotate migration document
ANNOTATE_DOC_SOURCE_INCLUDES = \
$(srcdir)/fdl.texi
info: $(INFO_DEPS)
dvi: $(DVIFILES)
-ps: gdb.ps stabs.ps refcard.ps annotate.ps
+ps: gdb.ps refcard.ps annotate.ps
html: $(HTMLFILES)
pdf: $(PDFFILES)
man: $(MANS)
$(READLINE_TEXI_INCFLAG) -I ${GDBMI_DIR} -I $(srcdir) \
$(srcdir)/gdb.texinfo
-stabs.info: $(STABS_DOC_FILES)
- $(ECHO_MAKEINFO) $(MAKEINFO_CMD) -I $(srcdir) -o stabs.info $(srcdir)/stabs.texinfo
-
-# STABS DOCUMENTATION: HTML file
-
-stabs/index.html: $(STABS_DOC_FILES)
- $(ECHO_GEN) $(MAKEHTML) $(MAKEHTMLFLAGS) \
- -o stabs \
- -I $(srcdir) \
- $(srcdir)/stabs.texinfo
-
-# STABS DOCUMENTATION: TeX dvi file
-stabs.dvi : $(STABS_DOC_FILES)
- $(ECHO_TEXI2DVI) $(TEXI2DVI_CMD) $(SILENT_Q_FLAG) -I $(srcdir) \
- $(srcdir)/stabs.texinfo
-
-stabs.ps: stabs.dvi
- $(ECHO_DVIPS) $(DVIPS) $(SILENT_Q_FLAG) -o $@ $?
-
-stabs.pdf: $(STABS_DOC_FILES)
- $(ECHO_TEXI2DVI) $(TEXI2DVI_CMD) $(SILENT_Q_FLAG) --pdf -I $(srcdir) \
- $(srcdir)/stabs.texinfo
-
# ANNOTATE DOCUMENTATION: TeX dvi file
annotate.dvi : $(ANNOTATE_DOC_FILES)
$(ECHO_TEXI2DVI) $(TEXI2DVI_CMD) $(SILENT_Q_FLAG) -I $(srcdir) \
(which may include, e.g., the compiler version and command line arguments),
@item
whether the executable includes debugging information for that file, and
-if so, what format the information is in (e.g., STABS, Dwarf 2, etc.), and
+if so, what format the information is in (e.g., Dwarf 2), and
@item
whether the debugging information includes information about
preprocessor macros.
We have not implemented the two-stage strategy for COFF yet. When the
symbol table is stored in COFF format, @code{symbol-file} reads the
-symbol table data in full right away. Note that ``stabs-in-COFF''
-still does the two-stage strategy, since the debug info is actually
-in stabs format.
+symbol table data in full right away.
@kindex readnow
@cindex reading symbols immediately
$ gdb -iex "set use-deprecated-index-sections on" <program>
@end smallexample
-Indices only work when using DWARF debugging information, not stabs.
+Indices only work when using DWARF debugging information.
@subsection Automatic symbol index cache
This command prints, for each object file in the program, various data
about that object file followed by the byte cache (@dfn{bcache})
statistics for the object file. The objfile data includes the number
-of minimal, partial, full, and stabs symbols, the number of types
-defined by the objfile, the number of as yet unexpanded psym tables,
-the number of line tables and string tables, and the amount of memory
-used by the various tables. The bcache statistics include the counts,
-sizes, and counts of duplicates of all and unique objects, max,
-average, and median entry size, total memory used and its overhead and
-savings, and various measures of the hash table size and chain
-lengths.
+of minimal, partial, and full, the number of types defined by the
+objfile, the number of as yet unexpanded psym tables, the number of
+line tables and string tables, and the amount of memory used by the
+various tables. The bcache statistics include the counts, sizes, and
+counts of duplicates of all and unique objects, max, average, and
+median entry size, total memory used and its overhead and savings,
+and various measures of the hash table size and chain lengths.
@kindex maint print target-stack
@cindex target stack description
+++ /dev/null
-\input texinfo
-@setfilename stabs.info
-@setchapternewpage odd
-@settitle STABS
-
-@c man begin INCLUDE
-@include gdb-cfg.texi
-@c man end
-
-@c @finalout
-
-@c This is a dir.info fragment to support semi-automated addition of
-@c manuals to an info tree.
-@dircategory Software development
-@direntry
-* Stabs: (stabs). The "stabs" debugging information format.
-@end direntry
-
-@copying
-Copyright @copyright{} 1992--2025 Free Software Foundation, Inc.
-Contributed by Cygnus Support. Written by Julia Menapace, Jim Kingdon,
-and David MacKenzie.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts. A copy of the license is included in the section entitled ``GNU
-Free Documentation License''.
-@end copying
-
-@ifnottex
-This document describes the stabs debugging symbol tables.
-
-@insertcopying
-@end ifnottex
-
-@titlepage
-@title The ``stabs'' debug format
-@author Julia Menapace, Jim Kingdon, David MacKenzie
-@author Cygnus Support
-@page
-@tex
-\def\$#1${{#1}} % Kludge: 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
-@insertcopying
-@end titlepage
-
-@ifnottex
-@node Top
-@top The "stabs" representation of debugging information
-
-This document describes the stabs debugging format.
-
-@menu
-* Overview:: Overview of stabs
-* Program Structure:: Encoding of the structure of the program
-* Constants:: Constants
-* Variables::
-* Types:: Type definitions
-* Macro define and undefine:: Representation of #define and #undef
-* Symbol Tables:: Symbol information in symbol tables
-* Cplusplus:: Stabs specific to C++
-* Stab Types:: Symbol types in a.out files
-* Symbol Descriptors:: Table of symbol descriptors
-* Type Descriptors:: Table of type descriptors
-* Expanded Reference:: Reference information by stab type
-* Questions:: Questions and anomalies
-* Stab Sections:: In some object file formats, stabs are
- in sections.
-* GNU Free Documentation License:: The license for this documentation
-* Symbol Types Index:: Index of symbolic stab symbol type names.
-@end menu
-@end ifnottex
-
-@contents
-
-@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
-Peter Kessler 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 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. Stabs for COBOL-specific features and for variant
-records (used by Pascal and Modula-2) are poorly documented here.
-
-@c FIXME: Need to document all OS9000 stuff in GDB; see all references
-@c to os9k_stabs in stabsread.c.
-
-Other sources of information on stabs are @cite{Dbx and Dbxtool
-Interfaces}, 2nd edition, by Sun, 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 explicitly directs
-you to them for more information.
-
-@menu
-* Flow:: Overview of debugging information flow
-* Stabs Format:: Overview of stab format
-* String Field:: The string field
-* 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 the assembler translates into
-a @file{.o} file, which the linker combines with other @file{.o} files and
-libraries to produce an executable file.
-
-With the @samp{-g} option, GCC puts in the @file{.s} file additional
-debugging information, 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 function names,
-parameters, and scopes.
-
-For some object file formats, the debugging information is encapsulated
-in assembler directives known collectively as @dfn{stab} (symbol table)
-directives, which are 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 which combination of four possible data fields follows. It is
-either @code{.stabs} (string), @code{.stabn} (number), or @code{.stabd}
-(dot). IBM's XCOFF assembler 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},@var{other},@var{desc},@var{value}
-.stabn @var{type},@var{other},@var{desc},@var{value}
-.stabd @var{type},@var{other},@var{desc}
-.stabx "@var{string}",@var{value},@var{type},@var{sdb-type}
-@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 @var{string} (the
-@code{n_strx} field is zero; see @ref{Symbol Tables}). For
-@code{.stabd}, the @var{value} field is implicit and has the value of
-the current file location. For @code{.stabx}, the @var{sdb-type} field
-is unused for stabs and can always be set to zero. The @var{other}
-field is almost always unused and can be set to zero.
-
-The number in the @var{type} field gives some basic information about
-which type of stab this is (or whether it @emph{is} a stab, as opposed
-to an ordinary symbol). Each valid type number defines a different stab
-type; further, the stab type defines the exact interpretation of, and
-possible values for, any remaining @var{string}, @var{desc}, or
-@var{value} fields present in the stab. @xref{Stab Types}, for a list
-in numeric order of the valid @var{type} field values for stab directives.
-
-@node String Field
-@section The String Field
-
-For most stabs the string field holds the meat of the
-debugging information. The flexible 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 of the string field for most stab types is:
-
-@example
-"@var{name}:@var{symbol-descriptor} @var{type-information}"
-@end example
-
-@var{name} is the name of the symbol represented by the stab; it can
-contain a pair of colons (@pxref{Nested Symbols}). @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}. The @samp{c}
-symbol descriptor is an exception in that it is not followed by type
-information. @xref{Constants}.
-
-@var{type-information} is either a @var{type-number}, or
-@samp{@var{type-number}=}. A @var{type-number} alone is a type
-reference, referring directly to a type that has already been defined.
-
-The @samp{@var{type-number}=} form 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. Also, the Lucid
-compiler will repeat @samp{@var{type-number}=} more than once if it
-wants to define several type numbers at once.
-
-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}.
-@xref{Type Descriptors}, for a list of @var{type-descriptor} values. If
-a number follows the @samp{=} then the number is a @var{type-reference}.
-For a full description of types, @ref{Types}.
-
-A @var{type-number} is often a single number. The GNU and Sun tools
-additionally permit a @var{type-number} to be a pair
-(@var{file-number},@var{filetype-number}) (the parentheses appear in the
-string, and serve to distinguish the two cases). The @var{file-number}
-is 0 for the base source file, 1 for the first included file, 2 for the
-next, and so on. The @var{filetype-number} is a number starting with
-1 which is incremented for each new type defined in the file.
-(Separating the file number and the type number permits the
-@code{N_BINCL} optimization to succeed more often; see @ref{Include
-Files}).
-
-There is an AIX extension for type attributes. Following the @samp{=}
-are any number of type attributes. Each one starts with @samp{@@} and
-ends with @samp{;}. Debuggers, including AIX's dbx and GDB 4.10, skip
-any type attributes they do not recognize. GDB 4.9 and other versions
-of dbx may not do this. Because of a conflict with C@t{++}
-(@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@t{++} 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 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.
-
-@item s@var{size}
-Size in bits of a variable of this type. This is fully supported by GDB
-4.11 and later.
-
-@item S
-Indicate that this type is a string instead of an array of characters,
-or a bitstring instead of a set. It doesn't change the layout of the
-data being represented, but does enable the debugger to know which type
-it is.
-
-@item V
-Indicate that this type is a vector instead of an array. The only
-major difference between vectors and arrays is that vectors are
-passed by value instead of by reference (vector coprocessor extension).
-
-@end table
-
-All of this can make the string field quite long. All versions of GDB,
-and some versions of dbx, can handle arbitrarily long strings. But many
-versions of dbx (or assemblers or linkers, I'm not sure which)
-cretinously limit the strings to about 80 characters, so compilers which
-must work with such systems need to split the @code{.stabs} directive
-into several @code{.stabs} directives. Each stab duplicates every field
-except the string field. The string field of every stab except the last
-is marked as continued with a backslash at the end (in the assembly code
-this may be written as a double backslash, depending on the assembler).
-Removing the backslashes and concatenating the string fields of each
-stab produces the original, long string. Just to be incompatible (or so
-they don't have to worry about what the assembler does with
-backslashes), AIX can use @samp{?} instead of backslash.
-
-@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
-
-This simple ``hello world'' example demonstrates several of the stab
-types used to describe C language source files.
-
-@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
-
-@node Program Structure
-@chapter Encoding the Structure of the Program
-
-The elements of the program structure that stabs encode include the name
-of the main function, the names of the source and include files, the
-line numbers, procedure names and types, and the beginnings and ends of
-blocks of code.
-
-@menu
-* Main Program:: Indicate what the main program is
-* Source Files:: The path and name of the source file
-* Include Files:: Names of include files
-* Line Numbers::
-* Procedures::
-* Nested Procedures::
-* Block Structure::
-* Alternate Entry Points:: Entering procedures except at the beginning.
-@end menu
-
-@node Main Program
-@section Main Program
-
-@findex N_MAIN
-Most languages allow the main program to have any name. The
-@code{N_MAIN} stab type tells the debugger the name that is used in this
-program. Only the string field is significant; it is the name of
-a function which is the main program. Most C compilers do not use this
-stab (they expect the debugger to assume that the name is @code{main}),
-but some C compilers emit an @code{N_MAIN} stab for the @code{main}
-function. I'm not sure how XCOFF handles this.
-
-@node Source Files
-@section Paths and Names of the Source Files
-
-@findex N_SO
-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 field contains the name of the file. The
-value of the symbol is the start address of the portion of the
-text section corresponding to that file.
-
-Some compilers use the desc field to indicate the language of the
-source file. Sun's compilers started this usage, and the first
-constants are derived from their documentation. Languages added
-by gcc/gdb start at 0x32 to avoid conflict with languages Sun may
-add in the future. A desc field with a value 0 indicates that no
-language has been specified via this mechanism.
-
-@table @asis
-@item @code{N_SO_AS} (0x1)
-Assembly language
-@item @code{N_SO_C} (0x2)
-K&R traditional C
-@item @code{N_SO_ANSI_C} (0x3)
-ANSI C
-@item @code{N_SO_CC} (0x4)
-C++
-@item @code{N_SO_FORTRAN} (0x5)
-Fortran
-@item @code{N_SO_PASCAL} (0x6)
-Pascal
-@item @code{N_SO_FORTRAN90} (0x7)
-Fortran90
-@item @code{N_SO_OBJC} (0x32)
-Objective-C
-@item @code{N_SO_OBJCPLUS} (0x33)
-Objective-C++
-@end table
-
-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 @code{cfront} C@t{++} 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 # @r{100 is N_SO}
-.stabs "hello.c",100,0,0,Ltext0
- .text
-Ltext0:
-@end example
-
-@findex C_FILE
-Instead of @code{N_SO} symbols, XCOFF uses a @code{.file} assembler
-directive which assembles to a @code{C_FILE} symbol; explaining this in
-detail is outside the scope of this document.
-
-@c FIXME: Exactly when should the empty N_SO be used? Why?
-If it is useful to indicate the end of a source file, this is done with
-an @code{N_SO} symbol with an empty string for the name. The value is
-the address of the end of the text section for the file. For some
-systems, there is no indication of the end of a source file, and you
-just need to figure it ended when you see an @code{N_SO} for a different
-source file, or a symbol ending in @code{.o} (which at least some
-linkers insert to mark the start of a new @code{.o} file).
-
-@node Include Files
-@section Names of Include Files
-
-There are several schemes for dealing with include files: the
-traditional @code{N_SOL} approach, Sun's @code{N_BINCL} approach, and the
-XCOFF @code{C_BINCL} approach (which despite the similar name has little in
-common with @code{N_BINCL}).
-
-@findex N_SOL
-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 end 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.
-
-@findex N_BINCL
-@findex N_EINCL
-@findex N_EXCL
-The @code{N_BINCL} approach works as follows. An @code{N_BINCL} symbol
-specifies the start of an include file. In an object file, only the
-string is significant; the linker puts data into some of the other
-fields. The end of the include file is marked by an @code{N_EINCL}
-symbol (which has no string field). In an object file, there is no
-significant data in the @code{N_EINCL} symbol. @code{N_BINCL} and
-@code{N_EINCL} can be nested.
-
-If the linker detects that two source files have identical stabs between
-an @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 occurrence is replaced by an @code{N_EXCL} symbol. I believe
-the GNU linker and the Sun (both SunOS4 and Solaris) linker are the only
-ones which supports this feature.
-
-A linker which supports this feature will set the value of a
-@code{N_BINCL} symbol to the total of all the characters in the stabs
-strings included in the header file, omitting any file numbers. The
-value of an @code{N_EXCL} symbol is the same as the value of the
-@code{N_BINCL} symbol it replaces. This information can be used to
-match up @code{N_EXCL} and @code{N_BINCL} symbols which have the same
-filename. The @code{N_EINCL} value, and the values of the other and
-description fields for all three, appear to always be zero.
-
-@findex C_BINCL
-@findex C_EINCL
-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 the offset into the executable of the beginning
-(inclusive, as you'd expect) or end (inclusive, as you would not expect)
-of the portion of the COFF line table that corresponds to this include
-file. @code{C_BINCL} and @code{C_EINCL} do not nest.
-
-@node Line Numbers
-@section Line Numbers
-
-@findex N_SLINE
-An @code{N_SLINE} symbol represents the start of a source line. The
-desc field contains the line number and the value contains the code
-address for the start of that source line. On most machines the address
-is absolute; for stabs in sections (@pxref{Stab Sections}), it is
-relative to the function in which the @code{N_SLINE} symbol occurs.
-
-@findex N_DSLINE
-@findex N_BSLINE
-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) since
-at least GDB 3.5.
-
-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.
-
-XCOFF does not use stabs for line numbers. Instead, it uses COFF line
-numbers (which are outside the scope of this document). Standard COFF
-line numbers cannot deal with include files, but in XCOFF this is fixed
-with the @code{C_BINCL} method of marking include files (@pxref{Include
-Files}).
-
-@node Procedures
-@section Procedures
-
-@findex N_FUN, for functions
-@findex N_FNAME
-@findex N_STSYM, for functions (Sun acc)
-@findex N_GSYM, for functions (Sun acc)
-All of the following stabs normally use the @code{N_FUN} symbol type.
-However, Sun's @code{acc} compiler on SunOS4 uses @code{N_GSYM} and
-@code{N_STSYM}, which means that the value of the stab for the function
-is useless and the debugger must get the address of the function from
-the non-stab symbols instead. On systems where non-stab symbols have
-leading underscores, the stabs will lack underscores and the debugger
-needs to know about the leading underscore to match up the stab and the
-non-stab symbol. BSD Fortran is said to use @code{N_FNAME} with the
-same restriction; the value of the symbol is not useful (I'm not sure it
-really does use this, because GDB doesn't handle this and no one has
-complained).
-
-@findex C_FUN
-A function is represented by an @samp{F} symbol descriptor for a global
-(extern) function, and @samp{f} for a static (local) function. For
-a.out, the value of the symbol is the address of the start of the
-function; it is already relocated. For stabs in ELF, the SunPRO
-compiler version 2.0.1 and GCC put out an address which gets relocated
-by the linker. In a future release SunPRO is planning to put out zero,
-in which case the address can be found from the ELF (non-stab) symbol.
-Because looking things up in the ELF symbols would probably be slow, I'm
-not sure how to find which symbol of that name is the right one, and
-this doesn't provide any way to deal with nested functions, it would
-probably be better to make the value of the stab an address relative to
-the start of the file, or just absolute. See @ref{ELF Linker
-Relocation} for more information on linker relocation of stabs in ELF
-files. For XCOFF, the stab uses the @code{C_FUN} storage class and the
-value of the stab is meaningless; the address of the function can be
-found from the csect symbol (XTY_LD/XMC_PR).
-
-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. There is no need to try to get the line number of the start of the
-function from the stab for the function; it is in the next
-@code{N_SLINE} symbol.
-
-@c FIXME: verify whether the "I suspect" below is true or not.
-Some compilers (such as Sun's Solaris compiler) support an extension for
-specifying the types of the arguments. I suspect this extension is not
-used for old (non-prototyped) function definitions in C. If the
-extension is in use, the type information of the stab for the function
-is 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). GDB has tolerated this extension (parsed the syntax, if not
-necessarily used the information) since at least version 4.8; I don't
-know whether all versions of dbx tolerate it. The argument types given
-here are not redundant with the symbols for the formal parameters
-(@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 when 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{Register 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 @code{void} type in C. I don't see why this couldn't
-be used for all languages (inventing a @code{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.
-
-The following example shows a stab for a function @code{main} which
-returns type number @code{1}. The @code{_main} specified for the value
-is a reference to an assembler label which is used to fill in the start
-address of the function.
-
-@example
-.stabs "main:F1",36,0,0,_main # @r{36 is N_FUN}
-@end example
-
-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.
-
-If functions can appear in different sections, then the debugger may not
-be able to find the end of a function. Recent versions of GCC will mark
-the end of a function with an @code{N_FUN} symbol with an empty string
-for the name. The value is the address of the end of the current
-function. Without such a symbol, there is no indication of the address
-of the end of a function, and you must assume that it ended at the
-starting address of the next function or at the end of the text section
-for the program.
-
-@node Nested Procedures
-@section Nested Procedures
-
-For any of the symbol descriptors representing procedures, after the
-symbol descriptor and the type information is optionally a scope
-specifier. This consists of a comma, the name of the procedure, another
-comma, and the name of the enclosing procedure. The first name is local
-to the scope specified, and seems to be redundant with the name of the
-symbol (before the @samp{:}). This feature is used by GCC, and
-presumably Pascal, Modula-2, etc., compilers, for nested functions.
-
-If procedures are nested more than one level deep, only the immediately
-containing scope is specified. For example, this code:
-
-@example
-int
-foo (int x)
-@{
- int bar (int y)
- @{
- int baz (int z)
- @{
- return x + y + z;
- @}
- return baz (x + 2 * y);
- @}
- return x + bar (3 * x);
-@}
-@end example
-
-@noindent
-produces the stabs:
-
-@example
-.stabs "baz:f1,baz,bar",36,0,0,_baz.15 # @r{36 is N_FUN}
-.stabs "bar:f1,bar,foo",36,0,0,_bar.12
-.stabs "foo:F1",36,0,0,_foo
-@end example
-
-@node Block Structure
-@section Block Structure
-
-@findex N_LBRAC
-@findex N_RBRAC
-@c For GCC 2.5.8 or so stabs-in-coff, these are absolute instead of
-@c function relative (as documented below). But GDB has never been able
-@c to deal with that (it had wanted them to be relative to the file, but
-@c I just fixed that (between GDB 4.12 and 4.13)), so it is function
-@c relative just like ELF and SOM and the below documentation.
-The program's block structure is represented by the @code{N_LBRAC} (left
-brace) and the @code{N_RBRAC} (right brace) stab types. The variables
-defined inside a block precede the @code{N_LBRAC} symbol for most
-compilers, including GCC. Other compilers, such as the Convex, Acorn
-RISC machine, and Sun @code{acc} compilers, put the variables after the
-@code{N_LBRAC} symbol. The values of the @code{N_LBRAC} and
-@code{N_RBRAC} symbols are the start and end addresses of the code of
-the block, respectively. For most machines, they are relative to the
-starting address of this source file. For the Gould NP1, they are
-absolute. For stabs in sections (@pxref{Stab Sections}), they are
-relative to the function in which they occur.
-
-The @code{N_LBRAC} and @code{N_RBRAC} stabs that describe the block
-scope of a procedure are located after the @code{N_FUN} stab that
-represents the procedure itself.
-
-Sun documents the desc field of @code{N_LBRAC} and
-@code{N_RBRAC} symbols as containing the nesting level of the block.
-However, dbx seems to not care, and GCC always sets desc to
-zero.
-
-@findex .bb
-@findex .be
-@findex C_BLOCK
-For XCOFF, block scope is indicated with @code{C_BLOCK} symbols. If the
-name of the symbol is @samp{.bb}, then it is the beginning of the block;
-if the name of the symbol is @samp{.be}; it is the end of the block.
-
-@node Alternate Entry Points
-@section Alternate Entry Points
-
-@findex N_ENTRY
-@findex C_ENTRY
-Some languages, like Fortran, have the ability to enter procedures at
-some place other than the beginning. One can declare an alternate entry
-point. The @code{N_ENTRY} stab is for this; however, the Sun FORTRAN
-compiler doesn't use it. According to AIX documentation, only the name
-of a @code{C_ENTRY} stab is significant; the address of the alternate
-entry point comes from the corresponding external symbol. A previous
-revision of this document said that the value of an @code{N_ENTRY} stab
-was the address of the alternate entry point, but I don't know the
-source for that information.
-
-@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{String Field}). @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{String Field}).
-@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 ignores them. GDB 4.8 and earlier gave an error
-message and refused to read symbols from the file containing the
-constants.
-
-The above information is followed by @samp{;}.
-
-@node Variables
-@chapter Variables
-
-Different types of stabs describe the various ways that variables can be
-allocated: on the stack, globally, in registers, in common blocks,
-statically, or as arguments to a function.
-
-@menu
-* Stack Variables:: Variables allocated on the stack.
-* Global Variables:: Variables used by more than one source file.
-* Register Variables:: Variables in registers.
-* Common Blocks:: Variables statically allocated together.
-* Statics:: Variables local to one source file.
-* Based Variables:: Fortran pointer based variables.
-* Parameters:: Variables for arguments to functions.
-@end menu
-
-@node Stack Variables
-@section Automatic Variables Allocated on the Stack
-
-If a variable's scope is local to a function and its lifetime is only as
-long as that function executes (C calls such variables
-@dfn{automatic}), it can be allocated in a register (@pxref{Register
-Variables}) or on the stack.
-
-@findex N_LSYM, for stack variables
-@findex C_LSYM
-Each variable allocated on the stack has a stab with the symbol
-descriptor omitted. Since type information should begin with a digit,
-@samp{-}, or @samp{(}, only those characters precluded from being used
-for symbol descriptors. However, the Acorn RISC machine (ARM) is said
-to get this wrong: it puts out a mere type definition here, without the
-preceding @samp{@var{type-number}=}. This is a bad idea; there is no
-guarantee that type descriptors are distinct from symbol descriptors.
-Stabs for stack variables use the @code{N_LSYM} stab type, or
-@code{C_LSYM} for XCOFF.
-
-The value of the stab is the offset of the variable within the
-local variables. On most machines this is an offset from the frame
-pointer and is negative. The location of the stab specifies which block
-it is defined in; see @ref{Block Structure}.
-
-For example, the following C code:
-
-@example
-int
-main ()
-@{
- int x;
-@}
-@end example
-
-produces the following stabs:
-
-@example
-.stabs "main:F1",36,0,0,_main # @r{36 is N_FUN}
-.stabs "x:1",128,0,0,-12 # @r{128 is N_LSYM}
-.stabn 192,0,0,LBB2 # @r{192 is N_LBRAC}
-.stabn 224,0,0,LBE2 # @r{224 is N_RBRAC}
-@end example
-
-See @ref{Procedures} for more information on the @code{N_FUN} stab, and
-@ref{Block Structure} for more information on the @code{N_LBRAC} and
-@code{N_RBRAC} stabs.
-
-@node Global Variables
-@section Global Variables
-
-@findex N_GSYM
-@findex C_GSYM
-@c FIXME: verify for sure that it really is C_GSYM on XCOFF
-A variable whose scope is not specific to just one source file is
-represented by the @samp{G} symbol descriptor. These stabs use the
-@code{N_GSYM} stab type (C_GSYM for XCOFF). The type information for
-the stab (@pxref{String Field}) gives the type of the variable.
-
-For example, the following source code:
-
-@example
-char g_foo = 'c';
-@end example
-
-@noindent
-yields the following assembly code:
-
-@example
-.stabs "g_foo:G2",32,0,0,0 # @r{32 is N_GSYM}
- .global _g_foo
- .data
-_g_foo:
- .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. In the example above,
-the @code{.global _g_foo} and @code{_g_foo:} lines tell the assembler to
-produce an external symbol.
-
-Some compilers, like GCC, output @code{N_GSYM} stabs only once, where
-the variable is defined. Other compilers, like SunOS4 /bin/cc, output a
-@code{N_GSYM} stab for each compilation unit which references the
-variable.
-
-@node Register Variables
-@section Register Variables
-
-@findex N_RSYM
-@findex C_RSYM
-@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}
-(@code{C_RSYM} for XCOFF), and their own symbol descriptor, @samp{r}.
-The stab's value is the number of the register where the variable data
-will be stored.
-@c .stabs "name:type",N_RSYM,0,RegSize,RegNumber (Sun doc)
-
-AIX defines a separate symbol descriptor @samp{d} for floating point
-registers. This seems unnecessary; 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
-
-@noindent
-then the stab may be emitted at the end of the object file, with
-the other bss symbols.
-
-@node Common Blocks
-@section Common Blocks
-
-A common block is a statically allocated section of memory which can be
-referred to by several source files. It may contain several variables.
-I believe Fortran is the only language with this feature.
-
-@findex N_BCOMM
-@findex N_ECOMM
-@findex C_BCOMM
-@findex C_ECOMM
-A @code{N_BCOMM} stab begins a common block and an @code{N_ECOMM} stab
-ends it. The only field that is significant in these two stabs is the
-string, which names a normal (non-debugging) symbol that gives the
-address of the common block. According to IBM documentation, only the
-@code{N_BCOMM} has the name of the common block (even though their
-compiler actually puts it both places).
-
-@findex N_ECOML
-@findex C_ECOML
-The stabs for the members of the common block are between the
-@code{N_BCOMM} and the @code{N_ECOMM}; the value of each stab is the
-offset within the common block of that variable. IBM uses the
-@code{C_ECOML} stab type, and there is a corresponding @code{N_ECOML}
-stab type, but Sun's Fortran compiler uses @code{N_GSYM} instead. The
-variables within a common block use the @samp{V} symbol descriptor (I
-believe this is true of all Fortran variables). Other stabs (at least
-type declarations using @code{C_DECL}) can also be between the
-@code{N_BCOMM} and the @code{N_ECOMM}.
-
-@node Statics
-@section Static Variables
-
-Initialized static variables are represented by the @samp{S} and
-@samp{V} symbol descriptors. @samp{S} means file scope static, and
-@samp{V} means procedure scope static. One exception: in XCOFF, IBM's
-xlc compiler always uses @samp{V}, and whether it is file scope or not
-is distinguished by whether the stab is located within a function.
-
-@c This is probably not worth mentioning; it is only true on the sparc
-@c for `double' variables which although declared const are actually in
-@c the data segment (the text segment can't guarantee 8 byte alignment).
-@c (although GCC
-@c 2.4.5 has a bug in that it uses @code{N_FUN}, so neither dbx nor GDB can
-@c find the variables)
-@findex N_STSYM
-@findex N_LCSYM
-@findex N_FUN, for variables
-@findex N_ROSYM
-In a.out files, @code{N_STSYM} means the data section, @code{N_FUN}
-means the text section, and @code{N_LCSYM} means the bss section. For
-those systems with a read-only data section separate from the text
-section (Solaris), @code{N_ROSYM} means the read-only data section.
-
-For example, the source lines:
-
-@example
-static const int var_const = 5;
-static int var_init = 2;
-static int var_noinit;
-@end example
-
-@noindent
-yield the following stabs:
-
-@example
-.stabs "var_const:S1",36,0,0,_var_const # @r{36 is N_FUN}
-@dots{}
-.stabs "var_init:S1",38,0,0,_var_init # @r{38 is N_STSYM}
-@dots{}
-.stabs "var_noinit:S1",40,0,0,_var_noinit # @r{40 is N_LCSYM}
-@end example
-
-@findex C_STSYM
-@findex C_BSTAT
-@findex C_ESTAT
-In XCOFF files, the stab type need not indicate the section;
-@code{C_STSYM} can be used for all statics. Also, each static variable
-is enclosed in a static block. A @code{C_BSTAT} (emitted with a
-@samp{.bs} assembler directive) symbol begins the static block; its
-value is the symbol number of the csect symbol whose value is the
-address of the static block, its section is the section of the variables
-in that static block, and its name is @samp{.bs}. A @code{C_ESTAT}
-(emitted with a @samp{.es} assembler directive) symbol ends the static
-block; its name is @samp{.es} and its value and section are ignored.
-
-In ECOFF files, the storage class is used to specify the section, so the
-stab type need not indicate the section.
-
-In ELF files, for the SunPRO compiler version 2.0.1, symbol descriptor
-@samp{S} means that the address is absolute (the linker relocates it)
-and symbol descriptor @samp{V} means that the address is relative to the
-start of the relevant section for that compilation unit. SunPRO has
-plans to have the linker stop relocating stabs; I suspect that their the
-debugger gets the address from the corresponding ELF (not stab) symbol.
-I'm not sure how to find which symbol of that name is the right one.
-The clean way to do all this would be to have the value of a symbol
-descriptor @samp{S} symbol be an offset relative to the start of the
-file, just like everything else, but that introduces obvious
-compatibility problems. For more information on linker stab relocation,
-@xref{ELF Linker Relocation}.
-
-@node Based Variables
-@section Fortran Based Variables
-
-Fortran (at least, the Sun and SGI dialects of FORTRAN-77) has a feature
-which allows allocating arrays with @code{malloc}, but which avoids
-blurring the line between arrays and pointers the way that C does. In
-stabs such a variable uses the @samp{b} symbol descriptor.
-
-For example, the Fortran declarations
-
-@example
-real foo, foo10(10), foo10_5(10,5)
-pointer (foop, foo)
-pointer (foo10p, foo10)
-pointer (foo105p, foo10_5)
-@end example
-
-produce the stabs
-
-@example
-foo:b6
-foo10:bar3;1;10;6
-foo10_5:bar3;1;5;ar3;1;10;6
-@end example
-
-In this example, @code{real} is type 6 and type 3 is an integral type
-which is the type of the subscripts of the array (probably
-@code{integer}).
-
-The @samp{b} symbol descriptor is like @samp{V} in that it denotes a
-statically allocated symbol whose scope is local to a function; see
-@xref{Statics}. The value of the symbol, instead of being the address
-of the variable itself, is the address of a pointer to that variable.
-So in the above example, the value of the @code{foo} stab is the address
-of a pointer to a real, the value of the @code{foo10} stab is the
-address of a pointer to a 10-element array of reals, and the value of
-the @code{foo10_5} stab is the address of a pointer to a 5-element array
-of 10-element arrays of reals.
-
-@node Parameters
-@section Parameters
-
-Formal parameters to a function are represented by a stab (or sometimes
-two; see below) for each parameter. The stabs are in the order in which
-the debugger should print the parameters (i.e., the order in which the
-parameters are declared in the source file). The exact form of the stab
-depends on how the parameter is being passed.
-
-@findex N_PSYM
-@findex C_PSYM
-Parameters passed on the stack use the symbol descriptor @samp{p} and
-the @code{N_PSYM} symbol type (or @code{C_PSYM} for XCOFF). The value
-of the symbol is an offset used to locate the parameter on the stack;
-its exact meaning is machine-dependent, but on most machines it is an
-offset from the frame pointer.
-
-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 # @r{36 is N_FUN}
-.stabs "argc:p1",160,0,0,68 # @r{160 is N_PSYM}
-.stabs "argv:p20=*21=*2",160,0,0,72
-@end example
-
-The type definition of @code{argv} is interesting because it contains
-several type definitions. Type 21 is pointer to type 2 (char) and
-@code{argv} (type 20) is pointer to type 21.
-
-@c FIXME: figure out what these mean and describe them coherently.
-The following symbol descriptors are also said to go with @code{N_PSYM}.
-The value of the symbol is said to be an offset from the argument
-pointer (I'm not sure whether this is true or not).
-
-@example
-pP (<<??>>)
-pF Fortran function parameter
-X (function result variable)
-@end example
-
-@menu
-* Register Parameters::
-* Local Variable Parameters::
-* Reference Parameters::
-* Conformant Arrays::
-@end menu
-
-@node Register Parameters
-@subsection Passing Parameters in Registers
-
-If the parameter is passed in a register, then traditionally there are
-two symbols for each argument:
-
-@example
-.stabs "arg:p1" . . . ; N_PSYM
-.stabs "arg:r1" . . . ; N_RSYM
-@end example
-
-Debuggers use the second one to find the value, and the first one to
-know that it is an argument.
-
-@findex C_RPSYM
-@findex N_RSYM, for parameters
-Because that approach is kind of ugly, some compilers use symbol
-descriptor @samp{P} or @samp{R} to indicate an argument which is in a
-register. Symbol type @code{C_RPSYM} is used in XCOFF and @code{N_RSYM}
-is used otherwise. The symbol's 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.
-
-There is at least one case where GCC uses a @samp{p} and @samp{r} pair
-rather than @samp{P}; this is where the argument is passed in the
-argument list and then loaded into a register.
-
-According to the AIX documentation, symbol descriptor @samp{D} is for a
-parameter passed in a floating point register. This seems
-unnecessary---why not 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.
-
-@c FIXME: On the hppa this is for any type > 8 bytes, I think, and not
-@c for small structures (investigate).
-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} and @samp{r} pair (using Sun
-@code{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} and @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 (@pxref{Reference Parameters}).
-
-@node Local Variable Parameters
-@subsection Storing Parameters as Local Variables
-
-There is a case similar to an argument in a register, which is an
-argument that 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.
-
-If a parameter is passed as one type and converted to a smaller type by
-the prologue (for example, the parameter is declared as a @code{float},
-but the calling conventions specify that it is passed as a
-@code{double}), then GCC2 (sometimes) uses a pair of symbols. The first
-symbol uses symbol descriptor @samp{p} and the type which is passed.
-The second symbol has the type and location which the parameter actually
-has after the prologue. For example, suppose the following C code
-appears with no prototypes involved:
-
-@example
-void
-subr (f)
- float f;
-@{
-@end example
-
-if @code{f} is passed as a double at stack offset 8, and the prologue
-converts it to a float in register number 0, then the stabs look like:
-
-@example
-.stabs "f:p13",160,0,3,8 # @r{160 is @code{N_PSYM}, here 13 is @code{double}}
-.stabs "f:r12",64,0,3,0 # @r{64 is @code{N_RSYM}, here 12 is @code{float}}
-@end example
-
-In both stabs 3 is the line number where @code{f} is declared
-(@pxref{Line Numbers}).
-
-@findex N_LSYM, for parameter
-GCC, at least on the 960, has another solution to the same problem. It
-uses a single @samp{p} symbol descriptor for an argument which is stored
-as a local variable but uses @code{N_LSYM} instead of @code{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.
-
-@c This is mostly just background info; the part that logically belongs
-@c here is the last sentence.
-On the VAX or on other machines in which the calling convention includes
-the number of words of arguments actually passed, the debugger (GDB at
-least) uses the parameter symbols to keep track of whether it needs to
-print nameless arguments in addition to the formal parameters which it
-has printed because each one has a stab. For example, in
-
-@example
-extern int fprintf (FILE *stream, char *format, @dots{});
-@dots{}
-fprintf (stdout, "%d\n", x);
-@end example
-
-there are stabs for @code{stream} and @code{format}. On most machines,
-the debugger can only print those two arguments (because it has no way
-of knowing that additional arguments were passed), but on the VAX or
-other machines with a calling convention which indicates the number of
-words of arguments, the debugger can print all three arguments. To do
-so, the parameter symbol (symbol descriptor @samp{p}) (not necessarily
-@samp{r} or symbol descriptor omitted symbols) needs to contain the
-actual type as passed (for example, @code{double} not @code{float} if it
-is passed as a double and converted to a float).
-
-@node Reference Parameters
-@subsection Passing Parameters by Reference
-
-If the parameter is passed by reference (e.g., Pascal @code{VAR}
-parameters), then the 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 rather 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.
-
-@node Conformant Arrays
-@subsection Passing Conformant Array Parameters
-
-@c Is this paragraph correct? It is based on piecing together patchy
-@c information and some guesswork
-Conformant arrays are 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.
-
-@node Types
-@chapter Defining Types
-
-The examples so far have described types as references to previously
-defined types, or defined in terms of subranges of or pointers to
-previously defined types. This chapter describes the other type
-descriptors that may follow the @samp{=} 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 convoluted, so new ways
-have been invented to describe them. Sun's @code{acc} uses special
-builtin type descriptors (@samp{b} and @samp{R}), and IBM uses negative
-type numbers. GDB accepts all three ways, as of version 4.8; dbx just
-accepts the traditional builtin types and perhaps one of the other two
-formats. The following sections describe each of these formats.
-
-@menu
-* Traditional Builtin Types:: Put on your seat belts 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
-
-This is the traditional, convoluted method for defining builtin types.
-There are several classes of such type definitions: integer, floating
-point, and @code{void}.
-
-@menu
-* Traditional Integer Types::
-* Traditional Other Types::
-@end menu
-
-@node Traditional Integer Types
-@subsubsection Traditional Integer Types
-
-Often types are defined as subranges of themselves. If the bounding values
-fit within an @code{int}, then they are given normally. For example:
-
-@example
-.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0 # @r{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,
-the type is an unsigned integral type whose bounds are too
-big to describe in an @code{int}. Traditionally this is only used for
-@code{unsigned int} and @code{unsigned long}:
-
-@example
-.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
-@end example
-
-For larger types, GCC 2.4.5 puts out bounds in octal, with one or more
-leading zeroes. In this case a negative bound consists of a number
-which is a 1 bit (for the sign bit) followed by a 0 bit for each bit in
-the number (except the sign bit), and a positive bound is one which is a
-1 bit for each bit in the number (except possibly the sign bit). All
-known versions of dbx and GDB version 4 accept this (at least in the
-sense of not refusing to process the file), but GDB 3.5 refuses to read
-the whole file containing such symbols. So GCC 2.3.3 did not output the
-proper size for these types. As an example of octal bounds, the string
-fields of the stabs for 64 bit integer types look like:
-
-@c .stabs directives, etc., omitted to make it fit on the page.
-@example
-long int:t3=r1;001000000000000000000000;000777777777777777777777;
-long unsigned int:t5=r1;000000000000000000000000;001777777777777777777777;
-@end example
-
-If the lower bound of a subrange is 0 and the upper bound is negative,
-the type 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,
-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.
-
-@node Traditional Other Types
-@subsubsection Traditional Other Types
-
-If the upper bound of a subrange is 0 and the lower bound is positive,
-the type 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}, so there is no way to distinguish.
-
-@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; there is
-no way to distinguish a single-precision complex from a double-precision
-floating-point type.
-
-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
-
-This is the method used by Sun's @code{acc} for defining builtin types.
-These are the 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 @code{complex}, @code{double complex}, and
-@code{complex*16}, respectively, but what does that mean? (i.e., Single
-precision? Double precision?).
-
-@item 6 (NF_LDOUBLE)
-Long double. This should probably only be used for Sun format
-@code{long double}, and new codes should be used for other floating
-point formats (@code{NF_DOUBLE} can be used if a @code{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-type}.
-
-@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
-
-This is the method used in XCOFF for defining builtin types.
-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 builtin type. There is no stab defining these types.
-
-There are several subtle issues with negative type numbers.
-
-One is the size of the type. A builtin type (for example the C types
-@code{int} or @code{long}) might have different sizes depending on
-compiler options, the target architecture, the ABI, etc. This issue
-doesn't come up for IBM tools since (so far) they just target the
-RS/6000; the sizes indicated below for each size are what the IBM
-RS/6000 tools use. To deal with differing sizes, either define separate
-negative type numbers for each size (which works but requires changing
-the debugger, and, unless you get both AIX dbx and GDB to accept the
-change, introduces an incompatibility), or use a type attribute
-(@pxref{String Field}) to define a new type with the appropriate size
-(which merely requires a debugger which understands type attributes,
-like AIX dbx or GDB). For example,
-
-@example
-.stabs "boolean:t10=@@s8;-16",128,0,0,0
-@end example
-
-defines an 8-bit boolean type, and
-
-@example
-.stabs "boolean:t10=@@s64;-16",128,0,0,0
-@end example
-
-defines a 64-bit boolean type.
-
-A similar issue is the format of the type. This comes up most often for
-floating-point types, which could have various formats (particularly
-extended doubles, which vary quite a bit even among IEEE systems).
-Again, it is best to define a new negative type number for each
-different format; changing the format based on the target system has
-various problems. One such problem is that the Alpha has both VAX and
-IEEE floating types. One can easily imagine one library using the VAX
-types and another library in the same executable using the IEEE types.
-Another example is that the interpretation of whether a boolean is true
-or false can be based on the least significant bit, most significant
-bit, whether it is zero, etc., and different compilers (or different
-options to the same compiler) might provide different kinds of boolean.
-
-The last major issue is the names of the types. The name of a given
-type depends @emph{only} on the negative type number given; these do not
-vary depending on the language, the target system, or anything else.
-One can always define separate type numbers---in the following list you
-will see for example separate @code{int} and @code{integer*4} types
-which are identical except for the name. But compatibility can be
-maintained by not inventing new negative type numbers and instead just
-defining a new type with a new name. For example:
-
-@example
-.stabs "CARDINAL:t10=-8",128,0,0,0
-@end example
-
-Here is the list of negative type numbers. The phrase @dfn{integral
-type} is used to mean twos-complement (I strongly suspect that all
-machines which use stabs use twos-complement; most machines use
-twos-complement these days).
-
-@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 (@code{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}. 32 bit type. GDB and GCC assume that zero is false,
-one is true, and other values have unspecified meaning. I hope this
-agrees with how the IBM tools use 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 character type.
-
-@item -21
-@code{logical*1}, 8 bit type. This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers. 0 is false, 1 is true, and other values are
-non-boolean.
-
-@item -22
-@code{logical*2}, 16 bit type. This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers. 0 is false, 1 is true, and other values are
-non-boolean.
-
-@item -23
-@code{logical*4}, 32 bit type. This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers. 0 is false, 1 is true, and other values are
-non-boolean.
-
-@item -24
-@code{logical}, 32 bit type. This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers. 0 is false, 1 is true, and other values are
-non-boolean.
-
-@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, unsigned (what format?
-Unicode?).
-
-@item -31
-@code{long long}, 64 bit signed integral type.
-
-@item -32
-@code{unsigned long long}, 64 bit unsigned integral type.
-
-@item -33
-@code{logical*8}, 64 bit unsigned integral type.
-
-@item -34
-@code{integer*8}, 64 bit signed integral type.
-@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?
-
-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. References and stores to a variable with a
-volatile-qualified 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 variable with a const-qualified 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; see @ref{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}.
-
-In CHILL, if it is a bitstring instead of a set, also use the @samp{S}
-type attribute (@pxref{String Field}).
-
-@item * @var{type-information}
-Pointer to @var{type-information}.
-@end table
-
-@node Cross-References
-@section Cross-References to Other Types
-
-A type can be used before it is defined; one common way to deal with
-that situation is just to use a type reference to a type which has not
-yet been defined.
-
-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{:}.
-If the name contains @samp{::} between a @samp{<} and @samp{>} pair (for
-C@t{++} templates), such a @samp{::} does not end the name---only a single
-@samp{:} ends the name; see @ref{Nested Symbols}.
-
-For example, the following C declarations:
-
-@example
-struct foo;
-struct foo *bar;
-@end example
-
-@noindent
-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{String Field}), 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 of which it is a
-subrange, 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 passed 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; see @ref{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 ends in a semicolon; otherwise
-(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{String Field}) (that is, it need not start with
-@samp{@var{type-number}=} 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 type
-descriptor @samp{r} and some parameters. It defines the size of the
-array. In the example below, the range @samp{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}, 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{String Field}). 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
-
-Languages, such as CHILL which have a string type which is basically
-just an array of characters use the @samp{S} type attribute
-(@pxref{String Field}).
-
-@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 at file scope.
-The type definition is located after the @code{N_RBRAC} that marks the end of
-the previous procedure's block scope, and before the @code{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 (@samp{T}) says that the stab describes a
-structure, enumeration, or union tag. The type descriptor @samp{e},
-following the @samp{22=} of the type definition narrows it down to an
-enumeration type. Following the @samp{e} is a list of the elements of
-the enumeration. The format is @samp{@var{name}:@var{value},}. The
-list of elements ends with @samp{;}. The fact that @var{value} is
-specified as an integer can cause problems if the value is large. GCC
-2.5.2 tries to output it in octal in that case with a leading zero,
-which is probably a good thing, although GDB 4.11 supports octal only in
-cases where decimal is perfectly good. Negative decimal values are
-supported by both GDB and dbx.
-
-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). Type attributes can be used to specify an enumeration type of
-another size for debuggers which support them; see @ref{String Field}.
-
-Enumeration types are unusual in that they define symbols for the
-enumeration values (@code{first}, @code{second}, and @code{third} in the
-above example), and even though these symbols are visible in the file as
-a whole (rather than being in a more local namespace like structure
-member names), they are defined in the type definition for the
-enumeration type rather than each having their own symbol. In order to
-be fast, GDB will only get symbols from such types (in its initial scan
-of the stabs) if the type is the first thing defined after a @samp{T} or
-@samp{t} symbol descriptor (the above example fulfills this
-requirement). If the type does not have a name, the compiler should
-emit it in a nameless stab (@pxref{String Field}); GCC does this.
-
-@node Structures
-@section Structures
-
-The encoding of structures in stabs can be shown with an example.
-
-The following source code declares a structure tag and defines an
-instance of the structure in global scope. Then a @code{typedef} equates the
-structure tag with a new type. Separate stabs are generated for the
-structure tag, the structure @code{typedef}, and the structure instance. The
-stabs for the tag and the @code{typedef} are emitted 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 the bss section.
-
-@example
-struct s_tag @{
- int s_int;
- float s_float;
- char s_char_vec[8];
- struct s_tag* s_next;
-@} g_an_s;
-
-typedef struct s_tag s_typedef;
-@end example
-
-The structure tag has an @code{N_LSYM} stab type because, like the
-enumeration, the symbol has file scope. Like the enumeration, the
-symbol descriptor is @samp{T}, for enumeration, structure, or tag type.
-The type descriptor @samp{s} following the @samp{16=} of the type
-definition narrows the symbol type to structure.
-
-Following the @samp{s} type descriptor is the number of bytes the
-structure occupies, followed by a description of each structure element.
-The structure element descriptions are of the form
-@samp{@var{name}:@var{type}, @var{bit offset from the start of the
-struct}, @var{number of bits in the element}}.
-
-@c FIXME: phony line break. Can probably be fixed by using an example
-@c with fewer fields.
-@example
-# @r{128 is N_LSYM}
-.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, the first two structure elements are previously defined
-types. For these, the type following the @samp{@var{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 @samp{@var{name}:}. The type definition for the
-array element looks just like a type definition for a stand-alone array.
-The @code{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 a type definition for an element which is a pointer to type 16.
-
-If a field is a static member (this is a C@t{++} feature in which a single
-variable appears to be a field of every structure of a given type) it
-still starts out with the field name, a colon, and the type, but then
-instead of a comma, bit position, comma, and bit size, there is a colon
-followed by the name of the variable which each such field refers to.
-
-If the structure has methods (a C@t{++} feature), they follow the non-method
-fields; see @ref{Cplusplus}.
-
-@node Typedefs
-@section Giving a Type a Name
-
-@findex N_LSYM, for types
-@findex C_DECL, for types
-To give a type a name, use the @samp{t} symbol descriptor. The type
-is specified by the type information (@pxref{String Field}) for the stab.
-For example,
-
-@example
-.stabs "s_typedef:t16",128,0,0,0 # @r{128 is N_LSYM}
-@end example
-
-specifies that @code{s_typedef} refers to type number 16. Such stabs
-have symbol type @code{N_LSYM} (or @code{C_DECL} for XCOFF). (The Sun
-documentation mentions using @code{N_GSYM} in some cases).
-
-If 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{String Field})? 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
-
-@example
-union u_tag @{
- int u_int;
- float u_float;
- char* u_char;
-@} an_u;
-@end example
-
-This code generates a stab for a union tag and a stab for a union
-variable. Both use the @code{N_LSYM} stab type. If a union variable is
-scoped locally to the procedure in which it is defined, its stab is
-located immediately preceding the @code{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 @code{N_LSYM}. This
-would seem to imply that the union type is file scope, like the struct
-type @code{s_tag}. This is not true. The contents and position of the stab
-for @code{u_type} do not convey any information about its procedure local
-scope.
-
-@c FIXME: phony line break. Can probably be fixed by using an example
-@c with fewer fields.
-@smallexample
-# @r{128 is N_LSYM}
-.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 @samp{T}, following the @samp{name:} means that
-the stab describes an enumeration, structure, or union tag. The type
-descriptor @samp{u}, following the @samp{23=} of the type definition,
-narrows it down to a union type definition. Following the @samp{u} is
-the number of bytes in the union. After that is a list of union element
-descriptions. Their format is @samp{@var{name}:@var{type}, @var{bit
-offset into the union}, @var{number of bytes for the element};}.
-
-The stab for the union variable is:
-
-@example
-.stabs "an_u:23",128,0,0,-20 # @r{128 is N_LSYM}
-@end example
-
-@samp{-20} specifies where the variable is stored (@pxref{Stack
-Variables}).
-
-@node Function Types
-@section Function Types
-
-Various types can be defined for function variables. These types are
-not used in defining functions (@pxref{Procedures}); 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 for which the number and types of the
-parameters are part of the type, as 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. If it is @samp{f} or @samp{F}, this
-type involves a function rather than a procedure, 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, 0 if passed by reference or
-1 if passed by value, and a semicolon. The type definition ends with a
-semicolon.
-
-For example, this variable definition:
-
-@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 a function returning @code{int}.
-
-@node Macro define and undefine
-@chapter Representation of #define and #undef
-
-This section describes the stabs support for macro define and undefine
-information, supported on some systems. (e.g., with @option{-g3}
-@option{-gstabs} when using GCC).
-
-A @code{#define @var{macro-name} @var{macro-body}} is represented with
-an @code{N_MAC_DEFINE} stab with a string field of
-@code{@var{macro-name} @var{macro-body}}.
-@findex N_MAC_DEFINE
-
-An @code{#undef @var{macro-name}} is represented with an
-@code{N_MAC_UNDEF} stabs with a string field of simply
-@code{@var{macro-name}}.
-@findex N_MAC_UNDEF
-
-For both @code{N_MAC_DEFINE} and @code{N_MAC_UNDEF}, the desc field is
-the line number within the file where the corresponding @code{#define}
-or @code{#undef} occurred.
-
-For example, the following C code:
-
-@example
- #define NONE 42
- #define TWO(a, b) (a + (a) + 2 * b)
- #define ONE(c) (c + 19)
-
- main(int argc, char *argv[])
- @{
- func(NONE, TWO(10, 11));
- func(NONE, ONE(23));
-
- #undef ONE
- #define ONE(c) (c + 23)
-
- func(NONE, ONE(-23));
-
- return (0);
- @}
-
- int global;
-
- func(int arg1, int arg2)
- @{
- global = arg1 + arg2;
- @}
-@end example
-
-@noindent
-produces the following stabs (as well as many others):
-
-@example
- .stabs "NONE 42",54,0,1,0
- .stabs "TWO(a,b) (a + (a) + 2 * b)",54,0,2,0
- .stabs "ONE(c) (c + 19)",54,0,3,0
- .stabs "ONE",58,0,10,0
- .stabs "ONE(c) (c + 23)",54,0,11,0
-@end example
-
-@noindent
-NOTE: In the above example, @code{54} is @code{N_MAC_DEFINE} and
-@code{58} is @code{N_MAC_UNDEF}.
-
-@node Symbol Tables
-@chapter Symbol Information in Symbol Tables
-
-This chapter describes the format of symbol table entries
-and how stab assembler directives map to them. It also describes the
-transformations that the assembler and linker make on data from stabs.
-
-@menu
-* Symbol Table Format::
-* Transformations On Symbol Tables::
-@end menu
-
-@node Symbol Table Format
-@section Symbol Table Format
-
-Each time the assembler encounters a stab directive, it puts
-each field of the stab into a corresponding field 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:
-
-@c FIXME: should refer to external, not internal.
-@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
-
-If the stab has a string, the @code{n_strx} field holds the offset in
-bytes of the string within the string table. The string is terminated
-by a NUL character. If the stab lacks a string (for example, it was
-produced by a @code{.stabn} or @code{.stabd} directive), the
-@code{n_strx} field is zero.
-
-Symbol table entries with @code{n_type} field values greater than 0x1f
-originated as stabs generated by the compiler (with one random
-exception). The other entries were placed in the symbol table of the
-executable by the assembler or the linker.
-
-@node Transformations On Symbol Tables
-@section Transformations on Symbol Tables
-
-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. To
-do this, use @samp{nm -ap}, which dumps the symbol table, including
-debugging information, unsorted. For stab entries the columns are:
-@var{value}, @var{other}, @var{desc}, @var{type}, @var{string}. For
-assembler and linker symbols, the columns are: @var{value}, @var{type},
-@var{string}.
-
-The low 5 bits of the stab type tell the linker how to relocate the
-value of the stab. Thus for stab types like @code{N_RSYM} and
-@code{N_LSYM}, where the value is an offset or a register number, the
-low 5 bits are @code{N_ABS}, which tells the linker not to relocate the
-value.
-
-Where the value 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.
-
-@menu
-* Transformations On Static Variables::
-* Transformations On Global Variables::
-* Stab Section Transformations:: For some object file formats,
- things are a bit different.
-@end menu
-
-@node Transformations On Static Variables
-@subsection Transformations on Static Variables
-
-This source line defines a static variable at file scope:
-
-@example
-static int s_g_repeat
-@end example
-
-@noindent
-The following stab describes the symbol:
-
-@example
-.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
-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
-0000e00c - 00 0000 STSYM s_g_repeat:S1
-@end example
-
-@node Transformations On Global Variables
-@subsection Transformations on Global Variables
-
-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
-char g_foo = 'c';
-@end example
-
-@noindent
-generates the stab:
-
-@example
-.stabs "g_foo:G2",32,0,0,0
-@end example
-
-The variable is represented by two symbol table entries in the object
-file (see below). The first one originated as a stab. The second one
-is an external symbol. The upper case @samp{D} signifies that the
-@code{n_type} field of the symbol table contains 7, @code{N_DATA} with
-local linkage. The stab's value is zero since the value is not used for
-@code{N_GSYM} stabs. The value of the linker symbol is the relocatable
-address corresponding to the variable.
-
-@example
-00000000 - 00 0000 GSYM g_foo:G2
-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
-00000000 - 00 0000 GSYM g_foo:G2
-@dots{}
-0000e008 D _g_foo
-@end example
-
-@node Stab Section Transformations
-@subsection Transformations of Stabs in separate sections
-
-For object file formats using stabs in separate sections (@pxref{Stab
-Sections}), use @code{objdump --stabs} instead of @code{nm} to show the
-stabs in an object or executable file. @code{objdump} is a GNU utility;
-Sun does not provide any equivalent.
-
-The following example is for a stab whose value is an address is
-relative to the compilation unit (@pxref{ELF Linker Relocation}). For
-example, if the source line
-
-@example
-static int ld = 5;
-@end example
-
-appears within a function, then the assembly language output from the
-compiler contains:
-
-@example
-.Ddata.data:
-@dots{}
- .stabs "ld:V(0,3)",0x26,0,4,.L18-Ddata.data # @r{0x26 is N_STSYM}
-@dots{}
-.L18:
- .align 4
- .word 0x5
-@end example
-
-Because the value is formed by subtracting one symbol from another, the
-value is absolute, not relocatable, and so the object file contains
-
-@example
-Symnum n_type n_othr n_desc n_value n_strx String
-31 STSYM 0 4 00000004 680 ld:V(0,3)
-@end example
-
-without any relocations, and the executable file also contains
-
-@example
-Symnum n_type n_othr n_desc n_value n_strx String
-31 STSYM 0 4 00000004 680 ld:V(0,3)
-@end example
-
-@node Cplusplus
-@chapter GNU C@t{++} Stabs
-
-@menu
-* Class Names:: C++ class names are both tags and typedefs.
-* Nested Symbols:: C++ symbol names can be within other types.
-* Basic Cplusplus Types::
-* Simple Classes::
-* Class Instance::
-* Methods:: Method definition
-* Method Type Descriptor:: The @samp{#} type descriptor
-* Member Type Descriptor:: The @samp{@@} type descriptor
-* Protections::
-* Method Modifiers::
-* Virtual Methods::
-* Inheritance::
-* Virtual Base Classes::
-* Static Members::
-@end menu
-
-@node Class Names
-@section C@t{++} Class Names
-
-In C@t{++}, a class name which is declared with @code{class}, @code{struct},
-or @code{union}, is not only a tag, as in C, but also a type name. Thus
-there should be stabs with both @samp{t} and @samp{T} symbol descriptors
-(@pxref{Typedefs}).
-
-To save space, there is a special abbreviation for this case. If the
-@samp{T} symbol descriptor is followed by @samp{t}, then the stab
-defines both a type name and a tag.
-
-For example, the C@t{++} code
-
-@example
-struct foo @{int x;@};
-@end example
-
-can be represented as either
-
-@example
-.stabs "foo:T19=s4x:1,0,32;;",128,0,0,0 # @r{128 is N_LSYM}
-.stabs "foo:t19",128,0,0,0
-@end example
-
-or
-
-@example
-.stabs "foo:Tt19=s4x:1,0,32;;",128,0,0,0
-@end example
-
-@node Nested Symbols
-@section Defining a Symbol Within Another Type
-
-In C@t{++}, a symbol (such as a type name) can be defined within another type.
-@c FIXME: Needs example.
-
-In stabs, this is sometimes represented by making the name of a symbol
-which contains @samp{::}. Such a pair of colons does not end the name
-of the symbol, the way a single colon would (@pxref{String Field}). I'm
-not sure how consistently used or well thought out this mechanism is.
-So that a pair of colons in this position always has this meaning,
-@samp{:} cannot be used as a symbol descriptor.
-
-For example, if the string for a stab is @samp{foo::bar::baz:t5=*6},
-then @code{foo::bar::baz} is the name of the symbol, @samp{t} is the
-symbol descriptor, and @samp{5=*6} is the type information.
-
-@node Basic Cplusplus Types
-@section Basic Types For C@t{++}
-
-<< the examples that follow are based on a01.C >>
-
-
-C@t{++} 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@t{++} 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@t{++} language features are an extension of the
-stabs describing C. Stabs representing C@t{++} 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 @code{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 @code{N_LSYM}. Since the
-stab is not located between an @code{N_FUN} and an @code{N_LBRAC} stab this indicates
-that the class is defined at file scope. If it were, then the @code{N_LSYM}
-would signify a local variable.
-
-A stab describing a C@t{++} 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 relevant to C@t{++} 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@t{++} 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@t{++} class stab representing a member function
-differs substantially from the field part of a C struct stab. It
-still begins with @samp{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 the type of the method.
-Normally this will be a type declared using the @samp{#} type
-descriptor; see @ref{Method Type Descriptor}; static member functions
-are declared using the @samp{f} type descriptor instead; see
-@ref{Function Types}.
-
-The format of an overloaded operator method name differs from that of
-other methods. It is @samp{op$::@var{operator-name}.} where
-@var{operator-name} is the operator name such as @samp{+} or @samp{+=}.
-The name ends with a period, and any characters except the period can
-occur in the @var{operator-name} string.
-
-The next part of the method description represents the arguments to the
-method, preceded 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@t{++} name mangling. In this example an @code{int} and a @code{char}
-map to @samp{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, @samp{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@t{++} 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 Definition
-
-The class definition shown above declares Ameth. The C@t{++} 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 @code{this} pointer. The @code{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 described in the @sc{arm} (@cite{The Annotated
-C++ Reference Manual}, by Ellis and Stroustrup, @sc{isbn}
-0-201-51459-1); @file{gpcompare.texi} in Cygnus GCC distributions
-describes the differences between GNU mangling and @sc{arm}
-mangling.
-@c FIXME: Use @xref, especially if this is generally installed in the
-@c info tree.
-@c FIXME: This information should be in a net release, either of GCC or
-@c GDB. But gpcompare.texi doesn't seem to be in the FSF GCC.
-
-@example
-.stabs "name:symbol_descriptor(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 @code{this} pointer implicit argument. The
-name of the @code{this} pointer is always @code{this}. Type 19, the
-@code{this} pointer is defined as a pointer to type 20, @code{baseA},
-but a stab defining @code{baseA} has not yet been emitted. Since the
-compiler knows it will be emitted shortly, here it just outputs a cross
-reference to the undefined symbol, by prefixing the symbol name with
-@samp{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 Method Type Descriptor
-@section The @samp{#} Type Descriptor
-
-This is used to describe a class method. This is a function which takes
-an extra argument as its first argument, for the @code{this} pointer.
-
-If the @samp{#} is immediately followed by another @samp{#}, the second
-one will be followed by the return type and a semicolon. The class and
-argument types are not specified, and must be determined by demangling
-the name of the method if it is available.
-
-Otherwise, the single @samp{#} is followed by the class type, a comma,
-the return type, a comma, and zero or more parameter types separated by
-commas. The list of arguments is terminated by a semicolon. In the
-debugging output generated by gcc, a final argument type of @code{void}
-indicates a method which does not take a variable number of arguments.
-If the final argument type of @code{void} does not appear, the method
-was declared with an ellipsis.
-
-Note that although such a type will normally be used to describe fields
-in structures, unions, or classes, for at least some versions of the
-compiler it can also be used in other contexts.
-
-@node Member Type Descriptor
-@section The @samp{@@} Type Descriptor
-
-The @samp{@@} type descriptor is used for a
-pointer-to-non-static-member-data type. It is followed
-by type information for the class (or union), a comma, and type
-information for the member data.
-
-The following C@t{++} source:
-
-@smallexample
-typedef int A::*int_in_a;
-@end smallexample
-
-generates the following stab:
-
-@smallexample
-.stabs "int_in_a:t20=21=@@19,1",128,0,0,0
-@end smallexample
-
-Note that there is a conflict between this and type attributes
-(@pxref{String Field}); both use type descriptor @samp{@@}.
-Fortunately, the @samp{@@} type descriptor used in this C@t{++} sense always
-will be followed by a digit, @samp{(}, or @samp{-}, and type attributes
-never start with those things.
-
-@node Protections
-@section Protections
-
-In the simple class definition shown above all member data and
-functions were publicly accessible. The example that follows
-contrasts public, protected and privately accessible fields and shows
-how these protections are encoded in C@t{++} stabs.
-
-If the character following the @samp{@var{field-name}:} part of the
-string is @samp{/}, then the next character is the visibility. @samp{0}
-means private, @samp{1} means protected, and @samp{2} means public.
-Debuggers should ignore visibility characters they do not recognize, and
-assume a reasonable default (such as public) (GDB 4.11 does not, but
-this should be fixed in the next GDB release). If no visibility is
-specified the field is public. The visibility @samp{9} means that the
-field has been optimized out and is public (there is no way to specify
-an optimized out field with a private or protected visibility).
-Visibility @samp{9} is not supported by GDB 4.11; this should be fixed
-in the next GDB release.
-
-The following C@t{++} source:
-
-@example
-class vis @{
-private:
- int priv;
-protected:
- char prot;
-public:
- float pub;
-@};
-@end example
-
-@noindent
-generates the following stab:
-
-@example
-# @r{128 is N_LSYM}
-.stabs "vis:T19=s12priv:/01,0,32;prot:/12,32,8;pub:12,64,32;;",128,0,0,0
-@end example
-
-@samp{vis:T19=s12} indicates that type number 19 is a 12 byte structure
-named @code{vis} The @code{priv} field has public visibility
-(@samp{/0}), type int (@samp{1}), and offset and size @samp{,0,32;}.
-The @code{prot} field has protected visibility (@samp{/1}), type char
-(@samp{2}) and offset and size @samp{,32,8;}. The @code{pub} field has
-type float (@samp{12}), and offset and size @samp{,64,32;}.
-
-Protections for member functions are signified by one digit embedded 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@t{++} 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 @samp{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)virtual(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 (@code{const}, @code{volatile}, @code{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 @samp{A}, const methods use
-@samp{B}, volatile methods use @samp{C}, and const volatile methods use
-@samp{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)modifier(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 @samp{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@t{++} 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 @samp{$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
-@samp{$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@t{++}
-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 @code{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
-@samp{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
-inheritance 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 preceded by @samp{~%} 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 Inheritance
-@section Inheritance
-
-Stabs describing C@t{++} derived classes include additional sections that
-describe the inheritance 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 inheritance 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 embedded 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: a virtual character, a
-visibility character, a number, a comma, another number, and a
-semi-colon.
-
-The virtual character is @samp{1} if the base class is virtual and
-@samp{0} if not. The visibility character is @samp{2} if the derivation
-is public, @samp{1} if it is protected, and @samp{0} if it is private.
-Debuggers should ignore virtual or visibility characters they do not
-recognize, and assume a reasonable default (such as public and
-non-virtual) (GDB 4.11 does not, but this should be fixed in the next
-GDB release).
-
-The number following the virtual and visibility characters 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 @code{A}, @code{B}, and
-@code{C} and the derived class @code{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 @code{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)inheritance_public(no)base_offset(0),
- base_class_type_ref(A);
- base_virtual(yes)inheritance_public(no)base_offset(NIL),
- base_class_type_ref(B);
- base_virtual(no)inheritance_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 concatenation 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 inheritance. In the example above, class @code{D}
-inherits virtually from base class @code{B}. This means that an
-instance of a @code{D} object will not contain its own @code{B} part but
-merely a pointer to a @code{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 @code{B} is given as 0 even though
-@code{B} is not the first base class. The first base class @code{A}
-starts at offset 0.
-
-The field information part of the stab for class @code{D} describes the field
-which is the pointer to the virtual base class @code{B}. The vbase pointer
-name is @samp{$vb} followed by a type reference to the virtual base class.
-Since the type id for @code{B} in this example is 25, the vbase pointer name
-is @samp{$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 @code{B} class @code{this} pointer. The
-@code{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 @code{D} object,
-before any data fields defined by the class. The layout of a @code{D}
-class object is a follows, @code{Adat} at 0, the vtable pointer for
-@code{A} at 32, @code{Cdat} at 64, the vtable pointer for C at 96, the
-virtual base pointer for @code{B} at 128, and @code{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 Stab Types
-@appendix Table of Stab Types
-
-The following are all the possible values for the stab type field, for
-a.out files, in numeric order. This does not apply to XCOFF, but
-it does apply to stabs in sections (@pxref{Stab Sections}). Stabs in
-ECOFF use these values but add 0x8f300 to distinguish them from non-stab
-symbols.
-
-The symbolic names are defined in the file @file{include/aout/stabs.def}.
-
-@menu
-* Non-Stab Symbol Types:: Types from 0 to 0x1f
-* Stab Symbol Types:: Types from 0x20 to 0xff
-@end menu
-
-@node Non-Stab Symbol Types
-@appendixsec Non-Stab Symbol Types
-
-The following types are used by the linker and assembler, not by stab
-directives. 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 @code{N_FN}, for Sequent compilers
-
-@item 0x0a N_INDR
-Symbol is indirected to another symbol
-
-@item 0x12 N_COMM
-Common---visible after shared library dynamic link
-
-@item 0x14 N_SETA
-@itemx 0x15 N_SETA | N_EXT
-Absolute set element
-
-@item 0x16 N_SETT
-@itemx 0x17 N_SETT | N_EXT
-Text segment set element
-
-@item 0x18 N_SETD
-@itemx 0x19 N_SETD | N_EXT
-Data segment set element
-
-@item 0x1a N_SETB
-@itemx 0x1b N_SETB | N_EXT
-BSS segment set element
-
-@item 0x1c N_SETV
-@itemx 0x1d N_SETV | N_EXT
-Pointer to set vector
-
-@item 0x1e N_WARNING
-Print a warning message during linking
-
-@item 0x1f N_FN
-File name of a @file{.o} file
-@end table
-
-@node Stab Symbol Types
-@appendixsec Stab Symbol Types
-
-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; see @ref{Global Variables}.
-
-@item 0x22 N_FNAME
-Function name (for BSD Fortran); see @ref{Procedures}.
-
-@item 0x24 N_FUN
-Function name (@pxref{Procedures}) or text segment variable
-(@pxref{Statics}).
-
-@item 0x26 N_STSYM
-Data segment file-scope variable; see @ref{Statics}.
-
-@item 0x28 N_LCSYM
-BSS segment file-scope variable; see @ref{Statics}.
-
-@item 0x2a N_MAIN
-Name of main routine; see @ref{Main Program}.
-
-@item 0x2c N_ROSYM
-Variable in @code{.rodata} section; see @ref{Statics}.
-
-@item 0x30 N_PC
-Global symbol (for Pascal); see @ref{N_PC}.
-
-@item 0x32 N_NSYMS
-Number of symbols (according to Ultrix V4.0); see @ref{N_NSYMS}.
-
-@item 0x34 N_NOMAP
-No DST map; see @ref{N_NOMAP}.
-
-@item 0x36 N_MAC_DEFINE
-Name and body of a @code{#define}d macro; see @ref{Macro define and undefine}.
-
-@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).
-
-@item 0x3a N_MAC_UNDEF
-Name of an @code{#undef}ed macro; see @ref{Macro define and undefine}.
-
-@c See include/aout/stab.def for (a little) more info.
-@item 0x3c N_OPT
-Debugger options (Solaris2).
-
-@item 0x40 N_RSYM
-Register variable; see @ref{Register Variables}.
-
-@item 0x42 N_M2C
-Modula-2 compilation unit; see @ref{N_M2C}.
-
-@item 0x44 N_SLINE
-Line number in text segment; see @ref{Line Numbers}.
-
-@item 0x46 N_DSLINE
-Line number in data segment; see @ref{Line Numbers}.
-
-@item 0x48 N_BSLINE
-Line number in bss segment; see @ref{Line Numbers}.
-
-@item 0x48 N_BROWS
-Sun source code browser, path to @file{.cb} file; see @ref{N_BROWS}.
-
-@item 0x4a N_DEFD
-GNU Modula2 definition module dependency; see @ref{N_DEFD}.
-
-@item 0x4c N_FLINE
-Function start/body/end line numbers (Solaris2).
-
-@item 0x50 N_EHDECL
-GNU C@t{++} exception variable; see @ref{N_EHDECL}.
-
-@item 0x50 N_MOD2
-Modula2 info "for imc" (according to Ultrix V4.0); see @ref{N_MOD2}.
-
-@item 0x54 N_CATCH
-GNU C@t{++} @code{catch} clause; see @ref{N_CATCH}.
-
-@item 0x60 N_SSYM
-Structure of union element; see @ref{N_SSYM}.
-
-@item 0x62 N_ENDM
-Last stab for module (Solaris2).
-
-@item 0x64 N_SO
-Path and name of source file; see @ref{Source Files}.
-
-@item 0x80 N_LSYM
-Stack variable (@pxref{Stack Variables}) or type (@pxref{Typedefs}).
-
-@item 0x82 N_BINCL
-Beginning of an include file (Sun only); see @ref{Include Files}.
-
-@item 0x84 N_SOL
-Name of include file; see @ref{Include Files}.
-
-@item 0xa0 N_PSYM
-Parameter variable; see @ref{Parameters}.
-
-@item 0xa2 N_EINCL
-End of an include file; see @ref{Include Files}.
-
-@item 0xa4 N_ENTRY
-Alternate entry point; see @ref{Alternate Entry Points}.
-
-@item 0xc0 N_LBRAC
-Beginning of a lexical block; see @ref{Block Structure}.
-
-@item 0xc2 N_EXCL
-Place holder for a deleted include file; see @ref{Include Files}.
-
-@item 0xc4 N_SCOPE
-Modula2 scope information (Sun linker); see @ref{N_SCOPE}.
-
-@item 0xe0 N_RBRAC
-End of a lexical block; see @ref{Block Structure}.
-
-@item 0xe2 N_BCOMM
-Begin named common block; see @ref{Common Blocks}.
-
-@item 0xe4 N_ECOMM
-End named common block; see @ref{Common Blocks}.
-
-@item 0xe8 N_ECOML
-Member of a common block; see @ref{Common Blocks}.
-
-@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; see @ref{Gould}.
-
-@item 0xf2 N_NBDATA
-Gould non-base registers; see @ref{Gould}.
-
-@item 0xf4 N_NBBSS
-Gould non-base registers; see @ref{Gould}.
-
-@item 0xf6 N_NBSTS
-Gould non-base registers; see @ref{Gould}.
-
-@item 0xf8 N_NBLCS
-Gould non-base registers; see @ref{Gould}.
-@end table
-
-@c Restore the default table indent
-@iftex
-@tableindent=.8in
-@end iftex
-
-@node Symbol Descriptors
-@appendix Table of Symbol Descriptors
-
-The symbol descriptor is the character which follows the colon in many
-stabs, and which tells what kind of stab it is. @xref{String Field},
-for more information about their use.
-
-@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 -
-Variable on the stack; see @ref{Stack Variables}.
-
-@item :
-C@t{++} nested symbol; see @xref{Nested Symbols}.
-
-@item a
-Parameter passed by reference in register; see @ref{Reference Parameters}.
-
-@item b
-Based variable; see @ref{Based Variables}.
-
-@item c
-Constant; see @ref{Constants}.
-
-@item C
-Conformant array bound (Pascal, maybe other languages); @ref{Conformant
-Arrays}. Name of a caught exception (GNU C@t{++}). These can be
-distinguished because the latter uses @code{N_CATCH} and the former uses
-another symbol type.
-
-@item d
-Floating point register variable; see @ref{Register Variables}.
-
-@item D
-Parameter in floating point register; see @ref{Register Parameters}.
-
-@item f
-File scope function; see @ref{Procedures}.
-
-@item F
-Global function; see @ref{Procedures}.
-
-@item G
-Global variable; see @ref{Global Variables}.
-
-@item i
-@xref{Register Parameters}.
-
-@item I
-Internal (nested) procedure; see @ref{Nested Procedures}.
-
-@item J
-Internal (nested) function; see @ref{Nested Procedures}.
-
-@item L
-Label name (documented by AIX, no further information known).
-
-@item m
-Module; see @ref{Procedures}.
-
-@item p
-Argument list parameter; see @ref{Parameters}.
-
-@item pP
-@xref{Parameters}.
-
-@item pF
-Fortran Function parameter; see @ref{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); see @ref{Procedures}. Register parameter (GNU) (symbol
-type @code{N_PSYM}); see @ref{Parameters}. Prototype of function
-referenced by this file (Sun @code{acc}) (symbol type @code{N_FUN}).
-
-@item Q
-Static Procedure; see @ref{Procedures}.
-
-@item R
-Register parameter; see @ref{Register Parameters}.
-
-@item r
-Register variable; see @ref{Register Variables}.
-
-@item S
-File scope variable; see @ref{Statics}.
-
-@item s
-Local variable (OS9000).
-
-@item t
-Type name; see @ref{Typedefs}.
-
-@item T
-Enumeration, structure, or union tag; see @ref{Typedefs}.
-
-@item v
-Parameter passed by reference; see @ref{Reference Parameters}.
-
-@item V
-Procedure scope static variable; see @ref{Statics}.
-
-@item x
-Conformant array; see @ref{Conformant Arrays}.
-
-@item X
-Function return variable; see @ref{Parameters}.
-@end table
-
-@node Type Descriptors
-@appendix Table of Type Descriptors
-
-The type descriptor is the character which follows the type number and
-an equals sign. It specifies what kind of type is being defined.
-@xref{String Field}, for more information about their use.
-
-@table @code
-@item @var{digit}
-@itemx (
-Type reference; see @ref{String Field}.
-
-@item -
-Reference to builtin type; see @ref{Negative Type Numbers}.
-
-@item #
-Method (C@t{++}); see @ref{Method Type Descriptor}.
-
-@item *
-Pointer; see @ref{Miscellaneous Types}.
-
-@item &
-Reference (C@t{++}).
-
-@item @@
-Type Attributes (AIX); see @ref{String Field}. Member (class and variable)
-type (GNU C@t{++}); see @ref{Member Type Descriptor}.
-
-@item a
-Array; see @ref{Arrays}.
-
-@item A
-Open array; see @ref{Arrays}.
-
-@item b
-Pascal space type (AIX); see @ref{Miscellaneous Types}. Builtin integer
-type (Sun); see @ref{Builtin Type Descriptors}. Const and volatile
-qualified type (OS9000).
-
-@item B
-Volatile-qualified type; see @ref{Miscellaneous Types}.
-
-@item c
-Complex builtin type (AIX); see @ref{Builtin Type Descriptors}.
-Const-qualified type (OS9000).
-
-@item C
-COBOL Picture type. See AIX documentation for details.
-
-@item d
-File type; see @ref{Miscellaneous Types}.
-
-@item D
-N-dimensional dynamic array; see @ref{Arrays}.
-
-@item e
-Enumeration type; see @ref{Enumerations}.
-
-@item E
-N-dimensional subarray; see @ref{Arrays}.
-
-@item f
-Function type; see @ref{Function Types}.
-
-@item F
-Pascal function parameter; see @ref{Function Types}
-
-@item g
-Builtin floating point type; see @ref{Builtin Type Descriptors}.
-
-@item G
-COBOL Group. See AIX documentation for details.
-
-@item i
-Imported type (AIX); see @ref{Cross-References}. Volatile-qualified
-type (OS9000).
-
-@item k
-Const-qualified type; see @ref{Miscellaneous Types}.
-
-@item K
-COBOL File Descriptor. See AIX documentation for details.
-
-@item M
-Multiple instance type; see @ref{Miscellaneous Types}.
-
-@item n
-String type; see @ref{Strings}.
-
-@item N
-Stringptr; see @ref{Strings}.
-
-@item o
-Opaque type; see @ref{Typedefs}.
-
-@item p
-Procedure; see @ref{Function Types}.
-
-@item P
-Packed array; see @ref{Arrays}.
-
-@item r
-Range type; see @ref{Subranges}.
-
-@item R
-Builtin floating type; see @ref{Builtin Type Descriptors} (Sun). Pascal
-subroutine parameter; see @ref{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; see @ref{Structures}.
-
-@item S
-Set type; see @ref{Miscellaneous Types}.
-
-@item u
-Union; see @ref{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; see @ref{Builtin Type Descriptors}.
-
-@item x
-Cross-reference; see @ref{Cross-References}.
-
-@item Y
-Used by IBM's xlC C@t{++} compiler (for structures, I think).
-
-@item z
-gstring; see @ref{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, see @ref{Stab Types}. This appendix just covers certain
-stabs which are not yet described in 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 (see @file{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.
-
-Finally, any further information.
-
-@menu
-* N_PC:: Pascal global symbol
-* N_NSYMS:: Number of symbols
-* N_NOMAP:: No DST map
-* 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_SCOPE:: Modula2 scope information (Sun only)
-* Gould:: non-base register symbols used on Gould systems
-* N_LENG:: Length of preceding entry
-@end menu
-
-@node N_PC
-@section N_PC
-
-@deffn @code{.stabs} N_PC
-@findex N_PC
-Global symbol (for Pascal).
-
-@example
-"name" -> "symbol_name" <<?>>
-value -> supposedly the line number (stab.def is skeptical)
-@end example
-
-@display
-@file{stabdump.c} says:
-
-global pascal symbol: name,,0,subtype,line
-<< subtype? >>
-@end display
-@end deffn
-
-@node N_NSYMS
-@section N_NSYMS
-
-@deffn @code{.stabn} N_NSYMS
-@findex N_NSYMS
-Number of symbols (according to Ultrix V4.0).
-
-@display
- 0, files,,funcs,lines (stab.def)
-@end display
-@end deffn
-
-@node N_NOMAP
-@section N_NOMAP
-
-@deffn @code{.stabs} N_NOMAP
-@findex N_NOMAP
-No DST map for symbol (according to Ultrix V4.0). I think this means a
-variable has been optimized out.
-
-@display
- name, ,0,type,ignored (stab.def)
-@end display
-@end deffn
-
-@node N_M2C
-@section N_M2C
-
-@deffn @code{.stabs} N_M2C
-@findex N_M2C
-Modula-2 compilation unit.
-
-@example
-"string" -> "unit_name,unit_time_stamp[,code_time_stamp]"
-desc -> unit_number
-value -> 0 (main unit)
- 1 (any other unit)
-@end example
-
-See @cite{Dbx and Dbxtool Interfaces}, 2nd edition, by Sun, 1988, for
-more information.
-
-@end deffn
-
-@node N_BROWS
-@section N_BROWS
-
-@deffn @code{.stabs} N_BROWS
-@findex N_BROWS
-Sun source code browser, path to @file{.cb} file
-
-<<?>>
-"path to associated @file{.cb} file"
-
-Note: N_BROWS has the same value as N_BSLINE.
-@end deffn
-
-@node N_DEFD
-@section N_DEFD
-
-@deffn @code{.stabn} N_DEFD
-@findex N_DEFD
-GNU Modula2 definition module dependency.
-
-GNU Modula-2 definition module dependency. The value is the
-modification time of the definition file. The other field is non-zero
-if it is imported with the GNU M2 keyword @code{%INITIALIZE}. Perhaps
-@code{N_M2C} can be used if there are enough empty fields?
-@end deffn
-
-@node N_EHDECL
-@section N_EHDECL
-
-@deffn @code{.stabs} N_EHDECL
-@findex N_EHDECL
-GNU C@t{++} exception variable <<?>>.
-
-"@var{string} is variable name"
-
-Note: conflicts with @code{N_MOD2}.
-@end deffn
-
-@node N_MOD2
-@section N_MOD2
-
-@deffn @code{.stab?} N_MOD2
-@findex N_MOD2
-Modula2 info "for imc" (according to Ultrix V4.0)
-
-Note: conflicts with @code{N_EHDECL} <<?>>
-@end deffn
-
-@node N_CATCH
-@section N_CATCH
-
-@deffn @code{.stabn} N_CATCH
-@findex N_CATCH
-GNU C@t{++} @code{catch} clause
-
-GNU C@t{++} @code{catch} clause. The value is its address. The desc field
-is nonzero if this entry is immediately followed by a @code{CAUGHT} stab
-saying what exception was caught. Multiple @code{CAUGHT} stabs means
-that multiple exceptions can be caught here. If desc is 0, it means all
-exceptions are caught here.
-@end deffn
-
-@node N_SSYM
-@section N_SSYM
-
-@deffn @code{.stabn} N_SSYM
-@findex N_SSYM
-Structure or union element.
-
-The value is the offset in the structure.
-
-<<?looking at structs and unions in C I didn't see these>>
-@end deffn
-
-@node N_SCOPE
-@section N_SCOPE
-
-@deffn @code{.stab?} N_SCOPE
-@findex N_SCOPE
-Modula2 scope information (Sun linker)
-<<?>>
-@end deffn
-
-@node Gould
-@section Non-base registers on Gould systems
-
-@deffn @code{.stab?} N_NBTEXT
-@deffnx @code{.stab?} N_NBDATA
-@deffnx @code{.stab?} N_NBBSS
-@deffnx @code{.stab?} N_NBSTS
-@deffnx @code{.stab?} N_NBLCS
-@findex N_NBTEXT
-@findex N_NBDATA
-@findex N_NBBSS
-@findex N_NBSTS
-@findex N_NBLCS
-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
-@end deffn
-
-@node N_LENG
-@section N_LENG
-
-@deffn @code{.stabn} N_LENG
-@findex N_LENG
-Second symbol entry containing a length-value for the preceding entry.
-The value is the length.
-@end deffn
-
-@node Questions
-@appendix Questions and Anomalies
-
-@itemize @bullet
-@item
-@c I think this is changed in GCC 2.4.5 to put the line number there.
-For GNU C stabs defining local and global variables (@code{N_LSYM} and
-@code{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 behavior is defined in @file{dbxout.c} and
-putting a line number in desc is controlled by @samp{#ifdef
-WINNING_GDB}, which defaults to false). GDB supposedly uses this
-information if you say @samp{list @var{var}}. In reality, @var{var} can
-be a variable defined in the program and GDB says @samp{function
-@var{var} not defined}.
-
-@item
-In GNU C stabs, there seems to be no way to differentiate tag types:
-structures, unions, and enums (symbol descriptor @samp{T}) and typedefs
-(symbol descriptor @samp{t}) defined at file scope from types defined locally
-to a procedure or other more local scope. They all use the @code{N_LSYM}
-stab type. Types defined at procedure scope are emitted after the
-@code{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 over-compensates by placing all types in block #1, the block for
-symbols of file scope. This is true for default, @samp{-ansi} and
-@samp{-traditional} compiler options. (Bugs gcc/1063, gdb/1066.)
-
-@item
-What ends the procedure scope? Is it the proc block's @code{N_RBRAC} or the
-next @code{N_FUN}? (I believe it's the first.)
-@end itemize
-
-@node Stab Sections
-@appendix Using Stabs in Their Own Sections
-
-Many object file formats allow tools to create object files with custom
-sections containing any arbitrary data. For any such object file
-format, stabs can be embedded in special sections. This is how stabs
-are used with ELF and SOM, and aside from ECOFF and XCOFF, is how stabs
-are used with COFF.
-
-@menu
-* Stab Section Basics:: How to embed stabs in sections
-* ELF Linker Relocation:: Sun ELF hacks
-@end menu
-
-@node Stab Section Basics
-@appendixsec How to Embed Stabs in Sections
-
-The assembler creates two custom sections, a section named @code{.stab}
-which contains an array of fixed length structures, one struct per stab,
-and a section named @code{.stabstr} containing all the variable length
-strings that are referenced by stabs in the @code{.stab} section. The
-byte order of the stabs binary data depends on the object file format.
-For ELF, it matches the byte order of the ELF file itself, as determined
-from the @code{EI_DATA} field in the @code{e_ident} member of the ELF
-header. For SOM, it is always big-endian (is this true??? FIXME). For
-COFF, it matches the byte order of the COFF headers. The meaning of the
-fields is the same as for a.out (@pxref{Symbol Table Format}), except
-that the @code{n_strx} field is relative to the strings for the current
-compilation unit (which can be found using the synthetic N_UNDF stab
-described below), rather than the entire string table.
-
-The first stab in the @code{.stab} section for each compilation unit is
-synthetic, generated entirely by the assembler, with no corresponding
-@code{.stab} directive as input to the assembler. This stab contains
-the following fields:
-
-@table @code
-@item n_strx
-Offset in the @code{.stabstr} section to the source filename.
-
-@item n_type
-@code{N_UNDF}.
-
-@item n_other
-Unused field, always zero.
-This may eventually be used to hold overflows from the count in
-the @code{n_desc} field.
-
-@item n_desc
-Count of upcoming symbols, i.e., the number of remaining stabs for this
-source file.
-
-@item n_value
-Size of the string table fragment associated with this source file, in
-bytes.
-@end table
-
-The @code{.stabstr} section always starts with a null byte (so that string
-offsets of zero reference a null string), followed by random length strings,
-each of which is null byte terminated.
-
-The ELF section header for the @code{.stab} section has its
-@code{sh_link} member set to the section number of the @code{.stabstr}
-section, and the @code{.stabstr} section has its ELF section
-header @code{sh_type} member set to @code{SHT_STRTAB} to mark it as a
-string table. SOM and COFF have no way of linking the sections together
-or marking them as string tables.
-
-For COFF, the @code{.stab} and @code{.stabstr} sections may be simply
-concatenated by the linker. GDB then uses the @code{n_desc} fields to
-figure out the extent of the original sections. Similarly, the
-@code{n_value} fields of the header symbols are added together in order
-to get the actual position of the strings in a desired @code{.stabstr}
-section. Although this design obviates any need for the linker to
-relocate or otherwise manipulate @code{.stab} and @code{.stabstr}
-sections, it also requires some care to ensure that the offsets are
-calculated correctly. For instance, if the linker were to pad in
-between the @code{.stabstr} sections before concatenating, then the
-offsets to strings in the middle of the executable's @code{.stabstr}
-section would be wrong.
-
-The GNU linker is able to optimize stabs information by merging
-duplicate strings and removing duplicate header file information
-(@pxref{Include Files}). When some versions of the GNU linker optimize
-stabs in sections, they remove the leading @code{N_UNDF} symbol and
-arranges for all the @code{n_strx} fields to be relative to the start of
-the @code{.stabstr} section.
-
-@node ELF Linker Relocation
-@appendixsec Having the Linker Relocate Stabs in ELF
-
-This section describes some Sun hacks for Stabs in ELF; it does not
-apply to COFF or SOM. While @value{GDBN} no longer supports this hack
-for Sun Stabs in ELF, this section is kept to document the issue.
-
-To keep linking fast, you don't want the linker to have to relocate very
-many stabs. Making sure this is done for @code{N_SLINE},
-@code{N_RBRAC}, and @code{N_LBRAC} stabs is the most important thing
-(see the descriptions of those stabs for more information). But Sun's
-stabs in ELF has taken this further, to make all addresses in the
-@code{n_value} field (functions and static variables) relative to the
-source file. For the @code{N_SO} symbol itself, Sun simply omits the
-address. To find the address of each section corresponding to a given
-source file, the compiler puts out symbols giving the address of each
-section for a given source file. Since these are ELF (not stab)
-symbols, the linker relocates them correctly without having to touch the
-stabs section. They are named @code{Bbss.bss} for the bss section,
-@code{Ddata.data} for the data section, and @code{Drodata.rodata} for
-the rodata section. For the text section, there is no such symbol (but
-there should be, see below). For an example of how these symbols work,
-@xref{Stab Section Transformations}. GCC does not provide these symbols;
-it instead relies on the stabs getting relocated. Thus addresses which
-would normally be relative to @code{Bbss.bss}, etc., are already
-relocated. The Sun linker provided with Solaris 2.2 and earlier
-relocates stabs using normal ELF relocation information, as it would do
-for any section. Sun has been threatening to kludge their linker to not
-do this (to speed up linking), even though the correct way to avoid
-having the linker do these relocations is to have the compiler no longer
-output relocatable values. Last I heard they had been talked out of the
-linker kludge. See Sun point patch 101052-01 and Sun bug 1142109. With
-the Sun compiler this affects @samp{S} symbol descriptor stabs
-(@pxref{Statics}) and functions (@pxref{Procedures}). In the latter
-case, to adopt the clean solution (making the value of the stab relative
-to the start of the compilation unit), it would be necessary to invent a
-@code{Ttext.text} symbol, analogous to the @code{Bbss.bss}, etc.,
-symbols. I recommend this rather than using a zero value and getting
-the address from the ELF symbols.
-
-Finding the correct @code{Bbss.bss}, etc., symbol is difficult, because
-the linker simply concatenates the @code{.stab} sections from each
-@file{.o} file without including any information about which part of a
-@code{.stab} section comes from which @file{.o} file. The way GDB use to
-do this is to look for an ELF @code{STT_FILE} symbol which has the same
-name as the last component of the file name from the @code{N_SO} symbol
-in the stabs (for example, if the file name is @file{../../gdb/main.c},
-it looks for an ELF @code{STT_FILE} symbol named @code{main.c}). This
-loses if different files have the same name (they could be in different
-directories, a library could have been copied from one system to
-another, etc.). It would be much cleaner to have the @code{Bbss.bss}
-symbols in the stabs themselves. Having the linker relocate them there
-is no more work than having the linker relocate ELF symbols, and it
-solves the problem of having to associate the ELF and stab symbols.
-However, no one has yet designed or implemented such a scheme.
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@include fdl.texi
-
-@node Symbol Types Index
-@unnumbered Symbol Types Index
-
-@printindex fn
-
-@bye
gdbarch_unwind_sp_ftype *unwind_sp = default_unwind_sp;
gdbarch_frame_num_args_ftype *frame_num_args = nullptr;
gdbarch_frame_align_ftype *frame_align = nullptr;
- gdbarch_stabs_argument_has_addr_ftype *stabs_argument_has_addr = default_stabs_argument_has_addr;
int frame_red_zone_size = 0;
gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
gdbarch_addr_bits_remove_ftype *addr_bits_remove = core_addr_identity;
/* Skip verify of unwind_sp, invalid_p == 0. */
/* Skip verify of frame_num_args, has predicate. */
/* Skip verify of frame_align, has predicate. */
- /* Skip verify of stabs_argument_has_addr, invalid_p == 0. */
/* Skip verify of frame_red_zone_size, invalid_p == 0. */
/* Skip verify of convert_from_func_ptr_addr, invalid_p == 0. */
/* Skip verify of addr_bits_remove, invalid_p == 0. */
gdb_printf (file,
"gdbarch_dump: frame_align = <%s>\n",
host_address_to_string (gdbarch->frame_align));
- gdb_printf (file,
- "gdbarch_dump: stabs_argument_has_addr = <%s>\n",
- host_address_to_string (gdbarch->stabs_argument_has_addr));
gdb_printf (file,
"gdbarch_dump: frame_red_zone_size = %s\n",
plongest (gdbarch->frame_red_zone_size));
gdbarch->frame_align = frame_align;
}
-int
-gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
- gdb_assert (gdbarch != NULL);
- gdb_assert (gdbarch->stabs_argument_has_addr != NULL);
- if (gdbarch_debug >= 2)
- gdb_printf (gdb_stdlog, "gdbarch_stabs_argument_has_addr called\n");
- return gdbarch->stabs_argument_has_addr (gdbarch, type);
-}
-
-void
-set_gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch,
- gdbarch_stabs_argument_has_addr_ftype stabs_argument_has_addr)
-{
- gdbarch->stabs_argument_has_addr = stabs_argument_has_addr;
-}
-
int
gdbarch_frame_red_zone_size (struct gdbarch *gdbarch)
{
extern CORE_ADDR gdbarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR address);
extern void set_gdbarch_frame_align (struct gdbarch *gdbarch, gdbarch_frame_align_ftype *frame_align);
-typedef int (gdbarch_stabs_argument_has_addr_ftype) (struct gdbarch *gdbarch, struct type *type);
-extern int gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type);
-extern void set_gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, gdbarch_stabs_argument_has_addr_ftype *stabs_argument_has_addr);
-
extern int gdbarch_frame_red_zone_size (struct gdbarch *gdbarch);
extern void set_gdbarch_frame_red_zone_size (struct gdbarch *gdbarch, int frame_red_zone_size);
predicate=True,
)
-Method(
- type="int",
- name="stabs_argument_has_addr",
- params=[("struct type *", "type")],
- predefault="default_stabs_argument_has_addr",
- invalid=False,
-)
-
Value(
type="int",
name="frame_red_zone_size",
return RETURN_VALUE_REGISTER_CONVENTION;
}
-static int
-microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
- return (type->length () == 16);
-}
-
/* Return next pc values : next in sequence and/or branch/return target. */
static std::vector<CORE_ADDR>
set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
set_gdbarch_return_value (gdbarch, microblaze_return_value);
- set_gdbarch_stabs_argument_has_addr
- (gdbarch, microblaze_stabs_argument_has_addr);
set_gdbarch_skip_prologue (gdbarch, microblaze_skip_prologue);
/* Number of full symbols read. */
int n_syms = 0;
- /* Number of ".stabs" read (if applicable). */
- int n_stabs = 0;
-
/* Number of types. */
int n_types = 0;
return RETURN_VALUE_REGISTER_CONVENTION;
}
-static int
-sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
- return (sparc_structure_or_union_p (type)
- || (sparc_floating_p (type) && type->length () == 16)
- || sparc_complex_floating_p (type));
-}
-
static int
sparc32_dwarf2_struct_return_p (const frame_info_ptr &this_frame)
{
set_gdbarch_push_dummy_call (gdbarch, sparc32_push_dummy_call);
set_gdbarch_return_value_as_value (gdbarch, sparc32_return_value);
- set_gdbarch_stabs_argument_has_addr
- (gdbarch, sparc32_stabs_argument_has_addr);
set_gdbarch_skip_prologue (gdbarch, sparc32_skip_prologue);
set_gdbarch_return_value (gdbarch, sparc64_return_value);
set_gdbarch_return_value_as_value (gdbarch, default_gdbarch_return_value);
- set_gdbarch_stabs_argument_has_addr
- (gdbarch, default_stabs_argument_has_addr);
set_gdbarch_skip_prologue (gdbarch, sparc64_skip_prologue);
set_gdbarch_stack_frame_destroyed_p (gdbarch, sparc_stack_frame_destroyed_p);
+++ /dev/null
-/* Support routines for decoding "stabs" debugging information format.
-
- Copyright (C) 1986-2025 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Support routines for reading and decoding debugging information in
- the "stabs" format. This format is used by some systems that use
- COFF or ELF where the stabs data is placed in a special section (as
- well as with many old systems that used the a.out object file
- format). Avoid placing any object file format specific code in
- this file. */
-
-#include "bfd.h"
-#include "event-top.h"
-#include "gdbsupport/gdb_obstack.h"
-#include "symtab.h"
-#include "gdbtypes.h"
-#include "expression.h"
-#include "symfile.h"
-#include "objfiles.h"
-#include "aout/stab_gnu.h"
-#include "psymtab.h"
-#include "libaout.h"
-#include "aout/aout64.h"
-#include "gdb-stabs.h"
-#include "buildsym-legacy.h"
-#include "complaints.h"
-#include "demangle.h"
-#include "gdb-demangle.h"
-#include "language.h"
-#include "target-float.h"
-#include "c-lang.h"
-#include "cp-abi.h"
-#include "cp-support.h"
-#include "block.h"
-#include "filenames.h"
-
-#include "stabsread.h"
-
-/* See stabsread.h for these globals. */
-unsigned int symnum;
-const char *(*next_symbol_text_func) (struct objfile *);
-unsigned char processing_gcc_compilation;
-int within_function;
-struct symbol *global_sym_chain[HASHSIZE];
-struct pending_stabs *global_stabs;
-int previous_stab_code;
-int *this_object_header_files;
-int n_this_object_header_files;
-int n_allocated_this_object_header_files;
-
-/* See stabsread.h. */
-
-const registry<objfile>::key<dbx_symfile_info> dbx_objfile_data_key;
-
-dbx_symfile_info::~dbx_symfile_info ()
-{
- if (header_files != NULL)
- {
- int i = n_header_files;
- struct header_file *hfiles = header_files;
-
- while (--i >= 0)
- {
- xfree (hfiles[i].name);
- xfree (hfiles[i].vector);
- }
- xfree (hfiles);
- }
-}
-
-struct stabs_nextfield
-{
- struct stabs_nextfield *next;
-
- struct field field;
-};
-
-struct next_fnfieldlist
-{
- struct next_fnfieldlist *next;
- struct fn_fieldlist fn_fieldlist;
-};
-
-/* The routines that read and process a complete stabs for a C struct or
- C++ class pass lists of data member fields and lists of member function
- fields in an instance of a field_info structure, as defined below.
- This is part of some reorganization of low level C++ support and is
- expected to eventually go away... (FIXME) */
-
-struct stab_field_info
- {
- struct stabs_nextfield *list = nullptr;
- struct next_fnfieldlist *fnlist = nullptr;
-
- auto_obstack obstack;
- };
-
-static void
-read_one_struct_field (struct stab_field_info *, const char **, const char *,
- struct type *, struct objfile *);
-
-static struct type *dbx_alloc_type (int[2], struct objfile *);
-
-static long read_huge_number (const char **, int, int *, int);
-
-static struct type *error_type (const char **, struct objfile *);
-
-static void
-patch_block_stabs (struct pending *, struct pending_stabs *,
- struct objfile *);
-
-static int read_type_number (const char **, int *);
-
-static struct type *read_type (const char **, struct objfile *);
-
-static struct type *read_range_type (const char **, int[2],
- int, struct objfile *);
-
-static struct type *read_sun_builtin_type (const char **,
- int[2], struct objfile *);
-
-static struct type *read_sun_floating_type (const char **, int[2],
- struct objfile *);
-
-static struct type *read_enum_type (const char **, struct type *, struct objfile *);
-
-static struct type *rs6000_builtin_type (int, struct objfile *);
-
-static int
-read_member_functions (struct stab_field_info *, const char **, struct type *,
- struct objfile *);
-
-static int
-read_struct_fields (struct stab_field_info *, const char **, struct type *,
- struct objfile *);
-
-static int
-read_baseclasses (struct stab_field_info *, const char **, struct type *,
- struct objfile *);
-
-static int
-read_tilde_fields (struct stab_field_info *, const char **, struct type *,
- struct objfile *);
-
-static int attach_fn_fields_to_type (struct stab_field_info *, struct type *);
-
-static int attach_fields_to_type (struct stab_field_info *, struct type *,
- struct objfile *);
-
-static struct type *read_struct_type (const char **, struct type *,
- enum type_code,
- struct objfile *);
-
-static struct type *read_array_type (const char **, struct type *,
- struct objfile *);
-
-static struct field *read_args (const char **, int, struct objfile *,
- int *, int *);
-
-static void add_undefined_type (struct type *, int[2]);
-
-static int
-read_cpp_abbrev (struct stab_field_info *, const char **, struct type *,
- struct objfile *);
-
-static const char *find_name_end (const char *name);
-
-static int process_reference (const char **string);
-
-void stabsread_clear_cache (void);
-
-static const char vptr_name[] = "_vptr$";
-static const char vb_name[] = "_vb$";
-
-void
-unknown_symtype_complaint (const char *arg1)
-{
- complaint (_("unknown symbol type %s"), arg1);
-}
-
-void
-lbrac_mismatch_complaint (int arg1)
-{
- complaint (_("N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d"), arg1);
-}
-
-void
-repeated_header_complaint (const char *arg1, int arg2)
-{
- complaint (_("\"repeated\" header file %s not "
- "previously seen, at symtab pos %d"),
- arg1, arg2);
-}
-
-static void
-invalid_cpp_abbrev_complaint (const char *arg1)
-{
- complaint (_("invalid C++ abbreviation `%s'"), arg1);
-}
-
-static void
-reg_value_complaint (int regnum, int num_regs, const char *sym)
-{
- complaint (_("bad register number %d (max %d) in symbol %s"),
- regnum, num_regs - 1, sym);
-}
-
-static void
-stabs_general_complaint (const char *arg1)
-{
- complaint ("%s", arg1);
-}
-
-static void
-function_outside_compilation_unit_complaint (const char *arg1)
-{
- complaint (_("function `%s' appears to be defined "
- "outside of all compilation units"),
- arg1);
-}
-
-/* Make a list of forward references which haven't been defined. */
-
-static struct type **undef_types;
-static int undef_types_allocated;
-static int undef_types_length;
-static struct symbol *current_symbol = NULL;
-
-/* Make a list of nameless types that are undefined.
- This happens when another type is referenced by its number
- before this type is actually defined. For instance "t(0,1)=k(0,2)"
- and type (0,2) is defined only later. */
-
-struct nat
-{
- int typenums[2];
- struct type *type;
-};
-static struct nat *noname_undefs;
-static int noname_undefs_allocated;
-static int noname_undefs_length;
-
-/* Check for and handle cretinous stabs symbol name continuation! */
-#define STABS_CONTINUE(pp,objfile) \
- do { \
- if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \
- *(pp) = next_symbol_text (objfile); \
- } while (0)
-
-/* Vector of types defined so far, indexed by their type numbers.
- (In newer sun systems, dbx uses a pair of numbers in parens,
- as in "(SUBFILENUM,NUMWITHINSUBFILE)".
- Then these numbers must be translated through the type_translations
- hash table to get the index into the type vector.) */
-
-static struct type **type_vector;
-
-/* Number of elements allocated for type_vector currently. */
-
-static int type_vector_length;
-
-/* Initial size of type vector. Is realloc'd larger if needed, and
- realloc'd down to the size actually used, when completed. */
-
-#define INITIAL_TYPE_VECTOR_LENGTH 160
-\f
-
-/* Look up a dbx type-number pair. Return the address of the slot
- where the type for that number-pair is stored.
- The number-pair is in TYPENUMS.
-
- This can be used for finding the type associated with that pair
- or for associating a new type with the pair. */
-
-static struct type **
-dbx_lookup_type (int typenums[2], struct objfile *objfile)
-{
- int filenum = typenums[0];
- int index = typenums[1];
- unsigned old_len;
- int real_filenum;
- struct header_file *f;
- int f_orig_length;
-
- if (filenum == -1) /* -1,-1 is for temporary types. */
- return 0;
-
- if (filenum < 0 || filenum >= n_this_object_header_files)
- {
- complaint (_("Invalid symbol data: type number "
- "(%d,%d) out of range at symtab pos %d."),
- filenum, index, symnum);
- goto error_return;
- }
-
- if (filenum == 0)
- {
- if (index < 0)
- {
- /* Caller wants address of address of type. We think
- that negative (rs6k builtin) types will never appear as
- "lvalues", (nor should they), so we stuff the real type
- pointer into a temp, and return its address. If referenced,
- this will do the right thing. */
- static struct type *temp_type;
-
- temp_type = rs6000_builtin_type (index, objfile);
- return &temp_type;
- }
-
- /* Type is defined outside of header files.
- Find it in this object file's type vector. */
- if (index >= type_vector_length)
- {
- old_len = type_vector_length;
- if (old_len == 0)
- {
- type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;
- type_vector = XNEWVEC (struct type *, type_vector_length);
- }
- while (index >= type_vector_length)
- {
- type_vector_length *= 2;
- }
- type_vector = (struct type **)
- xrealloc ((char *) type_vector,
- (type_vector_length * sizeof (struct type *)));
- memset (&type_vector[old_len], 0,
- (type_vector_length - old_len) * sizeof (struct type *));
- }
- return (&type_vector[index]);
- }
- else
- {
- real_filenum = this_object_header_files[filenum];
-
- if (real_filenum >= N_HEADER_FILES (objfile))
- {
- static struct type *temp_type;
-
- warning (_("GDB internal error: bad real_filenum"));
-
- error_return:
- temp_type = builtin_type (objfile)->builtin_error;
- return &temp_type;
- }
-
- f = HEADER_FILES (objfile) + real_filenum;
-
- f_orig_length = f->length;
- if (index >= f_orig_length)
- {
- while (index >= f->length)
- {
- f->length *= 2;
- }
- f->vector = (struct type **)
- xrealloc ((char *) f->vector, f->length * sizeof (struct type *));
- memset (&f->vector[f_orig_length], 0,
- (f->length - f_orig_length) * sizeof (struct type *));
- }
- return (&f->vector[index]);
- }
-}
-
-/* Make sure there is a type allocated for type numbers TYPENUMS
- and return the type object.
- This can create an empty (zeroed) type object.
- TYPENUMS may be (-1, -1) to return a new type object that is not
- put into the type vector, and so may not be referred to by number. */
-
-static struct type *
-dbx_alloc_type (int typenums[2], struct objfile *objfile)
-{
- struct type **type_addr;
-
- if (typenums[0] == -1)
- {
- return type_allocator (objfile,
- get_current_subfile ()->language).new_type ();
- }
-
- type_addr = dbx_lookup_type (typenums, objfile);
-
- /* If we are referring to a type not known at all yet,
- allocate an empty type for it.
- We will fill it in later if we find out how. */
- if (*type_addr == 0)
- {
- *type_addr = type_allocator (objfile,
- get_current_subfile ()->language).new_type ();
- }
-
- return (*type_addr);
-}
-
-/* Allocate a floating-point type of size BITS. */
-
-static struct type *
-dbx_init_float_type (struct objfile *objfile, int bits)
-{
- struct gdbarch *gdbarch = objfile->arch ();
- const struct floatformat **format;
- struct type *type;
-
- format = gdbarch_floatformat_for_type (gdbarch, NULL, bits);
- type_allocator alloc (objfile, get_current_subfile ()->language);
- if (format)
- type = init_float_type (alloc, bits, NULL, format);
- else
- type = alloc.new_type (TYPE_CODE_ERROR, bits, NULL);
-
- return type;
-}
-
-/* for all the stabs in a given stab vector, build appropriate types
- and fix their symbols in given symbol vector. */
-
-static void
-patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs,
- struct objfile *objfile)
-{
- int ii;
- char *name;
- const char *pp;
- struct symbol *sym;
-
- if (stabs)
- {
- /* for all the stab entries, find their corresponding symbols and
- patch their types! */
-
- for (ii = 0; ii < stabs->count; ++ii)
- {
- name = stabs->stab[ii];
- pp = (char *) strchr (name, ':');
- gdb_assert (pp); /* Must find a ':' or game's over. */
- while (pp[1] == ':')
- {
- pp += 2;
- pp = (char *) strchr (pp, ':');
- }
- sym = find_symbol_in_list (symbols, name, pp - name);
- if (!sym)
- {
- /* FIXME-maybe: it would be nice if we noticed whether
- the variable was defined *anywhere*, not just whether
- it is defined in this compilation unit. But neither
- xlc or GCC seem to need such a definition, and until
- we do psymtabs (so that the minimal symbols from all
- compilation units are available now), I'm not sure
- how to get the information. */
-
- /* On xcoff, if a global is defined and never referenced,
- ld will remove it from the executable. There is then
- a N_GSYM stab for it, but no regular (C_EXT) symbol. */
- sym = new (&objfile->objfile_obstack) symbol;
- sym->set_domain (VAR_DOMAIN);
- sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
- sym->set_linkage_name
- (obstack_strndup (&objfile->objfile_obstack, name, pp - name));
- pp += 2;
- if (*(pp - 1) == 'F' || *(pp - 1) == 'f')
- {
- /* I don't think the linker does this with functions,
- so as far as I know this is never executed.
- But it doesn't hurt to check. */
- sym->set_type
- (lookup_function_type (read_type (&pp, objfile)));
- }
- else
- {
- sym->set_type (read_type (&pp, objfile));
- }
- add_symbol_to_list (sym, get_global_symbols ());
- }
- else
- {
- pp += 2;
- if (*(pp - 1) == 'F' || *(pp - 1) == 'f')
- {
- sym->set_type
- (lookup_function_type (read_type (&pp, objfile)));
- }
- else
- {
- sym->set_type (read_type (&pp, objfile));
- }
- }
- }
- }
-}
-\f
-
-/* Read a number by which a type is referred to in dbx data,
- or perhaps read a pair (FILENUM, TYPENUM) in parentheses.
- Just a single number N is equivalent to (0,N).
- Return the two numbers by storing them in the vector TYPENUMS.
- TYPENUMS will then be used as an argument to dbx_lookup_type.
-
- Returns 0 for success, -1 for error. */
-
-static int
-read_type_number (const char **pp, int *typenums)
-{
- int nbits;
-
- if (**pp == '(')
- {
- (*pp)++;
- typenums[0] = read_huge_number (pp, ',', &nbits, 0);
- if (nbits != 0)
- return -1;
- typenums[1] = read_huge_number (pp, ')', &nbits, 0);
- if (nbits != 0)
- return -1;
- }
- else
- {
- typenums[0] = 0;
- typenums[1] = read_huge_number (pp, 0, &nbits, 0);
- if (nbits != 0)
- return -1;
- }
- return 0;
-}
-\f
-
-/* Free up old header file tables. */
-
-void
-free_header_files (void)
-{
- if (this_object_header_files)
- {
- xfree (this_object_header_files);
- this_object_header_files = NULL;
- }
- n_allocated_this_object_header_files = 0;
-}
-
-/* Allocate new header file tables. */
-
-void
-init_header_files (void)
-{
- n_allocated_this_object_header_files = 10;
- this_object_header_files = XNEWVEC (int, 10);
-}
-
-/* Close off the current usage of PST.
- Returns PST or NULL if the partial symtab was empty and thrown away.
-
- FIXME: List variables and peculiarities of same. */
-
-legacy_psymtab *
-stabs_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs,
- legacy_psymtab *pst,
- const char **include_list, int num_includes,
- int capping_symbol_offset, unrelocated_addr capping_text,
- legacy_psymtab **dependency_list,
- int number_dependencies,
- int textlow_not_set)
-{
- int i;
- struct gdbarch *gdbarch = objfile->arch ();
- dbx_symfile_info *key = dbx_objfile_data_key. get (objfile);
-
- if (capping_symbol_offset != -1)
- LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
- pst->set_text_high (capping_text);
-
- /* Under Solaris, the N_SO symbols always have a value of 0,
- instead of the usual address of the .o file. Therefore,
- we have to do some tricks to fill in texthigh and textlow.
- The first trick is: if we see a static
- or global function, and the textlow for the current pst
- is not set (ie: textlow_not_set), then we use that function's
- address for the textlow of the pst. */
-
- /* Now, to fill in texthigh, we remember the last function seen
- in the .o file. Also, there's a hack in
- bfd/elf.c and gdb/elfread.c to pass the ELF st_size field
- to here via the misc_info field. Therefore, we can fill in
- a reliable texthigh by taking the address plus size of the
- last function in the file. */
-
- if (!pst->text_high_valid && key->ctx.last_function_name
- && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- int n;
-
- const char *colon = strchr (key->ctx.last_function_name, ':');
- if (colon == NULL)
- n = 0;
- else
- n = colon - key->ctx.last_function_name;
- char *p = (char *) alloca (n + 2);
- strncpy (p, key->ctx.last_function_name, n);
- p[n] = 0;
-
- bound_minimal_symbol minsym
- = lookup_minimal_symbol (current_program_space, p, objfile,
- pst->filename);
- if (minsym.minsym == NULL)
- {
- /* Sun Fortran appends an underscore to the minimal symbol name,
- try again with an appended underscore if the minimal symbol
- was not found. */
- p[n] = '_';
- p[n + 1] = 0;
- minsym = lookup_minimal_symbol (current_program_space, p, objfile,
- pst->filename);
- }
-
- if (minsym.minsym)
- pst->set_text_high
- (unrelocated_addr (CORE_ADDR (minsym.minsym->unrelocated_address ())
- + minsym.minsym->size ()));
-
- key->ctx.last_function_name = NULL;
- }
-
- if (!gdbarch_sofun_address_maybe_missing (gdbarch))
- ;
- /* This test will be true if the last .o file is only data. */
- else if (textlow_not_set)
- pst->set_text_low (pst->unrelocated_text_high ());
- else
- {
- /* If we know our own starting text address, then walk through all other
- psymtabs for this objfile, and if any didn't know their ending text
- address, set it to our starting address. Take care to not set our
- own ending address to our starting address. */
-
- for (partial_symtab *p1 : partial_symtabs->range ())
- if (!p1->text_high_valid && p1->text_low_valid && p1 != pst)
- p1->set_text_high (pst->unrelocated_text_low ());
- }
-
- /* End of kludge for patching Solaris textlow and texthigh. */
-
- pst->end ();
-
- pst->number_of_dependencies = number_dependencies;
- if (number_dependencies)
- {
- pst->dependencies
- = partial_symtabs->allocate_dependencies (number_dependencies);
- memcpy (pst->dependencies, dependency_list,
- number_dependencies * sizeof (legacy_psymtab *));
- }
- else
- pst->dependencies = 0;
-
- for (i = 0; i < num_includes; i++)
- {
- legacy_psymtab *subpst =
- new legacy_psymtab (include_list[i], partial_symtabs, objfile->per_bfd);
-
- subpst->read_symtab_private =
- XOBNEW (&objfile->objfile_obstack, struct symloc);
- LDSYMOFF (subpst) =
- LDSYMLEN (subpst) = 0;
-
- /* We could save slight bits of space by only making one of these,
- shared by the entire set of include files. FIXME-someday. */
- subpst->dependencies =
- partial_symtabs->allocate_dependencies (1);
- subpst->dependencies[0] = pst;
- subpst->number_of_dependencies = 1;
-
- subpst->legacy_read_symtab = pst->legacy_read_symtab;
- subpst->legacy_expand_psymtab = pst->legacy_expand_psymtab;
- }
-
- if (num_includes == 0
- && number_dependencies == 0
- && pst->empty ()
- && key->ctx.has_line_numbers == 0)
- {
- /* Throw away this psymtab, it's empty. */
- /* Empty psymtabs happen as a result of header files which don't have
- any symbols in them. There can be a lot of them. But this check
- is wrong, in that a psymtab with N_SLINE entries but nothing else
- is not empty, but we don't realize that. Fixing that without slowing
- things down might be tricky. */
-
- partial_symtabs->discard_psymtab (pst);
-
- /* Indicate that psymtab was thrown away. */
- pst = NULL;
- }
- return pst;
-}
-
-/* Set namestring based on nlist. If the string table index is invalid,
- give a fake name, and print a single error message per symbol file read,
- rather than abort the symbol reading or flood the user with messages. */
-
-static const char *
-set_namestring (struct objfile *objfile, const struct internal_nlist *nlist)
-{
- const char *namestring;
- struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- if (nlist->n_strx + key->ctx.file_string_table_offset
- >= DBX_STRINGTAB_SIZE (objfile)
- || nlist->n_strx + key->ctx.file_string_table_offset < nlist->n_strx)
- {
- complaint (_("bad string table offset in symbol %d"),
- symnum);
- namestring = "<bad string table offset>";
- }
- else
- namestring = (nlist->n_strx + key->ctx.file_string_table_offset
- + DBX_STRINGTAB (objfile));
- return namestring;
-}
-
-static void
-stabs_seek (int sym_offset, struct objfile *objfile)
-{
- dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
- if (key->ctx.stabs_data)
- {
- key->ctx.symbuf_read += sym_offset;
- key->ctx.symbuf_left -= sym_offset;
- }
- else
- if (bfd_seek (objfile->obfd.get (), sym_offset, SEEK_CUR) != 0)
- perror_with_name (bfd_get_filename (objfile->obfd.get ()));
-}
-
-/* Buffer for reading the symbol table entries. */
-static struct external_nlist symbuf[4096];
-static int symbuf_idx;
-static int symbuf_end;
-
-/* Refill the symbol table input buffer
- and set the variables that control fetching entries from it.
- Reports an error if no data available.
- This function can read past the end of the symbol table
- (into the string table) but this does no harm. */
-
-static void
-fill_symbuf (bfd *sym_bfd, struct objfile *objfile)
-{
- unsigned int count;
- int nbytes;
- struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- if (key->ctx.stabs_data)
- {
- nbytes = sizeof (symbuf);
- if (nbytes > key->ctx.symbuf_left)
- nbytes = key->ctx.symbuf_left;
- memcpy (symbuf, key->ctx.stabs_data + key->ctx.symbuf_read, nbytes);
- }
- else if (key->ctx.symbuf_sections == NULL)
- {
- count = sizeof (symbuf);
- nbytes = bfd_read (symbuf, count, sym_bfd);
- }
- else
- {
- if (key->ctx.symbuf_left <= 0)
- {
- file_ptr filepos = (*key->ctx.symbuf_sections)[key->ctx.sect_idx]->filepos;
-
- if (bfd_seek (sym_bfd, filepos, SEEK_SET) != 0)
- perror_with_name (bfd_get_filename (sym_bfd));
- key->ctx.symbuf_left = bfd_section_size ((*key->ctx.symbuf_sections)[key->ctx.sect_idx]);
- key->ctx.symbol_table_offset = filepos - key->ctx.symbuf_read;
- ++key->ctx.sect_idx;
- }
-
- count = key->ctx.symbuf_left;
- if (count > sizeof (symbuf))
- count = sizeof (symbuf);
- nbytes = bfd_read (symbuf, count, sym_bfd);
- }
-
- if (nbytes < 0)
- perror_with_name (bfd_get_filename (sym_bfd));
- else if (nbytes == 0)
- error (_("Premature end of file reading symbol table"));
- symbuf_end = nbytes / key->ctx.symbol_size;
- symbuf_idx = 0;
- key->ctx.symbuf_left -= nbytes;
- key->ctx.symbuf_read += nbytes;
-}
-
-/* Read in a defined section of a specific object file's symbols. */
-
-static void
-read_ofile_symtab (struct objfile *objfile, legacy_psymtab *pst)
-{
- const char *namestring;
- struct external_nlist *bufp;
- struct internal_nlist nlist;
- unsigned char type;
- unsigned max_symnum;
- bfd *abfd;
- int sym_offset; /* Offset to start of symbols to read */
- int sym_size; /* Size of symbols to read */
- CORE_ADDR text_offset; /* Start of text segment for symbols */
- int text_size; /* Size of text segment for symbols */
- struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- sym_offset = LDSYMOFF (pst);
- sym_size = LDSYMLEN (pst);
- text_offset = pst->text_low (objfile);
- text_size = pst->text_high (objfile) - pst->text_low (objfile);
- const section_offsets §ion_offsets = objfile->section_offsets;
-
- key->ctx.stringtab_global = DBX_STRINGTAB (objfile);
- set_last_source_file (NULL);
-
- abfd = objfile->obfd.get ();
- symbuf_end = symbuf_idx = 0;
- key->ctx.symbuf_read = 0;
- key->ctx.symbuf_left = sym_offset + sym_size;
-
- /* It is necessary to actually read one symbol *before* the start
- of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL
- occurs before the N_SO symbol.
-
- Detecting this in read_stabs_symtab
- would slow down initial readin, so we look for it here instead. */
- if (!key->ctx.processing_acc_compilation && sym_offset >= (int) key->ctx.symbol_size)
- {
- stabs_seek (sym_offset - key->ctx.symbol_size, objfile);
- fill_symbuf (abfd, objfile);
- bufp = &symbuf[symbuf_idx++];
- INTERNALIZE_SYMBOL (nlist, bufp, abfd);
- OBJSTAT (objfile, n_stabs++);
-
- namestring = set_namestring (objfile, &nlist);
-
- processing_gcc_compilation = 0;
- if (nlist.n_type == N_TEXT)
- {
- const char *tempstring = namestring;
-
- if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0)
- processing_gcc_compilation = 1;
- else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0)
- processing_gcc_compilation = 2;
- if (*tempstring != '\0'
- && *tempstring == bfd_get_symbol_leading_char (objfile->obfd.get ()))
- ++tempstring;
- if (startswith (tempstring, "__gnu_compiled"))
- processing_gcc_compilation = 2;
- }
- }
- else
- {
- /* The N_SO starting this symtab is the first symbol, so we
- better not check the symbol before it. I'm not this can
- happen, but it doesn't hurt to check for it. */
- stabs_seek (sym_offset, objfile);
- processing_gcc_compilation = 0;
- }
-
- if (symbuf_idx == symbuf_end)
- fill_symbuf (abfd, objfile);
- bufp = &symbuf[symbuf_idx];
- if (bfd_h_get_8 (abfd, bufp->e_type) != N_SO)
- error (_("First symbol in segment of executable not a source symbol"));
-
- max_symnum = sym_size / key->ctx.symbol_size;
-
- for (symnum = 0;
- symnum < max_symnum;
- symnum++)
- {
- QUIT; /* Allow this to be interruptible. */
- if (symbuf_idx == symbuf_end)
- fill_symbuf (abfd, objfile);
- bufp = &symbuf[symbuf_idx++];
- INTERNALIZE_SYMBOL (nlist, bufp, abfd);
- OBJSTAT (objfile, n_stabs++);
-
- type = bfd_h_get_8 (abfd, bufp->e_type);
-
- namestring = set_namestring (objfile, &nlist);
-
- if (type & N_STAB)
- {
- if (sizeof (nlist.n_value) > 4
- /* We are a 64-bit debugger debugging a 32-bit program. */
- && (type == N_LSYM || type == N_PSYM))
- /* We have to be careful with the n_value in the case of N_LSYM
- and N_PSYM entries, because they are signed offsets from frame
- pointer, but we actually read them as unsigned 32-bit values.
- This is not a problem for 32-bit debuggers, for which negative
- values end up being interpreted correctly (as negative
- offsets) due to integer overflow.
- But we need to sign-extend the value for 64-bit debuggers,
- or we'll end up interpreting negative values as very large
- positive offsets. */
- nlist.n_value = (nlist.n_value ^ 0x80000000) - 0x80000000;
- process_one_symbol (type, nlist.n_desc, nlist.n_value,
- namestring, section_offsets, objfile,
- PST_LANGUAGE (pst));
- }
- /* We skip checking for a new .o or -l file; that should never
- happen in this routine. */
- else if (type == N_TEXT)
- {
- /* I don't think this code will ever be executed, because
- the GCC_COMPILED_FLAG_SYMBOL usually is right before
- the N_SO symbol which starts this source file.
- However, there is no reason not to accept
- the GCC_COMPILED_FLAG_SYMBOL anywhere. */
-
- if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0)
- processing_gcc_compilation = 1;
- else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0)
- processing_gcc_compilation = 2;
- }
- else if (type & N_EXT || type == (unsigned char) N_TEXT
- || type == (unsigned char) N_NBTEXT)
- {
- /* Global symbol: see if we came across a dbx definition for
- a corresponding symbol. If so, store the value. Remove
- syms from the chain when their values are stored, but
- search the whole chain, as there may be several syms from
- different files with the same name. */
- /* This is probably not true. Since the files will be read
- in one at a time, each reference to a global symbol will
- be satisfied in each file as it appears. So we skip this
- section. */
- ;
- }
- }
-
- /* In a Solaris elf file, this variable, which comes from the value
- of the N_SO symbol, will still be 0. Luckily, text_offset, which
- comes from low text address of PST, is correct. */
- if (get_last_source_start_addr () == 0)
- set_last_source_start_addr (text_offset);
-
- /* In reordered executables last_source_start_addr may not be the
- lower bound for this symtab, instead use text_offset which comes
- from the low text address of PST, which is correct. */
- if (get_last_source_start_addr () > text_offset)
- set_last_source_start_addr (text_offset);
-
- pst->compunit_symtab = end_compunit_symtab (text_offset + text_size);
-
- end_stabs ();
-
-}
-
-static void
-dbx_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
-{
- gdb_assert (!pst->readin);
- struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- /* Read in all partial symtabs on which this one is dependent. */
- pst->expand_dependencies (objfile);
-
- if (LDSYMLEN (pst)) /* Otherwise it's a dummy. */
- {
- /* Init stuff necessary for reading in symbols */
- stabsread_init ();
- scoped_free_pendings free_pending;
- key->ctx.file_string_table_offset = FILE_STRING_OFFSET (pst);
- key->ctx.symbol_size = SYMBOL_SIZE (pst);
-
- /* Read in this file's symbols. */
- if (bfd_seek (objfile->obfd.get (), SYMBOL_OFFSET (pst), SEEK_SET) == 0)
- read_ofile_symtab (objfile, pst);
- }
-
- pst->readin = true;
-}
-
-/* Invariant: The symbol pointed to by symbuf_idx is the first one
- that hasn't been swapped. Swap the symbol at the same time
- that symbuf_idx is incremented. */
-
-/* dbx allows the text of a symbol name to be continued into the
- next symbol name! When such a continuation is encountered
- (a \ at the end of the text of a name)
- call this function to get the continuation. */
-
-static const char *
-dbx_next_symbol_text (struct objfile *objfile)
-{
- struct internal_nlist nlist;
- dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- if (symbuf_idx == symbuf_end)
- fill_symbuf (objfile->obfd.get (), objfile);
-
- symnum++;
- INTERNALIZE_SYMBOL (nlist, &symbuf[symbuf_idx], objfile->obfd.get ());
- OBJSTAT (objfile, n_stabs++);
-
- symbuf_idx++;
-
- return nlist.n_strx + key->ctx.stringtab_global
- + key->ctx.file_string_table_offset;
-}
-
-/* Read in all of the symbols for a given psymtab for real.
- Be verbose about it if the user wants that. SELF is not NULL. */
-
-static void
-stabs_read_symtab (legacy_psymtab *self, struct objfile *objfile)
-{
- gdb_assert (!self->readin);
-
- if (LDSYMLEN (self) || self->number_of_dependencies)
- {
- next_symbol_text_func = dbx_next_symbol_text;
- dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- {
- scoped_restore restore_stabs_data = make_scoped_restore (&key->ctx.stabs_data);
- gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
- if (DBX_STAB_SECTION (objfile))
- {
- key->ctx.stabs_data
- = symfile_relocate_debug_section (objfile,
- DBX_STAB_SECTION (objfile),
- NULL);
- data_holder.reset (key->ctx.stabs_data);
- }
-
- self->expand_psymtab (objfile);
- }
-
- /* Match with global symbols. This only needs to be done once,
- after all of the symtabs and dependencies have been read in. */
- scan_file_globals (objfile);
- }
-}
-
-static void
-record_minimal_symbol (minimal_symbol_reader &reader,
- const char *name, unrelocated_addr address, int type,
- struct objfile *objfile)
-{
- enum minimal_symbol_type ms_type;
- int section;
- struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- switch (type)
- {
- case N_TEXT | N_EXT:
- ms_type = mst_text;
- section = SECT_OFF_TEXT (objfile);
- break;
- case N_DATA | N_EXT:
- ms_type = mst_data;
- section = SECT_OFF_DATA (objfile);
- break;
- case N_BSS | N_EXT:
- ms_type = mst_bss;
- section = SECT_OFF_BSS (objfile);
- break;
- case N_ABS | N_EXT:
- ms_type = mst_abs;
- section = -1;
- break;
-#ifdef N_SETV
- case N_SETV | N_EXT:
- ms_type = mst_data;
- section = SECT_OFF_DATA (objfile);
- break;
- case N_SETV:
- /* I don't think this type actually exists; since a N_SETV is the result
- of going over many .o files, it doesn't make sense to have one
- file local. */
- ms_type = mst_file_data;
- section = SECT_OFF_DATA (objfile);
- break;
-#endif
- case N_TEXT:
- case N_NBTEXT:
- case N_FN:
- case N_FN_SEQ:
- ms_type = mst_file_text;
- section = SECT_OFF_TEXT (objfile);
- break;
- case N_DATA:
- ms_type = mst_file_data;
-
- /* Check for __DYNAMIC, which is used by Sun shared libraries.
- Record it as global even if it's local, not global, so
- lookup_minimal_symbol can find it. We don't check symbol_leading_char
- because for SunOS4 it always is '_'. */
- if (strcmp ("__DYNAMIC", name) == 0)
- ms_type = mst_data;
-
- /* Same with virtual function tables, both global and static. */
- {
- const char *tempstring = name;
-
- if (*tempstring != '\0'
- && *tempstring == bfd_get_symbol_leading_char (objfile->obfd.get ()))
- ++tempstring;
- if (is_vtable_name (tempstring))
- ms_type = mst_data;
- }
- section = SECT_OFF_DATA (objfile);
- break;
- case N_BSS:
- ms_type = mst_file_bss;
- section = SECT_OFF_BSS (objfile);
- break;
- default:
- ms_type = mst_unknown;
- section = -1;
- break;
- }
-
- if ((ms_type == mst_file_text || ms_type == mst_text)
- && address < key->ctx.lowest_text_address)
- key->ctx.lowest_text_address = address;
-
- reader.record_with_info (name, address, ms_type, section);
-}
-
-/* Given a name, value pair, find the corresponding
- bincl in the list. Return the partial symtab associated
- with that header_file_location. */
-
-static legacy_psymtab *
-find_corresponding_bincl_psymtab (const char *name, int instance,
- struct objfile* objfile)
-{
- stabsread_context ctx = dbx_objfile_data_key.get (objfile) -> ctx;
- for (const header_file_location &bincl : ctx.bincl_list)
- if (bincl.instance == instance
- && strcmp (name, bincl.name) == 0)
- return bincl.pst;
-
- repeated_header_complaint (name, symnum);
- return (legacy_psymtab *) 0;
-}
-
-/* Allocate and partially fill a partial symtab. It will be
- completely filled at the end of the symbol list.
-
- SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
- is the address relative to which its symbols are (incremental) or 0
- (normal). */
-
-static legacy_psymtab *
-start_psymtab (psymtab_storage *partial_symtabs, struct objfile *objfile,
- const char *filename, unrelocated_addr textlow, int ldsymoff)
-{
- legacy_psymtab *result = new legacy_psymtab (filename, partial_symtabs,
- objfile->per_bfd, textlow);
-
- struct dbx_symfile_info *key = dbx_objfile_data_key.get(objfile);
-
- result->read_symtab_private =
- XOBNEW (&objfile->objfile_obstack, struct symloc);
- LDSYMOFF (result) = ldsymoff;
- result->legacy_read_symtab = stabs_read_symtab;
- result->legacy_expand_psymtab = dbx_expand_psymtab;
- SYMBOL_SIZE (result) = key->ctx.symbol_size;
- SYMBOL_OFFSET (result) = key->ctx.symbol_table_offset;
- STRING_OFFSET (result) = 0; /* This used to be an uninitialized global. */
- FILE_STRING_OFFSET (result) = key->ctx.file_string_table_offset;
-
- /* Deduce the source language from the filename for this psymtab. */
- key->ctx.psymtab_language = deduce_language_from_filename (filename);
- PST_LANGUAGE (result) = key->ctx.psymtab_language;
-
- return result;
-}
-
-/* See stabsread.h. */
-
-static void
-read_stabs_symtab_1 (minimal_symbol_reader &reader,
- psymtab_storage *partial_symtabs,
- struct objfile *objfile)
-{
- struct gdbarch *gdbarch = objfile->arch ();
- struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch. */
- struct internal_nlist nlist;
- CORE_ADDR text_addr;
- int text_size;
- const char *sym_name;
- int sym_len;
- unsigned int next_file_string_table_offset = 0;
- struct dbx_symfile_info *dbx = dbx_objfile_data_key.get(objfile);
-
- const char *namestring;
- int nsl;
- int past_first_source_file = 0;
- CORE_ADDR last_function_start = 0;
- bfd *abfd;
- int textlow_not_set;
- int data_sect_index;
-
- /* Current partial symtab. */
- legacy_psymtab *pst;
-
- /* List of current psymtab's include files. */
- const char **psymtab_include_list;
- int includes_allocated;
- int includes_used;
-
- /* Index within current psymtab dependency list. */
- legacy_psymtab **dependency_list;
- int dependencies_used, dependencies_allocated;
-
- text_addr = DBX_TEXT_ADDR (objfile);
- text_size = DBX_TEXT_SIZE (objfile);
-
- /* FIXME. We probably want to change stringtab_global rather than add this
- while processing every symbol entry. FIXME. */
- dbx->ctx.file_string_table_offset = 0;
-
- dbx->ctx.stringtab_global = DBX_STRINGTAB (objfile);
-
- pst = (legacy_psymtab *) 0;
-
- includes_allocated = 30;
- includes_used = 0;
- psymtab_include_list = (const char **) alloca (includes_allocated *
- sizeof (const char *));
-
- dependencies_allocated = 30;
- dependencies_used = 0;
- dependency_list =
- (legacy_psymtab **) alloca (dependencies_allocated *
- sizeof (legacy_psymtab *));
-
- /* Init bincl list */
- std::vector<struct header_file_location> bincl_storage;
- scoped_restore restore_bincl_global
- = make_scoped_restore (&(dbx->ctx.bincl_list), bincl_storage);
-
- set_last_source_file (NULL);
-
- dbx->ctx.lowest_text_address = (unrelocated_addr) -1;
-
- abfd = objfile->obfd.get ();
- symbuf_end = symbuf_idx = 0;
- next_symbol_text_func = dbx_next_symbol_text;
- textlow_not_set = 1;
- dbx->ctx.has_line_numbers = 0;
-
- /* FIXME: jimb/2003-09-12: We don't apply the right section's offset
- to global and static variables. The stab for a global or static
- variable doesn't give us any indication of which section it's in,
- so we can't tell immediately which offset in
- objfile->section_offsets we should apply to the variable's
- address.
-
- We could certainly find out which section contains the variable
- by looking up the variable's unrelocated address with
- find_pc_section, but that would be expensive; this is the
- function that constructs the partial symbol tables by examining
- every symbol in the entire executable, and it's
- performance-critical. So that expense would not be welcome. I'm
- not sure what to do about this at the moment.
-
- What we have done for years is to simply assume that the .data
- section's offset is appropriate for all global and static
- variables. Recently, this was expanded to fall back to the .bss
- section's offset if there is no .data section, and then to the
- .rodata section's offset. */
- data_sect_index = objfile->sect_index_data;
- if (data_sect_index == -1)
- data_sect_index = SECT_OFF_BSS (objfile);
- if (data_sect_index == -1)
- data_sect_index = SECT_OFF_RODATA (objfile);
-
- /* If data_sect_index is still -1, that's okay. It's perfectly fine
- for the file to have no .data, no .bss, and no .text at all, if
- it also has no global or static variables. */
-
- for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
- {
- /* Get the symbol for this run and pull out some info. */
- QUIT; /* Allow this to be interruptible. */
- if (symbuf_idx == symbuf_end)
- fill_symbuf (abfd, objfile);
- bufp = &symbuf[symbuf_idx++];
-
- /*
- * Special case to speed up readin.
- */
- if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
- {
- dbx->ctx.has_line_numbers = 1;
- continue;
- }
-
- INTERNALIZE_SYMBOL (nlist, bufp, abfd);
- OBJSTAT (objfile, n_stabs++);
-
- /* Ok. There is a lot of code duplicated in the rest of this
- switch statement (for efficiency reasons). Since I don't
- like duplicating code, I will do my penance here, and
- describe the code which is duplicated:
-
- *) The assignment to namestring.
- *) The call to strchr.
- *) The addition of a partial symbol the two partial
- symbol lists. This last is a large section of code, so
- I've embedded it in the following macro. */
-
- switch (nlist.n_type)
- {
- /*
- * Standard, external, non-debugger, symbols
- */
-
- case N_TEXT | N_EXT:
- case N_NBTEXT | N_EXT:
- goto record_it;
-
- case N_DATA | N_EXT:
- case N_NBDATA | N_EXT:
- goto record_it;
-
- case N_BSS:
- case N_BSS | N_EXT:
- case N_NBBSS | N_EXT:
- case N_SETV | N_EXT: /* FIXME, is this in BSS? */
- goto record_it;
-
- case N_ABS | N_EXT:
- record_it:
- namestring = set_namestring (objfile, &nlist);
-
- record_minimal_symbol (reader, namestring,
- unrelocated_addr (nlist.n_value),
- nlist.n_type, objfile); /* Always */
- continue;
-
- /* Standard, local, non-debugger, symbols. */
-
- case N_NBTEXT:
-
- /* We need to be able to deal with both N_FN or N_TEXT,
- because we have no way of knowing whether the sys-supplied ld
- or GNU ld was used to make the executable. Sequents throw
- in another wrinkle -- they renumbered N_FN. */
-
- case N_FN:
- case N_FN_SEQ:
- case N_TEXT:
- namestring = set_namestring (objfile, &nlist);
-
- if ((namestring[0] == '-' && namestring[1] == 'l')
- || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
- && namestring[nsl - 2] == '.'))
- {
- unrelocated_addr unrel_val = unrelocated_addr (nlist.n_value);
-
- if (past_first_source_file && pst
- /* The gould NP1 uses low values for .o and -l symbols
- which are not the address. */
- && unrel_val >= pst->unrelocated_text_low ())
- {
- stabs_end_psymtab (objfile, partial_symtabs,
- pst, psymtab_include_list,
- includes_used, symnum * dbx->ctx.symbol_size,
- unrel_val > pst->unrelocated_text_high ()
- ? unrel_val : pst->unrelocated_text_high (),
- dependency_list, dependencies_used,
- textlow_not_set);
- pst = (legacy_psymtab *) 0;
- includes_used = 0;
- dependencies_used = 0;
- dbx->ctx.has_line_numbers = 0;
- }
- else
- past_first_source_file = 1;
- }
- else
- goto record_it;
- continue;
-
- case N_DATA:
- goto record_it;
-
- case N_UNDF | N_EXT:
- /* The case (nlist.n_value != 0) is a "Fortran COMMON" symbol.
- We used to rely on the target to tell us whether it knows
- where the symbol has been relocated to, but none of the
- target implementations actually provided that operation.
- So we just ignore the symbol, the same way we would do if
- we had a target-side symbol lookup which returned no match.
-
- All other symbols (with nlist.n_value == 0), are really
- undefined, and so we ignore them too. */
- continue;
-
- case N_UNDF:
- if (dbx->ctx.processing_acc_compilation && nlist.n_strx == 1)
- {
- /* Deal with relative offsets in the string table
- used in ELF+STAB under Solaris. If we want to use the
- n_strx field, which contains the name of the file,
- we must adjust file_string_table_offset *before* calling
- set_namestring(). */
- past_first_source_file = 1;
- dbx->ctx.file_string_table_offset = next_file_string_table_offset;
- next_file_string_table_offset =
- dbx->ctx.file_string_table_offset + nlist.n_value;
- if (next_file_string_table_offset < dbx->ctx.file_string_table_offset)
- error (_("string table offset backs up at %d"), symnum);
- /* FIXME -- replace error() with complaint. */
- continue;
- }
- continue;
-
- /* Lots of symbol types we can just ignore. */
-
- case N_ABS:
- case N_NBDATA:
- case N_NBBSS:
- continue;
-
- /* Keep going . . . */
-
- /*
- * Special symbol types for GNU
- */
- case N_INDR:
- case N_INDR | N_EXT:
- case N_SETA:
- case N_SETA | N_EXT:
- case N_SETT:
- case N_SETT | N_EXT:
- case N_SETD:
- case N_SETD | N_EXT:
- case N_SETB:
- case N_SETB | N_EXT:
- case N_SETV:
- continue;
-
- /*
- * Debugger symbols
- */
-
- case N_SO:
- {
- CORE_ADDR valu;
- static int prev_so_symnum = -10;
- static int first_so_symnum;
- const char *p;
- static const char *dirname_nso;
- int prev_textlow_not_set;
-
- valu = nlist.n_value;
-
- prev_textlow_not_set = textlow_not_set;
-
- /* A zero value is probably an indication for the SunPRO 3.0
- compiler. stabs_end_psymtab explicitly tests for zero, so
- don't relocate it. */
-
- if (nlist.n_value == 0
- && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- textlow_not_set = 1;
- valu = 0;
- }
- else
- textlow_not_set = 0;
-
- past_first_source_file = 1;
-
- if (prev_so_symnum != symnum - 1)
- { /* Here if prev stab wasn't N_SO. */
- first_so_symnum = symnum;
-
- if (pst)
- {
- unrelocated_addr unrel_value = unrelocated_addr (valu);
- stabs_end_psymtab (objfile, partial_symtabs,
- pst, psymtab_include_list,
- includes_used, symnum * dbx->ctx.symbol_size,
- unrel_value > pst->unrelocated_text_high ()
- ? unrel_value
- : pst->unrelocated_text_high (),
- dependency_list, dependencies_used,
- prev_textlow_not_set);
- pst = (legacy_psymtab *) 0;
- includes_used = 0;
- dependencies_used = 0;
- dbx->ctx.has_line_numbers = 0;
- }
- }
-
- prev_so_symnum = symnum;
-
- /* End the current partial symtab and start a new one. */
-
- namestring = set_namestring (objfile, &nlist);
-
- /* Null name means end of .o file. Don't start a new one. */
- if (*namestring == '\000')
- continue;
-
- /* Some compilers (including gcc) emit a pair of initial N_SOs.
- The first one is a directory name; the second the file name.
- If pst exists, is empty, and has a filename ending in '/',
- we assume the previous N_SO was a directory name. */
-
- p = lbasename (namestring);
- if (p != namestring && *p == '\000')
- {
- /* Save the directory name SOs locally, then save it into
- the psymtab when it's created below. */
- dirname_nso = namestring;
- continue;
- }
-
- /* Some other compilers (C++ ones in particular) emit useless
- SOs for non-existent .c files. We ignore all subsequent SOs
- that immediately follow the first. */
-
- if (!pst)
- {
- pst = start_psymtab (partial_symtabs, objfile,
- namestring,
- unrelocated_addr (valu),
- first_so_symnum * dbx->ctx.symbol_size);
- pst->dirname = dirname_nso;
- dirname_nso = NULL;
- }
- continue;
- }
-
- case N_BINCL:
- {
- enum language tmp_language;
-
- /* Add this bincl to the bincl_list for future EXCLs. No
- need to save the string; it'll be around until
- read_stabs_symtab function returns. */
-
- namestring = set_namestring (objfile, &nlist);
- tmp_language = deduce_language_from_filename (namestring);
-
- /* Only change the psymtab's language if we've learned
- something useful (eg. tmp_language is not language_unknown).
- In addition, to match what start_subfile does, never change
- from C++ to C. */
- if (tmp_language != language_unknown
- && (tmp_language != language_c
- || dbx->ctx.psymtab_language != language_cplus))
- dbx->ctx.psymtab_language = tmp_language;
-
- if (pst == NULL)
- {
- /* FIXME: we should not get here without a PST to work on.
- Attempt to recover. */
- complaint (_("N_BINCL %s not in entries for "
- "any file, at symtab pos %d"),
- namestring, symnum);
- continue;
- }
- dbx->ctx.bincl_list.emplace_back (namestring, nlist.n_value, pst);
-
- /* Mark down an include file in the current psymtab. */
-
- goto record_include_file;
- }
-
- case N_SOL:
- {
- enum language tmp_language;
-
- /* Mark down an include file in the current psymtab. */
- namestring = set_namestring (objfile, &nlist);
- tmp_language = deduce_language_from_filename (namestring);
-
- /* Only change the psymtab's language if we've learned
- something useful (eg. tmp_language is not language_unknown).
- In addition, to match what start_subfile does, never change
- from C++ to C. */
- if (tmp_language != language_unknown
- && (tmp_language != language_c
- || dbx->ctx.psymtab_language != language_cplus))
- dbx->ctx.psymtab_language = tmp_language;
-
- /* In C++, one may expect the same filename to come round many
- times, when code is coming alternately from the main file
- and from inline functions in other files. So I check to see
- if this is a file we've seen before -- either the main
- source file, or a previously included file.
-
- This seems to be a lot of time to be spending on N_SOL, but
- things like "break c-exp.y:435" need to work (I
- suppose the psymtab_include_list could be hashed or put
- in a binary tree, if profiling shows this is a major hog). */
- if (pst && filename_cmp (namestring, pst->filename) == 0)
- continue;
- {
- int i;
-
- for (i = 0; i < includes_used; i++)
- if (filename_cmp (namestring, psymtab_include_list[i]) == 0)
- {
- i = -1;
- break;
- }
- if (i == -1)
- continue;
- }
-
- record_include_file:
-
- psymtab_include_list[includes_used++] = namestring;
- if (includes_used >= includes_allocated)
- {
- const char **orig = psymtab_include_list;
-
- psymtab_include_list = (const char **)
- alloca ((includes_allocated *= 2) * sizeof (const char *));
- memcpy (psymtab_include_list, orig,
- includes_used * sizeof (const char *));
- }
- continue;
- }
- case N_LSYM: /* Typedef or automatic variable. */
- case N_STSYM: /* Data seg var -- static. */
- case N_LCSYM: /* BSS " */
- case N_ROSYM: /* Read-only data seg var -- static. */
- case N_NBSTS: /* Gould nobase. */
- case N_NBLCS: /* symbols. */
- case N_FUN:
- case N_GSYM: /* Global (extern) variable; can be
- data or bss (sigh FIXME). */
-
- /* Following may probably be ignored; I'll leave them here
- for now (until I do Pascal and Modula 2 extensions). */
-
- case N_PC: /* I may or may not need this; I
- suspect not. */
- case N_M2C: /* I suspect that I can ignore this here. */
- case N_SCOPE: /* Same. */
- {
- const char *p;
-
- namestring = set_namestring (objfile, &nlist);
-
- /* See if this is an end of function stab. */
- if (pst && nlist.n_type == N_FUN && *namestring == '\000')
- {
- unrelocated_addr valu;
-
- /* It's value is the size (in bytes) of the function for
- function relative stabs, or the address of the function's
- end for old style stabs. */
- valu = unrelocated_addr (nlist.n_value + last_function_start);
- if (pst->unrelocated_text_high () == unrelocated_addr (0)
- || valu > pst->unrelocated_text_high ())
- pst->set_text_high (valu);
- break;
- }
-
- p = (char *) strchr (namestring, ':');
- if (!p)
- continue; /* Not a debugging symbol. */
-
- sym_len = 0;
- sym_name = NULL; /* pacify "gcc -Werror" */
- if (dbx->ctx.psymtab_language == language_cplus)
- {
- std::string name (namestring, p - namestring);
- gdb::unique_xmalloc_ptr<char> new_name
- = cp_canonicalize_string (name.c_str ());
- if (new_name != nullptr)
- {
- sym_len = strlen (new_name.get ());
- sym_name = obstack_strdup (&objfile->objfile_obstack,
- new_name.get ());
- }
- }
- else if (dbx->ctx.psymtab_language == language_c)
- {
- std::string name (namestring, p - namestring);
- gdb::unique_xmalloc_ptr<char> new_name
- = c_canonicalize_name (name.c_str ());
- if (new_name != nullptr)
- {
- sym_len = strlen (new_name.get ());
- sym_name = obstack_strdup (&objfile->objfile_obstack,
- new_name.get ());
- }
- }
-
- if (sym_len == 0)
- {
- sym_name = namestring;
- sym_len = p - namestring;
- }
-
- /* Main processing section for debugging symbols which
- the initial read through the symbol tables needs to worry
- about. If we reach this point, the symbol which we are
- considering is definitely one we are interested in.
- p must also contain the (valid) index into the namestring
- which indicates the debugging type symbol. */
-
- switch (p[1])
- {
- case 'S':
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len), true,
- VAR_DOMAIN, LOC_STATIC,
- data_sect_index,
- psymbol_placement::STATIC,
- unrelocated_addr (nlist.n_value),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- else
- complaint (_("static `%*s' appears to be defined "
- "outside of all compilation units"),
- sym_len, sym_name);
- continue;
-
- case 'G':
- /* The addresses in these entries are reported to be
- wrong. See the code that reads 'G's for symtabs. */
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len), true,
- VAR_DOMAIN, LOC_STATIC,
- data_sect_index,
- psymbol_placement::GLOBAL,
- unrelocated_addr (nlist.n_value),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- else
- complaint (_("global `%*s' appears to be defined "
- "outside of all compilation units"),
- sym_len, sym_name);
- continue;
-
- case 'T':
- /* When a 'T' entry is defining an anonymous enum, it
- may have a name which is the empty string, or a
- single space. Since they're not really defining a
- symbol, those shouldn't go in the partial symbol
- table. We do pick up the elements of such enums at
- 'check_enum:', below. */
- if (p >= namestring + 2
- || (p == namestring + 1
- && namestring[0] != ' '))
- {
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len),
- true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- unrelocated_addr (0),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- else
- complaint (_("enum, struct, or union `%*s' appears "
- "to be defined outside of all "
- "compilation units"),
- sym_len, sym_name);
- if (p[2] == 't')
- {
- /* Also a typedef with the same name. */
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len),
- true, VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- unrelocated_addr (0),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- else
- complaint (_("typedef `%*s' appears to be defined "
- "outside of all compilation units"),
- sym_len, sym_name);
- p += 1;
- }
- }
- goto check_enum;
-
- case 't':
- if (p != namestring) /* a name is there, not just :T... */
- {
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len),
- true, VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- unrelocated_addr (0),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- else
- complaint (_("typename `%*s' appears to be defined "
- "outside of all compilation units"),
- sym_len, sym_name);
- }
- check_enum:
- /* If this is an enumerated type, we need to
- add all the enum constants to the partial symbol
- table. This does not cover enums without names, e.g.
- "enum {a, b} c;" in C, but fortunately those are
- rare. There is no way for GDB to find those from the
- enum type without spending too much time on it. Thus
- to solve this problem, the compiler needs to put out the
- enum in a nameless type. GCC2 does this. */
-
- /* We are looking for something of the form
- <name> ":" ("t" | "T") [<number> "="] "e"
- {<constant> ":" <value> ","} ";". */
-
- /* Skip over the colon and the 't' or 'T'. */
- p += 2;
- /* This type may be given a number. Also, numbers can come
- in pairs like (0,26). Skip over it. */
- while ((*p >= '0' && *p <= '9')
- || *p == '(' || *p == ',' || *p == ')'
- || *p == '=')
- p++;
-
- if (*p++ == 'e')
- {
- /* The aix4 compiler emits extra crud before the members. */
- if (*p == '-')
- {
- /* Skip over the type (?). */
- while (*p != ':')
- p++;
-
- /* Skip over the colon. */
- p++;
- }
-
- /* We have found an enumerated type. */
- /* According to comments in read_enum_type
- a comma could end it instead of a semicolon.
- I don't know where that happens.
- Accept either. */
- while (*p && *p != ';' && *p != ',')
- {
- const char *q;
-
- /* Check for and handle cretinous dbx symbol name
- continuation! */
- if (*p == '\\' || (*p == '?' && p[1] == '\0'))
- p = next_symbol_text (objfile);
-
- /* Point to the character after the name
- of the enum constant. */
- for (q = p; *q && *q != ':'; q++)
- ;
- /* Note that the value doesn't matter for
- enum constants in psymtabs, just in symtabs. */
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (p, q - p), true,
- VAR_DOMAIN, LOC_CONST, -1,
- psymbol_placement::STATIC,
- unrelocated_addr (0),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- else
- complaint (_("enum constant `%*s' appears to be defined "
- "outside of all compilation units"),
- ((int) (q - p)), p);
- /* Point past the name. */
- p = q;
- /* Skip over the value. */
- while (*p && *p != ',')
- p++;
- /* Advance past the comma. */
- if (*p)
- p++;
- }
- }
- continue;
-
- case 'c':
- /* Constant, e.g. from "const" in Pascal. */
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len), true,
- VAR_DOMAIN, LOC_CONST, -1,
- psymbol_placement::STATIC,
- unrelocated_addr (0),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- else
- complaint (_("constant `%*s' appears to be defined "
- "outside of all compilation units"),
- sym_len, sym_name);
-
- continue;
-
- case 'f':
- if (! pst)
- {
- std::string name (namestring, (p - namestring));
- function_outside_compilation_unit_complaint (name.c_str ());
- }
- /* Kludges for ELF/STABS with Sun ACC. */
- dbx->ctx.last_function_name = namestring;
- /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
- value for the bottom of the text seg in those cases. */
- if (nlist.n_value == 0
- && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- bound_minimal_symbol minsym
- = find_stab_function (namestring,
- pst ? pst->filename : NULL, objfile);
- if (minsym.minsym != NULL)
- nlist.n_value
- = CORE_ADDR (minsym.minsym->unrelocated_address ());
- }
- if (pst && textlow_not_set
- && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- pst->set_text_low (unrelocated_addr (nlist.n_value));
- textlow_not_set = 0;
- }
- /* End kludge. */
-
- /* Keep track of the start of the last function so we
- can handle end of function symbols. */
- last_function_start = nlist.n_value;
-
- /* In reordered executables this function may lie outside
- the bounds created by N_SO symbols. If that's the case
- use the address of this function as the low bound for
- the partial symbol table. */
- if (pst
- && (textlow_not_set
- || (unrelocated_addr (nlist.n_value)
- < pst->unrelocated_text_low ()
- && (nlist.n_value != 0))))
- {
- pst->set_text_low (unrelocated_addr (nlist.n_value));
- textlow_not_set = 0;
- }
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len), true,
- VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::STATIC,
- unrelocated_addr (nlist.n_value),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- continue;
-
- /* Global functions were ignored here, but now they
- are put into the global psymtab like one would expect.
- They're also in the minimal symbol table. */
- case 'F':
- if (! pst)
- {
- std::string name (namestring, (p - namestring));
- function_outside_compilation_unit_complaint (name.c_str ());
- }
- /* Kludges for ELF/STABS with Sun ACC. */
- dbx->ctx.last_function_name = namestring;
- /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
- value for the bottom of the text seg in those cases. */
- if (nlist.n_value == 0
- && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- bound_minimal_symbol minsym
- = find_stab_function (namestring,
- pst ? pst->filename : NULL, objfile);
- if (minsym.minsym != NULL)
- nlist.n_value
- = CORE_ADDR (minsym.minsym->unrelocated_address ());
- }
- if (pst && textlow_not_set
- && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- pst->set_text_low (unrelocated_addr (nlist.n_value));
- textlow_not_set = 0;
- }
- /* End kludge. */
-
- /* Keep track of the start of the last function so we
- can handle end of function symbols. */
- last_function_start = nlist.n_value;
-
- /* In reordered executables this function may lie outside
- the bounds created by N_SO symbols. If that's the case
- use the address of this function as the low bound for
- the partial symbol table. */
- if (pst
- && (textlow_not_set
- || (unrelocated_addr (nlist.n_value)
- < pst->unrelocated_text_low ()
- && (nlist.n_value != 0))))
- {
- pst->set_text_low (unrelocated_addr (nlist.n_value));
- textlow_not_set = 0;
- }
- if (pst != nullptr)
- pst->add_psymbol (std::string_view (sym_name, sym_len), true,
- VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::GLOBAL,
- unrelocated_addr (nlist.n_value),
- dbx->ctx.psymtab_language,
- partial_symtabs, objfile);
- continue;
-
- /* Two things show up here (hopefully); static symbols of
- local scope (static used inside braces) or extensions
- of structure symbols. We can ignore both. */
- case 'V':
- case '(':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '-':
- case '#': /* For symbol identification (used in live ranges). */
- continue;
-
- case ':':
- /* It is a C++ nested symbol. We don't need to record it
- (I don't think); if we try to look up foo::bar::baz,
- then symbols for the symtab containing foo should get
- read in, I think. */
- /* Someone says sun cc puts out symbols like
- /foo/baz/maclib::/usr/local/bin/maclib,
- which would get here with a symbol type of ':'. */
- continue;
-
- default:
- /* Unexpected symbol descriptor. The second and subsequent stabs
- of a continued stab can show up here. The question is
- whether they ever can mimic a normal stab--it would be
- nice if not, since we certainly don't want to spend the
- time searching to the end of every string looking for
- a backslash. */
-
- complaint (_("unknown symbol descriptor `%c'"),
- p[1]);
-
- /* Ignore it; perhaps it is an extension that we don't
- know about. */
- continue;
- }
- }
-
- case N_EXCL:
-
- namestring = set_namestring (objfile, &nlist);
-
- /* Find the corresponding bincl and mark that psymtab on the
- psymtab dependency list. */
- {
- legacy_psymtab *needed_pst =
- find_corresponding_bincl_psymtab (namestring, nlist.n_value, objfile);
-
- /* If this include file was defined earlier in this file,
- leave it alone. */
- if (needed_pst == pst)
- continue;
-
- if (needed_pst)
- {
- int i;
- int found = 0;
-
- for (i = 0; i < dependencies_used; i++)
- if (dependency_list[i] == needed_pst)
- {
- found = 1;
- break;
- }
-
- /* If it's already in the list, skip the rest. */
- if (found)
- continue;
-
- dependency_list[dependencies_used++] = needed_pst;
- if (dependencies_used >= dependencies_allocated)
- {
- legacy_psymtab **orig = dependency_list;
-
- dependency_list =
- (legacy_psymtab **)
- alloca ((dependencies_allocated *= 2)
- * sizeof (legacy_psymtab *));
- memcpy (dependency_list, orig,
- (dependencies_used
- * sizeof (legacy_psymtab *)));
-#ifdef DEBUG_INFO
- gdb_printf (gdb_stderr,
- "Had to reallocate "
- "dependency list.\n");
- gdb_printf (gdb_stderr,
- "New dependencies allocated: %d\n",
- dependencies_allocated);
-#endif
- }
- }
- }
- continue;
-
- case N_ENDM:
- /* Solaris 2 end of module, finish current partial symbol
- table. stabs_end_psymtab will set the high text address of
- PST to the proper value, which is necessary if a module
- compiled without debugging info follows this module. */
- if (pst && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- stabs_end_psymtab (objfile, partial_symtabs, pst,
- psymtab_include_list, includes_used,
- symnum * dbx->ctx.symbol_size,
- (unrelocated_addr) 0, dependency_list,
- dependencies_used, textlow_not_set);
- pst = (legacy_psymtab *) 0;
- includes_used = 0;
- dependencies_used = 0;
- dbx->ctx.has_line_numbers = 0;
- }
- continue;
-
- case N_RBRAC:
-#ifdef HANDLE_RBRAC
- HANDLE_RBRAC (nlist.n_value);
- continue;
-#endif
- case N_EINCL:
- case N_DSLINE:
- case N_BSLINE:
- case N_SSYM: /* Claim: Structure or union element.
- Hopefully, I can ignore this. */
- case N_ENTRY: /* Alternate entry point; can ignore. */
- case N_MAIN: /* Can definitely ignore this. */
- case N_CATCH: /* These are GNU C++ extensions */
- case N_EHDECL: /* that can safely be ignored here. */
- case N_LENG:
- case N_BCOMM:
- case N_ECOMM:
- case N_ECOML:
- case N_FNAME:
- case N_SLINE:
- case N_RSYM:
- case N_PSYM:
- case N_BNSYM:
- case N_ENSYM:
- case N_LBRAC:
- case N_NSYMS: /* Ultrix 4.0: symbol count */
- case N_DEFD: /* GNU Modula-2 */
- case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
-
- case N_OBJ: /* Useless types from Solaris. */
- case N_OPT:
- case N_PATCH:
- /* These symbols aren't interesting; don't worry about them. */
- continue;
-
- default:
- /* If we haven't found it yet, ignore it. It's probably some
- new type we don't know about yet. */
- unknown_symtype_complaint (hex_string (nlist.n_type));
- continue;
- }
- }
-
- /* If there's stuff to be cleaned up, clean it up. */
- if (pst)
- {
- /* Don't set high text address of PST lower than it already
- is. */
- unrelocated_addr text_end
- = (unrelocated_addr
- ((dbx->ctx.lowest_text_address == (unrelocated_addr) -1
- ? text_addr
- : CORE_ADDR (dbx->ctx.lowest_text_address))
- + text_size));
-
- stabs_end_psymtab (objfile, partial_symtabs,
- pst, psymtab_include_list, includes_used,
- symnum * dbx->ctx.symbol_size,
- (text_end > pst->unrelocated_text_high ()
- ? text_end : pst->unrelocated_text_high ()),
- dependency_list, dependencies_used, textlow_not_set);
- }
-}
-
-/* Scan and build partial symbols for a symbol file.
- We have been initialized by a call to dbx_symfile_init, which
- put all the relevant info into a "struct dbx_symfile_info",
- hung off the objfile structure. */
-
-void
-read_stabs_symtab (struct objfile *objfile, symfile_add_flags symfile_flags)
-{
- bfd *sym_bfd;
- int val;
- struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- sym_bfd = objfile->obfd.get ();
-
- stabs_deprecated_warning ();
-
- /* .o and .nlm files are relocatables with text, data and bss segs based at
- 0. This flag disables special (Solaris stabs-in-elf only) fixups for
- symbols with a value of 0. */
-
- key->ctx.symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
-
- val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
- if (val < 0)
- perror_with_name (objfile_name (objfile));
-
- key->ctx.symbol_size = DBX_SYMBOL_SIZE (objfile);
- key->ctx.symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
-
- scoped_free_pendings free_pending;
-
- minimal_symbol_reader reader (objfile);
-
- /* Read stabs data from executable file and define symbols. */
-
- psymbol_functions *psf = new psymbol_functions ();
- psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
- objfile->qf.emplace_front (psf);
- read_stabs_symtab_1 (reader, partial_symtabs, objfile);
-
- /* Install any minimal symbols that have been collected as the current
- minimal symbols for this objfile. */
-
- reader.install ();
-}
-
-/* Record the namespace that the function defined by SYMBOL was
- defined in, if necessary. BLOCK is the associated block; use
- OBSTACK for allocation. */
-
-static void
-cp_set_block_scope (const struct symbol *symbol,
- struct block *block,
- struct obstack *obstack)
-{
- if (symbol->demangled_name () != NULL)
- {
- /* Try to figure out the appropriate namespace from the
- demangled name. */
-
- /* FIXME: carlton/2003-04-15: If the function in question is
- a method of a class, the name will actually include the
- name of the class as well. This should be harmless, but
- is a little unfortunate. */
-
- const char *name = symbol->demangled_name ();
- unsigned int prefix_len = cp_entire_prefix_len (name);
-
- block->set_scope (obstack_strndup (obstack, name, prefix_len),
- obstack);
- }
-}
-
-bound_minimal_symbol
-find_stab_function (const char *namestring, const char *filename,
- struct objfile *objfile)
-{
- int n;
-
- const char *colon = strchr (namestring, ':');
- if (colon == NULL)
- n = 0;
- else
- n = colon - namestring;
-
- char *p = (char *) alloca (n + 2);
- strncpy (p, namestring, n);
- p[n] = 0;
-
- bound_minimal_symbol msym
- = lookup_minimal_symbol (current_program_space, p, objfile, filename);
- if (msym.minsym == NULL)
- {
- /* Sun Fortran appends an underscore to the minimal symbol name,
- try again with an appended underscore if the minimal symbol
- was not found. */
- p[n] = '_';
- p[n + 1] = 0;
- msym
- = lookup_minimal_symbol (current_program_space, p, objfile, filename);
- }
-
- if (msym.minsym == NULL && filename != NULL)
- {
- /* Try again without the filename. */
- p[n] = 0;
- msym = lookup_minimal_symbol (current_program_space, p, objfile);
- }
- if (msym.minsym == NULL && filename != NULL)
- {
- /* And try again for Sun Fortran, but without the filename. */
- p[n] = '_';
- p[n + 1] = 0;
- msym = lookup_minimal_symbol (current_program_space, p, objfile);
- }
-
- return msym;
-}
-
-/* Add header file number I for this object file
- at the next successive FILENUM. */
-
-static void
-add_this_object_header_file (int i)
-{
- if (n_this_object_header_files == n_allocated_this_object_header_files)
- {
- n_allocated_this_object_header_files *= 2;
- this_object_header_files
- = (int *) xrealloc ((char *) this_object_header_files,
- n_allocated_this_object_header_files * sizeof (int));
- }
-
- this_object_header_files[n_this_object_header_files++] = i;
-}
-
-/* Add to this file an "old" header file, one already seen in
- a previous object file. NAME is the header file's name.
- INSTANCE is its instance code, to select among multiple
- symbol tables for the same header file. */
-
-static void
-add_old_header_file (const char *name, int instance, struct objfile *objfile)
-{
- struct header_file *p = HEADER_FILES (objfile);
- int i;
-
- for (i = 0; i < N_HEADER_FILES (objfile); i++)
- if (filename_cmp (p[i].name, name) == 0 && instance == p[i].instance)
- {
- add_this_object_header_file (i);
- return;
- }
- repeated_header_complaint (name, symnum);
-}
-
-/* Add to this file a "new" header file: definitions for its types follow.
- NAME is the header file's name.
- Most often this happens only once for each distinct header file,
- but not necessarily. If it happens more than once, INSTANCE has
- a different value each time, and references to the header file
- use INSTANCE values to select among them.
-
- dbx output contains "begin" and "end" markers for each new header file,
- but at this level we just need to know which files there have been;
- so we record the file when its "begin" is seen and ignore the "end". */
-
-static void
-add_new_header_file (const char *name, int instance, struct objfile *objfile)
-{
- int i;
- struct header_file *hfile;
-
- /* Make sure there is room for one more header file. */
-
- i = N_ALLOCATED_HEADER_FILES (objfile);
-
- if (N_HEADER_FILES (objfile) == i)
- {
- if (i == 0)
- {
- N_ALLOCATED_HEADER_FILES (objfile) = 10;
- HEADER_FILES (objfile) = (struct header_file *)
- xmalloc (10 * sizeof (struct header_file));
- }
- else
- {
- i *= 2;
- N_ALLOCATED_HEADER_FILES (objfile) = i;
- HEADER_FILES (objfile) = (struct header_file *)
- xrealloc ((char *) HEADER_FILES (objfile),
- (i * sizeof (struct header_file)));
- }
- }
-
- /* Create an entry for this header file. */
-
- i = N_HEADER_FILES (objfile)++;
- hfile = HEADER_FILES (objfile) + i;
- hfile->name = xstrdup (name);
- hfile->instance = instance;
- hfile->length = 10;
- hfile->vector = XCNEWVEC (struct type *, 10);
-
- add_this_object_header_file (i);
-}
-
-/* See stabsread.h. */
-
-void
-process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
- const section_offsets §ion_offsets,
- struct objfile *objfile, enum language language)
-{
- struct gdbarch *gdbarch = objfile->arch ();
- struct context_stack *newobj;
- struct context_stack cstk;
- /* This remembers the address of the start of a function. It is
- used because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries
- are relative to the current function's start address. On systems
- other than Solaris 2, this just holds the SECT_OFF_TEXT value,
- and is used to relocate these symbol types rather than
- SECTION_OFFSETS. */
- static CORE_ADDR function_start_offset;
-
- /* This holds the address of the start of a function, without the
- system peculiarities of function_start_offset. */
- static CORE_ADDR last_function_start;
-
- /* If this is nonzero, we've seen an N_SLINE since the start of the
- current function. We use this to tell us to move the first sline
- to the beginning of the function regardless of what its given
- value is. */
- static int sline_found_in_function = 1;
-
- /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this
- source file. Used to detect the SunPRO solaris compiler. */
- static int n_opt_found;
-
- /* The section index for this symbol. */
- int section_index = -1;
-
- struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
- /* Something is wrong if we see real data before seeing a source
- file name. */
-
- if (get_last_source_file () == NULL && type != (unsigned char) N_SO)
- {
- /* Ignore any symbols which appear before an N_SO symbol.
- Currently no one puts symbols there, but we should deal
- gracefully with the case. A complain()t might be in order,
- but this should not be an error (). */
- return;
- }
-
- switch (type)
- {
- case N_FUN:
- case N_FNAME:
-
- if (*name == '\000')
- {
- /* This N_FUN marks the end of a function. This closes off
- the current block. */
- struct block *block;
-
- if (outermost_context_p ())
- {
- lbrac_mismatch_complaint (symnum);
- break;
- }
-
- /* The following check is added before recording line 0 at
- end of function so as to handle hand-generated stabs
- which may have an N_FUN stabs at the end of the function,
- but no N_SLINE stabs. */
- if (sline_found_in_function)
- {
- CORE_ADDR addr = last_function_start + valu;
-
- record_line
- (get_current_subfile (), 0,
- unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, addr)
- - objfile->text_section_offset ()));
- }
-
- within_function = 0;
- cstk = pop_context ();
-
- /* Make a block for the local symbols within. */
- block = finish_block (cstk.name,
- cstk.old_blocks, NULL,
- cstk.start_addr, cstk.start_addr + valu);
-
- /* For C++, set the block's scope. */
- if (cstk.name->language () == language_cplus)
- cp_set_block_scope (cstk.name, block, &objfile->objfile_obstack);
-
- /* May be switching to an assembler file which may not be using
- block relative stabs, so reset the offset. */
- function_start_offset = 0;
-
- break;
- }
-
- sline_found_in_function = 0;
-
- /* Relocate for dynamic loading. */
- section_index = SECT_OFF_TEXT (objfile);
- valu += section_offsets[SECT_OFF_TEXT (objfile)];
- valu = gdbarch_addr_bits_remove (gdbarch, valu);
- last_function_start = valu;
-
- goto define_a_symbol;
-
- case N_LBRAC:
- /* This "symbol" just indicates the start of an inner lexical
- context within a function. */
-
- /* Ignore extra outermost context from SunPRO cc and acc. */
- if (n_opt_found && desc == 1)
- break;
-
- valu += function_start_offset;
-
- push_context (desc, valu);
- break;
-
- case N_RBRAC:
- /* This "symbol" just indicates the end of an inner lexical
- context that was started with N_LBRAC. */
-
- /* Ignore extra outermost context from SunPRO cc and acc. */
- if (n_opt_found && desc == 1)
- break;
-
- valu += function_start_offset;
-
- if (outermost_context_p ())
- {
- lbrac_mismatch_complaint (symnum);
- break;
- }
-
- cstk = pop_context ();
- if (desc != cstk.depth)
- lbrac_mismatch_complaint (symnum);
-
- if (*get_local_symbols () != NULL)
- {
- /* GCC development snapshots from March to December of
- 2000 would output N_LSYM entries after N_LBRAC
- entries. As a consequence, these symbols are simply
- discarded. Complain if this is the case. */
- complaint (_("misplaced N_LBRAC entry; discarding local "
- "symbols which have no enclosing block"));
- }
- *get_local_symbols () = cstk.locals;
-
- if (get_context_stack_depth () > 1)
- {
- /* This is not the outermost LBRAC...RBRAC pair in the
- function, its local symbols preceded it, and are the ones
- just recovered from the context stack. Define the block
- for them (but don't bother if the block contains no
- symbols. Should we complain on blocks without symbols?
- I can't think of any useful purpose for them). */
- if (*get_local_symbols () != NULL)
- {
- /* Muzzle a compiler bug that makes end < start.
-
- ??? Which compilers? Is this ever harmful?. */
- if (cstk.start_addr > valu)
- {
- complaint (_("block start larger than block end"));
- cstk.start_addr = valu;
- }
- /* Make a block for the local symbols within. */
- finish_block (0, cstk.old_blocks, NULL,
- cstk.start_addr, valu);
- }
- }
- else
- {
- /* This is the outermost LBRAC...RBRAC pair. There is no
- need to do anything; leave the symbols that preceded it
- to be attached to the function's own block. We need to
- indicate that we just moved outside of the function. */
- within_function = 0;
- }
-
- break;
-
- case N_FN:
- case N_FN_SEQ:
- /* This kind of symbol indicates the start of an object file.
- Relocate for dynamic loading. */
- section_index = SECT_OFF_TEXT (objfile);
- valu += section_offsets[SECT_OFF_TEXT (objfile)];
- break;
-
- case N_SO:
- /* This type of symbol indicates the start of data for one
- source file. Finish the symbol table of the previous source
- file (if any) and start accumulating a new symbol table.
- Relocate for dynamic loading. */
- section_index = SECT_OFF_TEXT (objfile);
- valu += section_offsets[SECT_OFF_TEXT (objfile)];
-
- n_opt_found = 0;
-
- if (get_last_source_file ())
- {
- /* Check if previous symbol was also an N_SO (with some
- sanity checks). If so, that one was actually the
- directory name, and the current one is the real file
- name. Patch things up. */
- if (previous_stab_code == (unsigned char) N_SO)
- {
- patch_subfile_names (get_current_subfile (), name);
- break; /* Ignore repeated SOs. */
- }
- end_compunit_symtab (valu);
- end_stabs ();
- }
-
- /* Null name means this just marks the end of text for this .o
- file. Don't start a new symtab in this case. */
- if (*name == '\000')
- break;
-
- function_start_offset = 0;
-
- start_stabs ();
- start_compunit_symtab (objfile, name, NULL, valu, language);
- record_debugformat ("stabs");
- break;
-
- case N_SOL:
- /* This type of symbol indicates the start of data for a
- sub-source-file, one whose contents were copied or included
- in the compilation of the main source file (whose name was
- given in the N_SO symbol). Relocate for dynamic loading. */
- section_index = SECT_OFF_TEXT (objfile);
- valu += section_offsets[SECT_OFF_TEXT (objfile)];
- start_subfile (name);
- break;
-
- case N_BINCL:
- push_subfile ();
- add_new_header_file (name, valu, objfile);
- start_subfile (name);
- break;
-
- case N_EINCL:
- start_subfile (pop_subfile ());
- break;
-
- case N_EXCL:
- add_old_header_file (name, valu, objfile);
- break;
-
- case N_SLINE:
- /* This type of "symbol" really just records one line-number --
- core-address correspondence. Enter it in the line list for
- this symbol table. */
-
- /* Relocate for dynamic loading and for ELF acc
- function-relative symbols. */
- valu += function_start_offset;
-
- /* GCC 2.95.3 emits the first N_SLINE stab somewhere in the
- middle of the prologue instead of right at the start of the
- function. To deal with this we record the address for the
- first N_SLINE stab to be the start of the function instead of
- the listed location. We really shouldn't to this. When
- compiling with optimization, this first N_SLINE stab might be
- optimized away. Other (non-GCC) compilers don't emit this
- stab at all. There is no real harm in having an extra
- numbered line, although it can be a bit annoying for the
- user. However, it totally screws up our testsuite.
-
- So for now, keep adjusting the address of the first N_SLINE
- stab, but only for code compiled with GCC. */
-
- if (within_function && sline_found_in_function == 0)
- {
- CORE_ADDR addr = processing_gcc_compilation == 2 ?
- last_function_start : valu;
-
- record_line
- (get_current_subfile (), desc,
- unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, addr)
- - objfile->text_section_offset ()));
- sline_found_in_function = 1;
- }
- else
- record_line
- (get_current_subfile (), desc,
- unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, valu)
- - objfile->text_section_offset ()));
- break;
-
- case N_BCOMM:
- common_block_start (name, objfile);
- break;
-
- case N_ECOMM:
- common_block_end (objfile);
- break;
-
- /* The following symbol types need to have the appropriate
- offset added to their value; then we process symbol
- definitions in the name. */
-
- case N_STSYM: /* Static symbol in data segment. */
- case N_LCSYM: /* Static symbol in BSS segment. */
- case N_ROSYM: /* Static symbol in read-only data segment. */
- /* HORRID HACK DEPT. However, it's Sun's furgin' fault.
- Solaris 2's stabs-in-elf makes *most* symbols relative but
- leaves a few absolute (at least for Solaris 2.1 and version
- 2.0.1 of the SunPRO compiler). N_STSYM and friends sit on
- the fence. .stab "foo:S...",N_STSYM is absolute (ld
- relocates it) .stab "foo:V...",N_STSYM is relative (section
- base subtracted). This leaves us no choice but to search for
- the 'S' or 'V'... (or pass the whole section_offsets stuff
- down ONE MORE function call level, which we really don't want
- to do). */
- {
- const char *p;
-
- /* Normal object file and NLMs have non-zero text seg offsets,
- but don't need their static syms offset in this fashion.
- XXX - This is really a crock that should be fixed in the
- solib handling code so that I don't have to work around it
- here. */
-
- if (!key->ctx.symfile_relocatable)
- {
- p = strchr (name, ':');
- if (p != 0 && p[1] == 'S')
- {
- /* The linker relocated it. We don't want to add a
- Sun-stabs Tfoo.foo-like offset, but we *do*
- want to add whatever solib.c passed to
- symbol_file_add as addr (this is known to affect
- SunOS 4, and I suspect ELF too). Since there is no
- Ttext.text symbol, we can get addr from the text offset. */
- section_index = SECT_OFF_TEXT (objfile);
- valu += section_offsets[SECT_OFF_TEXT (objfile)];
- goto define_a_symbol;
- }
- }
- /* Since it's not the kludge case, re-dispatch to the right
- handler. */
- switch (type)
- {
- case N_STSYM:
- goto case_N_STSYM;
- case N_LCSYM:
- goto case_N_LCSYM;
- case N_ROSYM:
- goto case_N_ROSYM;
- default:
- internal_error (_("failed internal consistency check"));
- }
- }
-
- case_N_STSYM: /* Static symbol in data segment. */
- case N_DSLINE: /* Source line number, data segment. */
- section_index = SECT_OFF_DATA (objfile);
- valu += section_offsets[SECT_OFF_DATA (objfile)];
- goto define_a_symbol;
-
- case_N_LCSYM: /* Static symbol in BSS segment. */
- case N_BSLINE: /* Source line number, BSS segment. */
- /* N_BROWS: overlaps with N_BSLINE. */
- section_index = SECT_OFF_BSS (objfile);
- valu += section_offsets[SECT_OFF_BSS (objfile)];
- goto define_a_symbol;
-
- case_N_ROSYM: /* Static symbol in read-only data segment. */
- section_index = SECT_OFF_RODATA (objfile);
- valu += section_offsets[SECT_OFF_RODATA (objfile)];
- goto define_a_symbol;
-
- case N_ENTRY: /* Alternate entry point. */
- /* Relocate for dynamic loading. */
- section_index = SECT_OFF_TEXT (objfile);
- valu += section_offsets[SECT_OFF_TEXT (objfile)];
- goto define_a_symbol;
-
- /* The following symbol types we don't know how to process.
- Handle them in a "default" way, but complain to people who
- care. */
- default:
- case N_CATCH: /* Exception handler catcher. */
- case N_EHDECL: /* Exception handler name. */
- case N_PC: /* Global symbol in Pascal. */
- case N_M2C: /* Modula-2 compilation unit. */
- /* N_MOD2: overlaps with N_EHDECL. */
- case N_SCOPE: /* Modula-2 scope information. */
- case N_ECOML: /* End common (local name). */
- case N_NBTEXT: /* Gould Non-Base-Register symbols??? */
- case N_NBDATA:
- case N_NBBSS:
- case N_NBSTS:
- case N_NBLCS:
- unknown_symtype_complaint (hex_string (type));
-
- define_a_symbol:
- [[fallthrough]];
- /* These symbol types don't need the address field relocated,
- since it is either unused, or is absolute. */
- case N_GSYM: /* Global variable. */
- case N_NSYMS: /* Number of symbols (Ultrix). */
- case N_NOMAP: /* No map? (Ultrix). */
- case N_RSYM: /* Register variable. */
- case N_DEFD: /* Modula-2 GNU module dependency. */
- case N_SSYM: /* Struct or union element. */
- case N_LSYM: /* Local symbol in stack. */
- case N_PSYM: /* Parameter variable. */
- case N_LENG: /* Length of preceding symbol type. */
- if (name)
- {
- int deftype;
- const char *colon_pos = strchr (name, ':');
-
- if (colon_pos == NULL)
- deftype = '\0';
- else
- deftype = colon_pos[1];
-
- switch (deftype)
- {
- case 'f':
- case 'F':
- /* Deal with the SunPRO 3.0 compiler which omits the
- address from N_FUN symbols. */
- if (type == N_FUN
- && valu == section_offsets[SECT_OFF_TEXT (objfile)]
- && gdbarch_sofun_address_maybe_missing (gdbarch))
- {
- bound_minimal_symbol minsym
- = find_stab_function (name, get_last_source_file (),
- objfile);
- if (minsym.minsym != NULL)
- valu = minsym.value_address ();
- }
-
- /* These addresses are absolute. */
- function_start_offset = valu;
-
- within_function = 1;
-
- if (get_context_stack_depth () > 1)
- {
- complaint (_("unmatched N_LBRAC before symtab pos %d"),
- symnum);
- break;
- }
-
- if (!outermost_context_p ())
- {
- struct block *block;
-
- cstk = pop_context ();
- /* Make a block for the local symbols within. */
- block = finish_block (cstk.name,
- cstk.old_blocks, NULL,
- cstk.start_addr, valu);
-
- /* For C++, set the block's scope. */
- if (cstk.name->language () == language_cplus)
- cp_set_block_scope (cstk.name, block,
- &objfile->objfile_obstack);
- }
-
- newobj = push_context (0, valu);
- newobj->name = define_symbol (valu, name, desc, type, objfile);
- if (newobj->name != nullptr)
- newobj->name->set_section_index (section_index);
- break;
-
- default:
- {
- struct symbol *sym = define_symbol (valu, name, desc, type,
- objfile);
- if (sym != nullptr)
- sym->set_section_index (section_index);
- }
- break;
- }
- }
- break;
-
- /* We use N_OPT to carry the gcc2_compiled flag. Sun uses it
- for a bunch of other flags, too. Someday we may parse their
- flags; for now we ignore theirs and hope they'll ignore ours. */
- case N_OPT: /* Solaris 2: Compiler options. */
- if (name)
- {
- if (strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0)
- {
- processing_gcc_compilation = 2;
- }
- else
- n_opt_found = 1;
- }
- break;
-
- case N_MAIN: /* Name of main routine. */
- /* FIXME: If one has a symbol file with N_MAIN and then replaces
- it with a symbol file with "main" and without N_MAIN. I'm
- not sure exactly what rule to follow but probably something
- like: N_MAIN takes precedence over "main" no matter what
- objfile it is in; If there is more than one N_MAIN, choose
- the one in the symfile_objfile; If there is more than one
- N_MAIN within a given objfile, complain() and choose
- arbitrarily. (kingdon) */
- if (name != NULL)
- set_objfile_main_name (objfile, name, language_unknown);
- break;
-
- /* The following symbol types can be ignored. */
- case N_OBJ: /* Solaris 2: Object file dir and name. */
- case N_PATCH: /* Solaris 2: Patch Run Time Checker. */
- /* N_UNDF: Solaris 2: File separator mark. */
- /* N_UNDF: -- we will never encounter it, since we only process
- one file's symbols at once. */
- case N_ENDM: /* Solaris 2: End of module. */
- case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
- break;
- }
-
- /* '#' is a GNU C extension to allow one symbol to refer to another
- related symbol.
-
- Generally this is used so that an alias can refer to its main
- symbol. */
- gdb_assert (name);
- if (name[0] == '#')
- {
- /* Initialize symbol reference names and determine if this is a
- definition. If a symbol reference is being defined, go ahead
- and add it. Otherwise, just return. */
-
- const char *s = name;
- int refnum;
-
- /* If this stab defines a new reference ID that is not on the
- reference list, then put it on the reference list.
-
- We go ahead and advance NAME past the reference, even though
- it is not strictly necessary at this time. */
- refnum = symbol_reference_defined (&s);
- if (refnum >= 0)
- if (!ref_search (refnum))
- ref_add (refnum, 0, name, valu);
- name = s;
- }
-
- previous_stab_code = type;
-}
-
-#define VISIBILITY_PRIVATE '0' /* Stabs character for private field */
-#define VISIBILITY_PROTECTED '1' /* Stabs character for protected fld */
-#define VISIBILITY_PUBLIC '2' /* Stabs character for public field */
-#define VISIBILITY_IGNORE '9' /* Optimized out or zero length */
-
-/* Structure for storing pointers to reference definitions for fast lookup
- during "process_later". */
-
-struct ref_map
-{
- const char *stabs;
- CORE_ADDR value;
- struct symbol *sym;
-};
-
-#define MAX_CHUNK_REFS 100
-#define REF_CHUNK_SIZE (MAX_CHUNK_REFS * sizeof (struct ref_map))
-#define REF_MAP_SIZE(ref_chunk) ((ref_chunk) * REF_CHUNK_SIZE)
-
-static struct ref_map *ref_map;
-
-/* Ptr to free cell in chunk's linked list. */
-static int ref_count = 0;
-
-/* Number of chunks malloced. */
-static int ref_chunk = 0;
-
-/* This file maintains a cache of stabs aliases found in the symbol
- table. If the symbol table changes, this cache must be cleared
- or we are left holding onto data in invalid obstacks. */
-void
-stabsread_clear_cache (void)
-{
- ref_count = 0;
- ref_chunk = 0;
-}
-
-/* Create array of pointers mapping refids to symbols and stab strings.
- Add pointers to reference definition symbols and/or their values as we
- find them, using their reference numbers as our index.
- These will be used later when we resolve references. */
-void
-ref_add (int refnum, struct symbol *sym, const char *stabs, CORE_ADDR value)
-{
- if (ref_count == 0)
- ref_chunk = 0;
- if (refnum >= ref_count)
- ref_count = refnum + 1;
- if (ref_count > ref_chunk * MAX_CHUNK_REFS)
- {
- int new_slots = ref_count - ref_chunk * MAX_CHUNK_REFS;
- int new_chunks = new_slots / MAX_CHUNK_REFS + 1;
-
- ref_map = (struct ref_map *)
- xrealloc (ref_map, REF_MAP_SIZE (ref_chunk + new_chunks));
- memset (ref_map + ref_chunk * MAX_CHUNK_REFS, 0,
- new_chunks * REF_CHUNK_SIZE);
- ref_chunk += new_chunks;
- }
- ref_map[refnum].stabs = stabs;
- ref_map[refnum].sym = sym;
- ref_map[refnum].value = value;
-}
-
-/* Return defined sym for the reference REFNUM. */
-struct symbol *
-ref_search (int refnum)
-{
- if (refnum < 0 || refnum > ref_count)
- return 0;
- return ref_map[refnum].sym;
-}
-
-/* Parse a reference id in STRING and return the resulting
- reference number. Move STRING beyond the reference id. */
-
-static int
-process_reference (const char **string)
-{
- const char *p;
- int refnum = 0;
-
- if (**string != '#')
- return 0;
-
- /* Advance beyond the initial '#'. */
- p = *string + 1;
-
- /* Read number as reference id. */
- while (*p && c_isdigit (*p))
- {
- refnum = refnum * 10 + *p - '0';
- p++;
- }
- *string = p;
- return refnum;
-}
-
-/* If STRING defines a reference, store away a pointer to the reference
- definition for later use. Return the reference number. */
-
-int
-symbol_reference_defined (const char **string)
-{
- const char *p = *string;
- int refnum = 0;
-
- refnum = process_reference (&p);
-
- /* Defining symbols end in '='. */
- if (*p == '=')
- {
- /* Symbol is being defined here. */
- *string = p + 1;
- return refnum;
- }
- else
- {
- /* Must be a reference. Either the symbol has already been defined,
- or this is a forward reference to it. */
- *string = p;
- return -1;
- }
-}
-
-static int
-stab_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
-{
- int regno = gdbarch_stab_reg_to_regnum (gdbarch, sym->value_longest ());
-
- if (regno < 0 || regno >= gdbarch_num_cooked_regs (gdbarch))
- {
- reg_value_complaint (regno, gdbarch_num_cooked_regs (gdbarch),
- sym->print_name ());
-
- regno = gdbarch_sp_regnum (gdbarch); /* Known safe, though useless. */
- }
-
- return regno;
-}
-
-static const struct symbol_register_ops stab_register_funcs = {
- stab_reg_to_regnum
-};
-
-/* The "loc_class" indices for computed symbols. */
-
-static int stab_register_index;
-static int stab_regparm_index;
-
-struct symbol *
-define_symbol (CORE_ADDR valu, const char *string, int desc, int type,
- struct objfile *objfile)
-{
- struct gdbarch *gdbarch = objfile->arch ();
- struct symbol *sym;
- const char *p = find_name_end (string);
- int deftype;
- int synonym = 0;
- int i;
-
- /* We would like to eliminate nameless symbols, but keep their types.
- E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer
- to type 2, but, should not create a symbol to address that type. Since
- the symbol will be nameless, there is no way any user can refer to it. */
-
- int nameless;
-
- /* Ignore syms with empty names. */
- if (string[0] == 0)
- return 0;
-
- /* Ignore old-style symbols from cc -go. */
- if (p == 0)
- return 0;
-
- while (p[1] == ':')
- {
- p += 2;
- p = strchr (p, ':');
- if (p == NULL)
- {
- complaint (
- _("Bad stabs string '%s'"), string);
- return NULL;
- }
- }
-
- /* If a nameless stab entry, all we need is the type, not the symbol.
- e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */
- nameless = (p == string || ((string[0] == ' ') && (string[1] == ':')));
-
- current_symbol = sym = new (&objfile->objfile_obstack) symbol;
-
- if (processing_gcc_compilation)
- {
- /* GCC 2.x puts the line number in desc. SunOS apparently puts in the
- number of bytes occupied by a type or object, which we ignore. */
- sym->set_line (desc);
- }
- else
- {
- sym->set_line (0); /* unknown */
- }
-
- sym->set_language (get_current_subfile ()->language,
- &objfile->objfile_obstack);
-
- if (is_cplus_marker (string[0]))
- {
- /* Special GNU C++ names. */
- switch (string[1])
- {
- case 't':
- sym->set_linkage_name ("this");
- break;
-
- case 'v': /* $vtbl_ptr_type */
- goto normal;
-
- case 'e':
- sym->set_linkage_name ("eh_throw");
- break;
-
- case '_':
- /* This was an anonymous type that was never fixed up. */
- goto normal;
-
- default:
- complaint (_("Unknown C++ symbol name `%s'"),
- string);
- goto normal; /* Do *something* with it. */
- }
- }
- else
- {
- normal:
- gdb::unique_xmalloc_ptr<char> new_name;
-
- if (sym->language () == language_cplus)
- {
- std::string name (string, p - string);
- new_name = cp_canonicalize_string (name.c_str ());
- }
- else if (sym->language () == language_c)
- {
- std::string name (string, p - string);
- new_name = c_canonicalize_name (name.c_str ());
- }
- if (new_name != nullptr)
- sym->compute_and_set_names (new_name.get (), true, objfile->per_bfd);
- else
- sym->compute_and_set_names (std::string_view (string, p - string), true,
- objfile->per_bfd);
-
- if (sym->language () == language_cplus)
- cp_scan_for_anonymous_namespaces (get_buildsym_compunit (), sym,
- objfile);
-
- }
- p++;
-
- /* Determine the type of name being defined. */
-#if 0
- /* Getting GDB to correctly skip the symbol on an undefined symbol
- descriptor and not ever dump core is a very dodgy proposition if
- we do things this way. I say the acorn RISC machine can just
- fix their compiler. */
- /* The Acorn RISC machine's compiler can put out locals that don't
- start with "234=" or "(3,4)=", so assume anything other than the
- deftypes we know how to handle is a local. */
- if (!strchr ("cfFGpPrStTvVXCR", *p))
-#else
- if (c_isdigit (*p) || *p == '(' || *p == '-')
-#endif
- deftype = 'l';
- else
- deftype = *p++;
-
- switch (deftype)
- {
- case 'c':
- /* c is a special case, not followed by a type-number.
- SYMBOL:c=iVALUE for an integer constant symbol.
- SYMBOL:c=rVALUE for a floating constant symbol.
- SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
- e.g. "b:c=e6,0" for "const b = blob1"
- (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
- if (*p != '=')
- {
- sym->set_loc_class_index (LOC_CONST);
- sym->set_type (error_type (&p, objfile));
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_file_symbols ());
- return sym;
- }
- ++p;
- switch (*p++)
- {
- case 'r':
- {
- gdb_byte *dbl_valu;
- struct type *dbl_type;
-
- dbl_type = builtin_type (objfile)->builtin_double;
- dbl_valu
- = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack,
- dbl_type->length ());
-
- target_float_from_string (dbl_valu, dbl_type, std::string (p));
-
- sym->set_type (dbl_type);
- sym->set_value_bytes (dbl_valu);
- sym->set_loc_class_index (LOC_CONST_BYTES);
- }
- break;
- case 'i':
- {
- /* Defining integer constants this way is kind of silly,
- since 'e' constants allows the compiler to give not
- only the value, but the type as well. C has at least
- int, long, unsigned int, and long long as constant
- types; other languages probably should have at least
- unsigned as well as signed constants. */
-
- sym->set_type (builtin_type (objfile)->builtin_long);
- sym->set_value_longest (atoi (p));
- sym->set_loc_class_index (LOC_CONST);
- }
- break;
-
- case 'c':
- {
- sym->set_type (builtin_type (objfile)->builtin_char);
- sym->set_value_longest (atoi (p));
- sym->set_loc_class_index (LOC_CONST);
- }
- break;
-
- case 's':
- {
- struct type *range_type;
- int ind = 0;
- char quote = *p++;
- gdb_byte *string_local = (gdb_byte *) alloca (strlen (p));
- gdb_byte *string_value;
-
- if (quote != '\'' && quote != '"')
- {
- sym->set_loc_class_index (LOC_CONST);
- sym->set_type (error_type (&p, objfile));
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_file_symbols ());
- return sym;
- }
-
- /* Find matching quote, rejecting escaped quotes. */
- while (*p && *p != quote)
- {
- if (*p == '\\' && p[1] == quote)
- {
- string_local[ind] = (gdb_byte) quote;
- ind++;
- p += 2;
- }
- else if (*p)
- {
- string_local[ind] = (gdb_byte) (*p);
- ind++;
- p++;
- }
- }
- if (*p != quote)
- {
- sym->set_loc_class_index (LOC_CONST);
- sym->set_type (error_type (&p, objfile));
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_file_symbols ());
- return sym;
- }
-
- /* NULL terminate the string. */
- string_local[ind] = 0;
- type_allocator alloc (objfile, get_current_subfile ()->language);
- range_type
- = create_static_range_type (alloc,
- builtin_type (objfile)->builtin_int,
- 0, ind);
- sym->set_type
- (create_array_type (alloc, builtin_type (objfile)->builtin_char,
- range_type));
- string_value
- = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, ind + 1);
- memcpy (string_value, string_local, ind + 1);
- p++;
-
- sym->set_value_bytes (string_value);
- sym->set_loc_class_index (LOC_CONST_BYTES);
- }
- break;
-
- case 'e':
- /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
- can be represented as integral.
- e.g. "b:c=e6,0" for "const b = blob1"
- (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
- {
- sym->set_loc_class_index (LOC_CONST);
- sym->set_type (read_type (&p, objfile));
-
- if (*p != ',')
- {
- sym->set_type (error_type (&p, objfile));
- break;
- }
- ++p;
-
- /* If the value is too big to fit in an int (perhaps because
- it is unsigned), or something like that, we silently get
- a bogus value. The type and everything else about it is
- correct. Ideally, we should be using whatever we have
- available for parsing unsigned and long long values,
- however. */
- sym->set_value_longest (atoi (p));
- }
- break;
- default:
- {
- sym->set_loc_class_index (LOC_CONST);
- sym->set_type (error_type (&p, objfile));
- }
- }
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_file_symbols ());
- return sym;
-
- case 'C':
- /* The name of a caught exception. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_LABEL);
- sym->set_domain (VAR_DOMAIN);
- sym->set_value_address (valu);
- add_symbol_to_list (sym, get_local_symbols ());
- break;
-
- case 'f':
- /* A static function definition. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_BLOCK);
- sym->set_domain (FUNCTION_DOMAIN);
- add_symbol_to_list (sym, get_file_symbols ());
- /* fall into process_function_types. */
-
- process_function_types:
- /* Function result types are described as the result type in stabs.
- We need to convert this to the function-returning-type-X type
- in GDB. E.g. "int" is converted to "function returning int". */
- if (sym->type ()->code () != TYPE_CODE_FUNC)
- sym->set_type (lookup_function_type (sym->type ()));
-
- /* All functions in C++ have prototypes. Stabs does not offer an
- explicit way to identify prototyped or unprototyped functions,
- but both GCC and Sun CC emit stabs for the "call-as" type rather
- than the "declared-as" type for unprototyped functions, so
- we treat all functions as if they were prototyped. This is used
- primarily for promotion when calling the function from GDB. */
- sym->type ()->set_is_prototyped (true);
-
- /* fall into process_prototype_types. */
-
- process_prototype_types:
- /* Sun acc puts declared types of arguments here. */
- if (*p == ';')
- {
- struct type *ftype = sym->type ();
- int nsemi = 0;
- int nparams = 0;
- const char *p1 = p;
-
- /* Obtain a worst case guess for the number of arguments
- by counting the semicolons. */
- while (*p1)
- {
- if (*p1++ == ';')
- nsemi++;
- }
-
- /* Allocate parameter information fields and fill them in. */
- ftype->alloc_fields (nsemi);
- while (*p++ == ';')
- {
- struct type *ptype;
-
- /* A type number of zero indicates the start of varargs.
- FIXME: GDB currently ignores vararg functions. */
- if (p[0] == '0' && p[1] == '\0')
- break;
- ptype = read_type (&p, objfile);
-
- /* The Sun compilers mark integer arguments, which should
- be promoted to the width of the calling conventions, with
- a type which references itself. This type is turned into
- a TYPE_CODE_VOID type by read_type, and we have to turn
- it back into builtin_int here.
- FIXME: Do we need a new builtin_promoted_int_arg ? */
- if (ptype->code () == TYPE_CODE_VOID)
- ptype = builtin_type (objfile)->builtin_int;
- ftype->field (nparams).set_type (ptype);
- ftype->field (nparams).set_is_artificial (false);
- nparams++;
- }
- ftype->set_num_fields (nparams);
- ftype->set_is_prototyped (true);
- }
- break;
-
- case 'F':
- /* A global function definition. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_BLOCK);
- sym->set_domain (FUNCTION_DOMAIN);
- add_symbol_to_list (sym, get_global_symbols ());
- goto process_function_types;
-
- case 'G':
- /* For a class G (global) symbol, it appears that the
- value is not correct. It is necessary to search for the
- corresponding linker definition to find the value.
- These definitions appear at the end of the namelist. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_STATIC);
- sym->set_domain (VAR_DOMAIN);
- /* Don't add symbol references to global_sym_chain.
- Symbol references don't have valid names and won't match up with
- minimal symbols when the global_sym_chain is relocated.
- We'll fixup symbol references when we fixup the defining symbol. */
- if (sym->linkage_name () && sym->linkage_name ()[0] != '#')
- {
- i = hashname (sym->linkage_name ());
- sym->set_value_chain (global_sym_chain[i]);
- global_sym_chain[i] = sym;
- }
- add_symbol_to_list (sym, get_global_symbols ());
- break;
-
- /* This case is faked by a conditional above,
- when there is no code letter in the dbx data.
- Dbx data never actually contains 'l'. */
- case 's':
- case 'l':
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_LOCAL);
- sym->set_value_longest (valu);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_local_symbols ());
- break;
-
- case 'p':
- if (*p == 'F')
- /* pF is a two-letter code that means a function parameter in Fortran.
- The type-number specifies the type of the return value.
- Translate it into a pointer-to-function type. */
- {
- p++;
- sym->set_type
- (lookup_pointer_type
- (lookup_function_type (read_type (&p, objfile))));
- }
- else
- sym->set_type (read_type (&p, objfile));
-
- sym->set_loc_class_index (LOC_ARG);
- sym->set_value_longest (valu);
- sym->set_domain (VAR_DOMAIN);
- sym->set_is_argument (1);
- add_symbol_to_list (sym, get_local_symbols ());
-
- if (gdbarch_byte_order (gdbarch) != BFD_ENDIAN_BIG)
- {
- /* On little-endian machines, this crud is never necessary,
- and, if the extra bytes contain garbage, is harmful. */
- break;
- }
-
- /* If it's gcc-compiled, if it says `short', believe it. */
- if (processing_gcc_compilation
- || gdbarch_believe_pcc_promotion (gdbarch))
- break;
-
- if (!gdbarch_believe_pcc_promotion (gdbarch))
- {
- /* If PCC says a parameter is a short or a char, it is
- really an int. */
- if (sym->type ()->length ()
- < gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT
- && sym->type ()->code () == TYPE_CODE_INT)
- {
- sym->set_type
- (sym->type ()->is_unsigned ()
- ? builtin_type (objfile)->builtin_unsigned_int
- : builtin_type (objfile)->builtin_int);
- }
- break;
- }
- [[fallthrough]];
-
- case 'P':
- /* acc seems to use P to declare the prototypes of functions that
- are referenced by this file. gdb is not prepared to deal
- with this extra information. FIXME, it ought to. */
- if (type == N_FUN)
- {
- sym->set_type (read_type (&p, objfile));
- goto process_prototype_types;
- }
- [[fallthrough]];
-
- case 'R':
- /* Parameter which is in a register. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (stab_register_index);
- sym->set_is_argument (1);
- sym->set_value_longest (valu);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_local_symbols ());
- break;
-
- case 'r':
- /* Register variable (either global or local). */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (stab_register_index);
- sym->set_value_longest (valu);
- sym->set_domain (VAR_DOMAIN);
- if (within_function)
- {
- /* Sun cc uses a pair of symbols, one 'p' and one 'r', with
- the same name to represent an argument passed in a
- register. GCC uses 'P' for the same case. So if we find
- such a symbol pair we combine it into one 'P' symbol.
- For Sun cc we need to do this regardless of stabs_argument_has_addr, because the compiler puts out
- the 'p' symbol even if it never saves the argument onto
- the stack.
-
- On most machines, we want to preserve both symbols, so
- that we can still get information about what is going on
- with the stack (VAX for computing args_printed, using
- stack slots instead of saved registers in backtraces,
- etc.).
-
- Note that this code illegally combines
- main(argc) struct foo argc; { register struct foo argc; }
- but this case is considered pathological and causes a warning
- from a decent compiler. */
-
- struct pending *local_symbols = *get_local_symbols ();
- if (local_symbols
- && local_symbols->nsyms > 0
- && gdbarch_stabs_argument_has_addr (gdbarch, sym->type ()))
- {
- struct symbol *prev_sym;
-
- prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
- if ((prev_sym->loc_class () == LOC_REF_ARG
- || prev_sym->loc_class () == LOC_ARG)
- && strcmp (prev_sym->linkage_name (),
- sym->linkage_name ()) == 0)
- {
- prev_sym->set_loc_class_index (stab_register_index);
- /* Use the type from the LOC_REGISTER; that is the type
- that is actually in that register. */
- prev_sym->set_type (sym->type ());
- prev_sym->set_value_longest (sym->value_longest ());
- sym = prev_sym;
- break;
- }
- }
- add_symbol_to_list (sym, get_local_symbols ());
- }
- else
- add_symbol_to_list (sym, get_file_symbols ());
- break;
-
- case 'S':
- /* Static symbol at top level of file. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_STATIC);
- sym->set_value_address (valu);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_file_symbols ());
- break;
-
- case 't':
- /* In Ada, there is no distinction between typedef and non-typedef;
- any type declaration implicitly has the equivalent of a typedef,
- and thus 't' is in fact equivalent to 'Tt'.
-
- Therefore, for Ada units, we check the character immediately
- before the 't', and if we do not find a 'T', then make sure to
- create the associated symbol in the STRUCT_DOMAIN ('t' definitions
- will be stored in the VAR_DOMAIN). If the symbol was indeed
- defined as 'Tt' then the STRUCT_DOMAIN symbol will be created
- elsewhere, so we don't need to take care of that.
-
- This is important to do, because of forward references:
- The cleanup of undefined types stored in undef_types only uses
- STRUCT_DOMAIN symbols to perform the replacement. */
- synonym = (sym->language () == language_ada && p[-2] != 'T');
-
- /* Typedef */
- sym->set_type (read_type (&p, objfile));
-
- /* For a nameless type, we don't want a create a symbol, thus we
- did not use `sym'. Return without further processing. */
- if (nameless)
- return NULL;
-
- sym->set_loc_class_index (LOC_TYPEDEF);
- sym->set_value_longest (valu);
- sym->set_domain (TYPE_DOMAIN);
- /* C++ vagaries: we may have a type which is derived from
- a base type which did not have its name defined when the
- derived class was output. We fill in the derived class's
- base part member's name here in that case. */
- if (sym->type ()->name () != NULL)
- if ((sym->type ()->code () == TYPE_CODE_STRUCT
- || sym->type ()->code () == TYPE_CODE_UNION)
- && TYPE_N_BASECLASSES (sym->type ()))
- {
- int j;
-
- for (j = TYPE_N_BASECLASSES (sym->type ()) - 1; j >= 0; j--)
- if (TYPE_BASECLASS_NAME (sym->type (), j) == 0)
- sym->type ()->field (j).set_name
- (TYPE_BASECLASS (sym->type (), j)->name ());
- }
-
- if (sym->type ()->name () == NULL)
- {
- if ((sym->type ()->code () == TYPE_CODE_PTR
- && strcmp (sym->linkage_name (), vtbl_ptr_name))
- || sym->type ()->code () == TYPE_CODE_FUNC)
- {
- /* If we are giving a name to a type such as "pointer to
- foo" or "function returning foo", we better not set
- the TYPE_NAME. If the program contains "typedef char
- *caddr_t;", we don't want all variables of type char
- * to print as caddr_t. This is not just a
- consequence of GDB's type management; PCC and GCC (at
- least through version 2.4) both output variables of
- either type char * or caddr_t with the type number
- defined in the 't' symbol for caddr_t. If a future
- compiler cleans this up it GDB is not ready for it
- yet, but if it becomes ready we somehow need to
- disable this check (without breaking the PCC/GCC2.4
- case).
-
- Sigh.
-
- Fortunately, this check seems not to be necessary
- for anything except pointers or functions. */
- /* ezannoni: 2000-10-26. This seems to apply for
- versions of gcc older than 2.8. This was the original
- problem: with the following code gdb would tell that
- the type for name1 is caddr_t, and func is char().
-
- typedef char *caddr_t;
- char *name2;
- struct x
- {
- char *name1;
- } xx;
- char *func()
- {
- }
- main () {}
- */
-
- /* Pascal accepts names for pointer types. */
- if (get_current_subfile ()->language == language_pascal)
- sym->type ()->set_name (sym->linkage_name ());
- }
- else
- sym->type ()->set_name (sym->linkage_name ());
- }
-
- add_symbol_to_list (sym, get_file_symbols ());
-
- if (synonym)
- {
- /* Create the STRUCT_DOMAIN clone. */
- struct symbol *struct_sym = new (&objfile->objfile_obstack) symbol;
-
- *struct_sym = *sym;
- struct_sym->set_loc_class_index (LOC_TYPEDEF);
- struct_sym->set_value_longest (valu);
- struct_sym->set_domain (STRUCT_DOMAIN);
- if (sym->type ()->name () == 0)
- sym->type ()->set_name
- (obconcat (&objfile->objfile_obstack, sym->linkage_name (),
- (char *) NULL));
- add_symbol_to_list (struct_sym, get_file_symbols ());
- }
-
- break;
-
- case 'T':
- /* Struct, union, or enum tag. For GNU C++, this can be be followed
- by 't' which means we are typedef'ing it as well. */
- synonym = *p == 't';
-
- if (synonym)
- p++;
-
- sym->set_type (read_type (&p, objfile));
-
- /* For a nameless type, we don't want a create a symbol, thus we
- did not use `sym'. Return without further processing. */
- if (nameless)
- return NULL;
-
- sym->set_loc_class_index (LOC_TYPEDEF);
- sym->set_value_longest (valu);
- sym->set_domain (STRUCT_DOMAIN);
- if (sym->type ()->name () == 0)
- sym->type ()->set_name
- (obconcat (&objfile->objfile_obstack, sym->linkage_name (),
- (char *) NULL));
- add_symbol_to_list (sym, get_file_symbols ());
-
- if (synonym)
- {
- /* Clone the sym and then modify it. */
- struct symbol *typedef_sym = new (&objfile->objfile_obstack) symbol;
-
- *typedef_sym = *sym;
- typedef_sym->set_loc_class_index (LOC_TYPEDEF);
- typedef_sym->set_value_longest (valu);
- typedef_sym->set_domain (TYPE_DOMAIN);
- if (sym->type ()->name () == 0)
- sym->type ()->set_name
- (obconcat (&objfile->objfile_obstack, sym->linkage_name (),
- (char *) NULL));
- add_symbol_to_list (typedef_sym, get_file_symbols ());
- }
- break;
-
- case 'V':
- /* Static symbol of local scope. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_STATIC);
- sym->set_value_address (valu);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_local_symbols ());
- break;
-
- case 'v':
- /* Reference parameter */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_REF_ARG);
- sym->set_is_argument (1);
- sym->set_value_longest (valu);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_local_symbols ());
- break;
-
- case 'a':
- /* Reference parameter which is in a register. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (stab_regparm_index);
- sym->set_is_argument (1);
- sym->set_value_longest (valu);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_local_symbols ());
- break;
-
- case 'X':
- /* This is used by Sun FORTRAN for "function result value".
- Sun claims ("dbx and dbxtool interfaces", 2nd ed)
- that Pascal uses it too, but when I tried it Pascal used
- "x:3" (local symbol) instead. */
- sym->set_type (read_type (&p, objfile));
- sym->set_loc_class_index (LOC_LOCAL);
- sym->set_value_longest (valu);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_local_symbols ());
- break;
-
- default:
- sym->set_type (error_type (&p, objfile));
- sym->set_loc_class_index (LOC_CONST);
- sym->set_value_longest (0);
- sym->set_domain (VAR_DOMAIN);
- add_symbol_to_list (sym, get_file_symbols ());
- break;
- }
-
- /* Some systems pass variables of certain types by reference instead
- of by value, i.e. they will pass the address of a structure (in a
- register or on the stack) instead of the structure itself. */
-
- if (gdbarch_stabs_argument_has_addr (gdbarch, sym->type ())
- && sym->is_argument ())
- {
- /* We have to convert LOC_REGISTER to LOC_REGPARM_ADDR (for
- variables passed in a register). */
- if (sym->loc_class () == LOC_REGISTER)
- sym->set_loc_class_index (LOC_REGPARM_ADDR);
- /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th
- and subsequent arguments on SPARC, for example). */
- else if (sym->loc_class () == LOC_ARG)
- sym->set_loc_class_index (LOC_REF_ARG);
- }
-
- return sym;
-}
-
-/* Skip rest of this symbol and return an error type.
-
- General notes on error recovery: error_type always skips to the
- end of the symbol (modulo cretinous dbx symbol name continuation).
- Thus code like this:
-
- if (*(*pp)++ != ';')
- return error_type (pp, objfile);
-
- is wrong because if *pp starts out pointing at '\0' (typically as the
- result of an earlier error), it will be incremented to point to the
- start of the next symbol, which might produce strange results, at least
- if you run off the end of the string table. Instead use
-
- if (**pp != ';')
- return error_type (pp, objfile);
- ++*pp;
-
- or
-
- if (**pp != ';')
- foo = error_type (pp, objfile);
- else
- ++*pp;
-
- And in case it isn't obvious, the point of all this hair is so the compiler
- can define new types and new syntaxes, and old versions of the
- debugger will be able to read the new symbol tables. */
-
-static struct type *
-error_type (const char **pp, struct objfile *objfile)
-{
- complaint (_("couldn't parse type; debugger out of date?"));
- while (1)
- {
- /* Skip to end of symbol. */
- while (**pp != '\0')
- {
- (*pp)++;
- }
-
- /* Check for and handle cretinous dbx symbol name continuation! */
- if ((*pp)[-1] == '\\' || (*pp)[-1] == '?')
- {
- *pp = next_symbol_text (objfile);
- }
- else
- {
- break;
- }
- }
- return builtin_type (objfile)->builtin_error;
-}
-\f
-
-/* Allocate a stub method whose return type is TYPE. This apparently
- happens for speed of symbol reading, since parsing out the
- arguments to the method is cpu-intensive, the way we are doing it.
- So, we will fill in arguments later. This always returns a fresh
- type. */
-
-static struct type *
-allocate_stub_method (struct type *type)
-{
- struct type *mtype;
-
- mtype = type_allocator (type).new_type ();
- mtype->set_code (TYPE_CODE_METHOD);
- mtype->set_length (1);
- mtype->set_is_stub (true);
- mtype->set_target_type (type);
- /* TYPE_SELF_TYPE (mtype) = unknown yet */
- return mtype;
-}
-
-/* Read type information or a type definition; return the type. Even
- though this routine accepts either type information or a type
- definition, the distinction is relevant--some parts of stabsread.c
- assume that type information starts with a digit, '-', or '(' in
- deciding whether to call read_type. */
-
-static struct type *
-read_type (const char **pp, struct objfile *objfile)
-{
- struct type *type = 0;
- struct type *type1;
- int typenums[2];
- char type_descriptor;
-
- /* Size in bits of type if specified by a type attribute, or -1 if
- there is no size attribute. */
- int type_size = -1;
-
- /* Used to distinguish string and bitstring from char-array and set. */
- int is_string = 0;
-
- /* Used to distinguish vector from array. */
- int is_vector = 0;
-
- /* Read type number if present. The type number may be omitted.
- for instance in a two-dimensional array declared with type
- "ar1;1;10;ar1;1;10;4". */
- if ((**pp >= '0' && **pp <= '9')
- || **pp == '('
- || **pp == '-')
- {
- if (read_type_number (pp, typenums) != 0)
- return error_type (pp, objfile);
-
- if (**pp != '=')
- {
- /* Type is not being defined here. Either it already
- exists, or this is a forward reference to it.
- dbx_alloc_type handles both cases. */
- type = dbx_alloc_type (typenums, objfile);
-
- /* If this is a forward reference, arrange to complain if it
- doesn't get patched up by the time we're done
- reading. */
- if (type->code () == TYPE_CODE_UNDEF)
- add_undefined_type (type, typenums);
-
- return type;
- }
-
- /* Type is being defined here. */
- /* Skip the '='.
- Also skip the type descriptor - we get it below with (*pp)[-1]. */
- (*pp) += 2;
- }
- else
- {
- /* 'typenums=' not present, type is anonymous. Read and return
- the definition, but don't put it in the type vector. */
- typenums[0] = typenums[1] = -1;
- (*pp)++;
- }
-
-again:
- type_descriptor = (*pp)[-1];
- switch (type_descriptor)
- {
- case 'x':
- {
- enum type_code code;
-
- /* Used to index through file_symbols. */
- struct pending *ppt;
- int i;
-
- /* Name including "struct", etc. */
- char *type_name;
-
- {
- const char *from, *p, *q1, *q2;
-
- /* Set the type code according to the following letter. */
- switch ((*pp)[0])
- {
- case 's':
- code = TYPE_CODE_STRUCT;
- break;
- case 'u':
- code = TYPE_CODE_UNION;
- break;
- case 'e':
- code = TYPE_CODE_ENUM;
- break;
- default:
- {
- /* Complain and keep going, so compilers can invent new
- cross-reference types. */
- complaint (_("Unrecognized cross-reference type `%c'"),
- (*pp)[0]);
- code = TYPE_CODE_STRUCT;
- break;
- }
- }
-
- q1 = strchr (*pp, '<');
- p = strchr (*pp, ':');
- if (p == NULL)
- return error_type (pp, objfile);
- if (q1 && p > q1 && p[1] == ':')
- {
- int nesting_level = 0;
-
- for (q2 = q1; *q2; q2++)
- {
- if (*q2 == '<')
- nesting_level++;
- else if (*q2 == '>')
- nesting_level--;
- else if (*q2 == ':' && nesting_level == 0)
- break;
- }
- p = q2;
- if (*p != ':')
- return error_type (pp, objfile);
- }
- type_name = NULL;
- if (get_current_subfile ()->language == language_cplus)
- {
- std::string name (*pp, p - *pp);
- gdb::unique_xmalloc_ptr<char> new_name
- = cp_canonicalize_string (name.c_str ());
- if (new_name != nullptr)
- type_name = obstack_strdup (&objfile->objfile_obstack,
- new_name.get ());
- }
- else if (get_current_subfile ()->language == language_c)
- {
- std::string name (*pp, p - *pp);
- gdb::unique_xmalloc_ptr<char> new_name
- = c_canonicalize_name (name.c_str ());
- if (new_name != nullptr)
- type_name = obstack_strdup (&objfile->objfile_obstack,
- new_name.get ());
- }
- if (type_name == NULL)
- {
- char *to = type_name = (char *)
- obstack_alloc (&objfile->objfile_obstack, p - *pp + 1);
-
- /* Copy the name. */
- from = *pp + 1;
- while (from < p)
- *to++ = *from++;
- *to = '\0';
- }
-
- /* Set the pointer ahead of the name which we just read, and
- the colon. */
- *pp = p + 1;
- }
-
- /* If this type has already been declared, then reuse the same
- type, rather than allocating a new one. This saves some
- memory. */
-
- for (ppt = *get_file_symbols (); ppt; ppt = ppt->next)
- for (i = 0; i < ppt->nsyms; i++)
- {
- struct symbol *sym = ppt->symbol[i];
-
- if (sym->loc_class () == LOC_TYPEDEF
- && sym->domain () == STRUCT_DOMAIN
- && (sym->type ()->code () == code)
- && strcmp (sym->linkage_name (), type_name) == 0)
- {
- obstack_free (&objfile->objfile_obstack, type_name);
- type = sym->type ();
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums, objfile) = type;
- return type;
- }
- }
-
- /* Didn't find the type to which this refers, so we must
- be dealing with a forward reference. Allocate a type
- structure for it, and keep track of it so we can
- fill in the rest of the fields when we get the full
- type. */
- type = dbx_alloc_type (typenums, objfile);
- type->set_code (code);
- type->set_name (type_name);
- INIT_CPLUS_SPECIFIC (type);
- type->set_is_stub (true);
-
- add_undefined_type (type, typenums);
- return type;
- }
-
- case '-': /* RS/6000 built-in type */
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '(':
- (*pp)--;
-
- /* We deal with something like t(1,2)=(3,4)=... which
- the Lucid compiler and recent gcc versions (post 2.7.3) use. */
-
- /* Allocate and enter the typedef type first.
- This handles recursive types. */
- type = dbx_alloc_type (typenums, objfile);
- type->set_code (TYPE_CODE_TYPEDEF);
- {
- struct type *xtype = read_type (pp, objfile);
-
- if (type == xtype)
- {
- /* It's being defined as itself. That means it is "void". */
- type->set_code (TYPE_CODE_VOID);
- type->set_length (1);
- }
- else if (type_size >= 0 || is_string)
- {
- /* This is the absolute wrong way to construct types. Every
- other debug format has found a way around this problem and
- the related problems with unnecessarily stubbed types;
- someone motivated should attempt to clean up the issue
- here as well. Once a type pointed to has been created it
- should not be modified.
-
- Well, it's not *absolutely* wrong. Constructing recursive
- types (trees, linked lists) necessarily entails modifying
- types after creating them. Constructing any loop structure
- entails side effects. The Dwarf 2 reader does handle this
- more gracefully (it never constructs more than once
- instance of a type object, so it doesn't have to copy type
- objects wholesale), but it still mutates type objects after
- other folks have references to them.
-
- Keep in mind that this circularity/mutation issue shows up
- at the source language level, too: C's "incomplete types",
- for example. So the proper cleanup, I think, would be to
- limit GDB's type smashing to match exactly those required
- by the source language. So GDB could have a
- "complete_this_type" function, but never create unnecessary
- copies of a type otherwise. */
- replace_type (type, xtype);
- type->set_name (NULL);
- }
- else
- {
- type->set_target_is_stub (true);
- type->set_target_type (xtype);
- }
- }
- break;
-
- /* In the following types, we must be sure to overwrite any existing
- type that the typenums refer to, rather than allocating a new one
- and making the typenums point to the new one. This is because there
- may already be pointers to the existing type (if it had been
- forward-referenced), and we must change it to a pointer, function,
- reference, or whatever, *in-place*. */
-
- case '*': /* Pointer to another type */
- type1 = read_type (pp, objfile);
- type = make_pointer_type (type1, dbx_lookup_type (typenums, objfile));
- break;
-
- case '&': /* Reference to another type */
- type1 = read_type (pp, objfile);
- type = make_reference_type (type1, dbx_lookup_type (typenums, objfile),
- TYPE_CODE_REF);
- break;
-
- case 'f': /* Function returning another type */
- type1 = read_type (pp, objfile);
- type = make_function_type (type1, dbx_lookup_type (typenums, objfile));
- break;
-
- case 'g': /* Prototyped function. (Sun) */
- {
- /* Unresolved questions:
-
- - According to Sun's ``STABS Interface Manual'', for 'f'
- and 'F' symbol descriptors, a `0' in the argument type list
- indicates a varargs function. But it doesn't say how 'g'
- type descriptors represent that info. Someone with access
- to Sun's toolchain should try it out.
-
- - According to the comment in define_symbol (search for
- `process_prototype_types:'), Sun emits integer arguments as
- types which ref themselves --- like `void' types. Do we
- have to deal with that here, too? Again, someone with
- access to Sun's toolchain should try it out and let us
- know. */
-
- const char *type_start = (*pp) - 1;
- struct type *return_type = read_type (pp, objfile);
- struct type *func_type
- = make_function_type (return_type,
- dbx_lookup_type (typenums, objfile));
- struct type_list {
- struct type *type;
- struct type_list *next;
- } *arg_types = 0;
- int num_args = 0;
-
- while (**pp && **pp != '#')
- {
- struct type *arg_type = read_type (pp, objfile);
- struct type_list *newobj = XALLOCA (struct type_list);
- newobj->type = arg_type;
- newobj->next = arg_types;
- arg_types = newobj;
- num_args++;
- }
- if (**pp == '#')
- ++*pp;
- else
- {
- complaint (_("Prototyped function type didn't "
- "end arguments with `#':\n%s"),
- type_start);
- }
-
- /* If there is just one argument whose type is `void', then
- that's just an empty argument list. */
- if (arg_types
- && ! arg_types->next
- && arg_types->type->code () == TYPE_CODE_VOID)
- num_args = 0;
-
- func_type->alloc_fields (num_args);
- {
- int i;
- struct type_list *t;
-
- /* We stuck each argument type onto the front of the list
- when we read it, so the list is reversed. Build the
- fields array right-to-left. */
- for (t = arg_types, i = num_args - 1; t; t = t->next, i--)
- func_type->field (i).set_type (t->type);
- }
- func_type->set_num_fields (num_args);
- func_type->set_is_prototyped (true);
-
- type = func_type;
- break;
- }
-
- case 'k': /* Const qualifier on some type (Sun) */
- type = read_type (pp, objfile);
- type = make_cv_type (1, TYPE_VOLATILE (type), type,
- dbx_lookup_type (typenums, objfile));
- break;
-
- case 'B': /* Volatile qual on some type (Sun) */
- type = read_type (pp, objfile);
- type = make_cv_type (TYPE_CONST (type), 1, type,
- dbx_lookup_type (typenums, objfile));
- break;
-
- case '@':
- if (c_isdigit (**pp) || **pp == '(' || **pp == '-')
- { /* Member (class & variable) type */
- /* FIXME -- we should be doing smash_to_XXX types here. */
-
- struct type *domain = read_type (pp, objfile);
- struct type *memtype;
-
- if (**pp != ',')
- /* Invalid member type data format. */
- return error_type (pp, objfile);
- ++*pp;
-
- memtype = read_type (pp, objfile);
- type = dbx_alloc_type (typenums, objfile);
- smash_to_memberptr_type (type, domain, memtype);
- }
- else
- /* type attribute */
- {
- const char *attr = *pp;
-
- /* Skip to the semicolon. */
- while (**pp != ';' && **pp != '\0')
- ++(*pp);
- if (**pp == '\0')
- return error_type (pp, objfile);
- else
- ++ * pp; /* Skip the semicolon. */
-
- switch (*attr)
- {
- case 's': /* Size attribute */
- type_size = atoi (attr + 1);
- if (type_size <= 0)
- type_size = -1;
- break;
-
- case 'S': /* String attribute */
- /* FIXME: check to see if following type is array? */
- is_string = 1;
- break;
-
- case 'V': /* Vector attribute */
- /* FIXME: check to see if following type is array? */
- is_vector = 1;
- break;
-
- default:
- /* Ignore unrecognized type attributes, so future compilers
- can invent new ones. */
- break;
- }
- ++*pp;
- goto again;
- }
- break;
-
- case '#': /* Method (class & fn) type */
- if ((*pp)[0] == '#')
- {
- /* We'll get the parameter types from the name. */
- struct type *return_type;
-
- (*pp)++;
- return_type = read_type (pp, objfile);
- if (*(*pp)++ != ';')
- complaint (_("invalid (minimal) member type "
- "data format at symtab pos %d."),
- symnum);
- type = allocate_stub_method (return_type);
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums, objfile) = type;
- }
- else
- {
- struct type *domain = read_type (pp, objfile);
- struct type *return_type;
- struct field *args;
- int nargs, varargs;
-
- if (**pp != ',')
- /* Invalid member type data format. */
- return error_type (pp, objfile);
- else
- ++(*pp);
-
- return_type = read_type (pp, objfile);
- args = read_args (pp, ';', objfile, &nargs, &varargs);
- if (args == NULL)
- return error_type (pp, objfile);
- type = dbx_alloc_type (typenums, objfile);
- smash_to_method_type (type, domain, return_type,
- gdb::make_array_view (args, nargs),
- varargs);
- }
- break;
-
- case 'r': /* Range type */
- type = read_range_type (pp, typenums, type_size, objfile);
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums, objfile) = type;
- break;
-
- case 'b':
- {
- /* Sun ACC builtin int type */
- type = read_sun_builtin_type (pp, typenums, objfile);
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums, objfile) = type;
- }
- break;
-
- case 'R': /* Sun ACC builtin float type */
- type = read_sun_floating_type (pp, typenums, objfile);
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums, objfile) = type;
- break;
-
- case 'e': /* Enumeration type */
- type = dbx_alloc_type (typenums, objfile);
- type = read_enum_type (pp, type, objfile);
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums, objfile) = type;
- break;
-
- case 's': /* Struct type */
- case 'u': /* Union type */
- {
- enum type_code type_code = TYPE_CODE_UNDEF;
- type = dbx_alloc_type (typenums, objfile);
- switch (type_descriptor)
- {
- case 's':
- type_code = TYPE_CODE_STRUCT;
- break;
- case 'u':
- type_code = TYPE_CODE_UNION;
- break;
- }
- type = read_struct_type (pp, type, type_code, objfile);
- break;
- }
-
- case 'a': /* Array type */
- if (**pp != 'r')
- return error_type (pp, objfile);
- ++*pp;
-
- type = dbx_alloc_type (typenums, objfile);
- type = read_array_type (pp, type, objfile);
- if (is_string)
- type->set_code (TYPE_CODE_STRING);
- if (is_vector)
- make_vector_type (type);
- break;
-
- case 'S': /* Set type */
- {
- type1 = read_type (pp, objfile);
- type_allocator alloc (objfile, get_current_subfile ()->language);
- type = create_set_type (alloc, type1);
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums, objfile) = type;
- }
- break;
-
- default:
- --*pp; /* Go back to the symbol in error. */
- /* Particularly important if it was \0! */
- return error_type (pp, objfile);
- }
-
- if (type == 0)
- {
- warning (_("GDB internal error, type is NULL in stabsread.c."));
- return error_type (pp, objfile);
- }
-
- /* Size specified in a type attribute overrides any other size. */
- if (type_size != -1)
- type->set_length ((type_size + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT);
-
- return type;
-}
-\f
-/* RS/6000 xlc/dbx combination uses a set of builtin types, starting from -1.
- Return the proper type node for a given builtin type number. */
-
-static const registry<objfile>::key<struct type *,
- gdb::noop_deleter<struct type *>>
- rs6000_builtin_type_data;
-
-static struct type *
-rs6000_builtin_type (int typenum, struct objfile *objfile)
-{
- struct type **negative_types = rs6000_builtin_type_data.get (objfile);
-
- /* We recognize types numbered from -NUMBER_RECOGNIZED to -1. */
-#define NUMBER_RECOGNIZED 34
- struct type *rettype = NULL;
-
- if (typenum >= 0 || typenum < -NUMBER_RECOGNIZED)
- {
- complaint (_("Unknown builtin type %d"), typenum);
- return builtin_type (objfile)->builtin_error;
- }
-
- if (!negative_types)
- {
- /* This includes an empty slot for type number -0. */
- negative_types = OBSTACK_CALLOC (&objfile->objfile_obstack,
- NUMBER_RECOGNIZED + 1, struct type *);
- rs6000_builtin_type_data.set (objfile, negative_types);
- }
-
- if (negative_types[-typenum] != NULL)
- return negative_types[-typenum];
-
-#if TARGET_CHAR_BIT != 8
-#error This code wrong for TARGET_CHAR_BIT not 8
- /* These definitions all assume that TARGET_CHAR_BIT is 8. I think
- that if that ever becomes not true, the correct fix will be to
- make the size in the struct type to be in bits, not in units of
- TARGET_CHAR_BIT. */
-#endif
-
- type_allocator alloc (objfile, get_current_subfile ()->language);
- switch (-typenum)
- {
- case 1:
- /* The size of this and all the other types are fixed, defined
- by the debugging format. If there is a type called "int" which
- is other than 32 bits, then it should use a new negative type
- number (or avoid negative type numbers for that case).
- See stabs.texinfo. */
- rettype = init_integer_type (alloc, 32, 0, "int");
- break;
- case 2:
- rettype = init_integer_type (alloc, 8, 0, "char");
- rettype->set_has_no_signedness (true);
- break;
- case 3:
- rettype = init_integer_type (alloc, 16, 0, "short");
- break;
- case 4:
- rettype = init_integer_type (alloc, 32, 0, "long");
- break;
- case 5:
- rettype = init_integer_type (alloc, 8, 1, "unsigned char");
- break;
- case 6:
- rettype = init_integer_type (alloc, 8, 0, "signed char");
- break;
- case 7:
- rettype = init_integer_type (alloc, 16, 1, "unsigned short");
- break;
- case 8:
- rettype = init_integer_type (alloc, 32, 1, "unsigned int");
- break;
- case 9:
- rettype = init_integer_type (alloc, 32, 1, "unsigned");
- break;
- case 10:
- rettype = init_integer_type (alloc, 32, 1, "unsigned long");
- break;
- case 11:
- rettype = alloc.new_type (TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
- break;
- case 12:
- /* IEEE single precision (32 bit). */
- rettype = init_float_type (alloc, 32, "float",
- floatformats_ieee_single);
- break;
- case 13:
- /* IEEE double precision (64 bit). */
- rettype = init_float_type (alloc, 64, "double",
- floatformats_ieee_double);
- break;
- case 14:
- /* This is an IEEE double on the RS/6000, and different machines with
- different sizes for "long double" should use different negative
- type numbers. See stabs.texinfo. */
- rettype = init_float_type (alloc, 64, "long double",
- floatformats_ieee_double);
- break;
- case 15:
- rettype = init_integer_type (alloc, 32, 0, "integer");
- break;
- case 16:
- rettype = init_boolean_type (alloc, 32, 1, "boolean");
- break;
- case 17:
- rettype = init_float_type (alloc, 32, "short real",
- floatformats_ieee_single);
- break;
- case 18:
- rettype = init_float_type (alloc, 64, "real",
- floatformats_ieee_double);
- break;
- case 19:
- rettype = alloc.new_type (TYPE_CODE_ERROR, 0, "stringptr");
- break;
- case 20:
- rettype = init_character_type (alloc, 8, 1, "character");
- break;
- case 21:
- rettype = init_boolean_type (alloc, 8, 1, "logical*1");
- break;
- case 22:
- rettype = init_boolean_type (alloc, 16, 1, "logical*2");
- break;
- case 23:
- rettype = init_boolean_type (alloc, 32, 1, "logical*4");
- break;
- case 24:
- rettype = init_boolean_type (alloc, 32, 1, "logical");
- break;
- case 25:
- /* Complex type consisting of two IEEE single precision values. */
- rettype = init_complex_type ("complex",
- rs6000_builtin_type (12, objfile));
- break;
- case 26:
- /* Complex type consisting of two IEEE double precision values. */
- rettype = init_complex_type ("double complex",
- rs6000_builtin_type (13, objfile));
- break;
- case 27:
- rettype = init_integer_type (alloc, 8, 0, "integer*1");
- break;
- case 28:
- rettype = init_integer_type (alloc, 16, 0, "integer*2");
- break;
- case 29:
- rettype = init_integer_type (alloc, 32, 0, "integer*4");
- break;
- case 30:
- rettype = init_character_type (alloc, 16, 0, "wchar");
- break;
- case 31:
- rettype = init_integer_type (alloc, 64, 0, "long long");
- break;
- case 32:
- rettype = init_integer_type (alloc, 64, 1, "unsigned long long");
- break;
- case 33:
- rettype = init_integer_type (alloc, 64, 1, "logical*8");
- break;
- case 34:
- rettype = init_integer_type (alloc, 64, 0, "integer*8");
- break;
- }
- negative_types[-typenum] = rettype;
- return rettype;
-}
-\f
-/* This page contains subroutines of read_type. */
-
-/* Wrapper around method_name_from_physname to flag a complaint
- if there is an error. */
-
-static char *
-stabs_method_name_from_physname (const char *physname)
-{
- char *method_name;
-
- method_name = method_name_from_physname (physname);
-
- if (method_name == NULL)
- {
- complaint (_("Method has bad physname %s\n"), physname);
- return NULL;
- }
-
- return method_name;
-}
-
-/* Read member function stabs info for C++ classes. The form of each member
- function data is:
-
- NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
-
- An example with two member functions is:
-
- afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
-
- For the case of overloaded operators, the format is op$::*.funcs, where
- $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
- name (such as `+=') and `.' marks the end of the operator name.
-
- Returns 1 for success, 0 for failure. */
-
-static int
-read_member_functions (struct stab_field_info *fip, const char **pp,
- struct type *type, struct objfile *objfile)
-{
- int nfn_fields = 0;
- int length = 0;
- int i;
- struct next_fnfield
- {
- struct next_fnfield *next;
- struct fn_field fn_field;
- }
- *sublist;
- struct type *look_ahead_type;
- struct next_fnfieldlist *new_fnlist;
- struct next_fnfield *new_sublist;
- char *main_fn_name;
- const char *p;
-
- /* Process each list until we find something that is not a member function
- or find the end of the functions. */
-
- while (**pp != ';')
- {
- /* We should be positioned at the start of the function name.
- Scan forward to find the first ':' and if it is not the
- first of a "::" delimiter, then this is not a member function. */
- p = *pp;
- while (*p != ':')
- {
- p++;
- }
- if (p[1] != ':')
- {
- break;
- }
-
- sublist = NULL;
- look_ahead_type = NULL;
- length = 0;
-
- new_fnlist = OBSTACK_ZALLOC (&fip->obstack, struct next_fnfieldlist);
-
- if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && is_cplus_marker ((*pp)[2]))
- {
- /* This is a completely weird case. In order to stuff in the
- names that might contain colons (the usual name delimiter),
- Mike Tiemann defined a different name format which is
- signalled if the identifier is "op$". In that case, the
- format is "op$::XXXX." where XXXX is the name. This is
- used for names like "+" or "=". YUUUUUUUK! FIXME! */
- /* This lets the user type "break operator+".
- We could just put in "+" as the name, but that wouldn't
- work for "*". */
- static char opname[32] = "op$";
- char *o = opname + 3;
-
- /* Skip past '::'. */
- *pp = p + 2;
-
- STABS_CONTINUE (pp, objfile);
- p = *pp;
- while (*p != '.')
- {
- *o++ = *p++;
- }
- main_fn_name = savestring (opname, o - opname);
- /* Skip past '.' */
- *pp = p + 1;
- }
- else
- {
- main_fn_name = savestring (*pp, p - *pp);
- /* Skip past '::'. */
- *pp = p + 2;
- }
- new_fnlist->fn_fieldlist.name = main_fn_name;
-
- do
- {
- new_sublist = OBSTACK_ZALLOC (&fip->obstack, struct next_fnfield);
-
- /* Check for and handle cretinous dbx symbol name continuation! */
- if (look_ahead_type == NULL)
- {
- /* Normal case. */
- STABS_CONTINUE (pp, objfile);
-
- new_sublist->fn_field.type = read_type (pp, objfile);
- if (**pp != ':')
- {
- /* Invalid symtab info for member function. */
- return 0;
- }
- }
- else
- {
- /* g++ version 1 kludge */
- new_sublist->fn_field.type = look_ahead_type;
- look_ahead_type = NULL;
- }
-
- (*pp)++;
- p = *pp;
- while (*p != ';')
- {
- p++;
- }
-
- /* These are methods, not functions. */
- if (new_sublist->fn_field.type->code () == TYPE_CODE_FUNC)
- new_sublist->fn_field.type->set_code (TYPE_CODE_METHOD);
-
- /* If this is just a stub, then we don't have the real name here. */
- if (new_sublist->fn_field.type->is_stub ())
- {
- if (!TYPE_SELF_TYPE (new_sublist->fn_field.type))
- set_type_self_type (new_sublist->fn_field.type, type);
- new_sublist->fn_field.is_stub = 1;
- }
-
- new_sublist->fn_field.physname = savestring (*pp, p - *pp);
- *pp = p + 1;
-
- /* Set this member function's visibility fields. */
- switch (*(*pp)++)
- {
- case VISIBILITY_PRIVATE:
- new_sublist->fn_field.accessibility = accessibility::PRIVATE;
- break;
- case VISIBILITY_PROTECTED:
- new_sublist->fn_field.accessibility = accessibility::PROTECTED;
- break;
- }
-
- STABS_CONTINUE (pp, objfile);
- switch (**pp)
- {
- case 'A': /* Normal functions. */
- new_sublist->fn_field.is_const = 0;
- new_sublist->fn_field.is_volatile = 0;
- (*pp)++;
- break;
- case 'B': /* `const' member functions. */
- new_sublist->fn_field.is_const = 1;
- new_sublist->fn_field.is_volatile = 0;
- (*pp)++;
- break;
- case 'C': /* `volatile' member function. */
- new_sublist->fn_field.is_const = 0;
- new_sublist->fn_field.is_volatile = 1;
- (*pp)++;
- break;
- case 'D': /* `const volatile' member function. */
- new_sublist->fn_field.is_const = 1;
- new_sublist->fn_field.is_volatile = 1;
- (*pp)++;
- break;
- case '*': /* File compiled with g++ version 1 --
- no info. */
- case '?':
- case '.':
- break;
- default:
- complaint (_("const/volatile indicator missing, got '%c'"),
- **pp);
- break;
- }
-
- switch (*(*pp)++)
- {
- case '*':
- {
- int nbits;
- /* virtual member function, followed by index.
- The sign bit is set to distinguish pointers-to-methods
- from virtual function indices. Since the array is
- in words, the quantity must be shifted left by 1
- on 16 bit machine, and by 2 on 32 bit machine, forcing
- the sign bit out, and usable as a valid index into
- the array. Remove the sign bit here. */
- new_sublist->fn_field.voffset =
- (0x7fffffff & read_huge_number (pp, ';', &nbits, 0)) + 2;
- if (nbits != 0)
- return 0;
-
- STABS_CONTINUE (pp, objfile);
- if (**pp == ';' || **pp == '\0')
- {
- /* Must be g++ version 1. */
- new_sublist->fn_field.fcontext = 0;
- }
- else
- {
- /* Figure out from whence this virtual function came.
- It may belong to virtual function table of
- one of its baseclasses. */
- look_ahead_type = read_type (pp, objfile);
- if (**pp == ':')
- {
- /* g++ version 1 overloaded methods. */
- }
- else
- {
- new_sublist->fn_field.fcontext = look_ahead_type;
- if (**pp != ';')
- {
- return 0;
- }
- else
- {
- ++*pp;
- }
- look_ahead_type = NULL;
- }
- }
- break;
- }
- case '?':
- /* static member function. */
- {
- int slen = strlen (main_fn_name);
-
- new_sublist->fn_field.voffset = VOFFSET_STATIC;
-
- /* For static member functions, we can't tell if they
- are stubbed, as they are put out as functions, and not as
- methods.
- GCC v2 emits the fully mangled name if
- dbxout.c:flag_minimal_debug is not set, so we have to
- detect a fully mangled physname here and set is_stub
- accordingly. Fully mangled physnames in v2 start with
- the member function name, followed by two underscores.
- GCC v3 currently always emits stubbed member functions,
- but with fully mangled physnames, which start with _Z. */
- if (!(strncmp (new_sublist->fn_field.physname,
- main_fn_name, slen) == 0
- && new_sublist->fn_field.physname[slen] == '_'
- && new_sublist->fn_field.physname[slen + 1] == '_'))
- {
- new_sublist->fn_field.is_stub = 1;
- }
- break;
- }
-
- default:
- /* error */
- complaint (_("member function type missing, got '%c'"),
- (*pp)[-1]);
- /* Normal member function. */
- [[fallthrough]];
-
- case '.':
- /* normal member function. */
- new_sublist->fn_field.voffset = 0;
- new_sublist->fn_field.fcontext = 0;
- break;
- }
-
- new_sublist->next = sublist;
- sublist = new_sublist;
- length++;
- STABS_CONTINUE (pp, objfile);
- }
- while (**pp != ';' && **pp != '\0');
-
- (*pp)++;
- STABS_CONTINUE (pp, objfile);
-
- /* Skip GCC 3.X member functions which are duplicates of the callable
- constructor/destructor. */
- if (strcmp_iw (main_fn_name, "__base_ctor ") == 0
- || strcmp_iw (main_fn_name, "__base_dtor ") == 0
- || strcmp (main_fn_name, "__deleting_dtor") == 0)
- {
- xfree (main_fn_name);
- }
- else
- {
- int has_destructor = 0, has_other = 0;
- int is_v3 = 0;
- struct next_fnfield *tmp_sublist;
-
- /* Various versions of GCC emit various mostly-useless
- strings in the name field for special member functions.
-
- For stub methods, we need to defer correcting the name
- until we are ready to unstub the method, because the current
- name string is used by gdb_mangle_name. The only stub methods
- of concern here are GNU v2 operators; other methods have their
- names correct (see caveat below).
-
- For non-stub methods, in GNU v3, we have a complete physname.
- Therefore we can safely correct the name now. This primarily
- affects constructors and destructors, whose name will be
- __comp_ctor or __comp_dtor instead of Foo or ~Foo. Cast
- operators will also have incorrect names; for instance,
- "operator int" will be named "operator i" (i.e. the type is
- mangled).
-
- For non-stub methods in GNU v2, we have no easy way to
- know if we have a complete physname or not. For most
- methods the result depends on the platform (if CPLUS_MARKER
- can be `$' or `.', it will use minimal debug information, or
- otherwise the full physname will be included).
-
- Rather than dealing with this, we take a different approach.
- For v3 mangled names, we can use the full physname; for v2,
- we use cplus_demangle_opname (which is actually v2 specific),
- because the only interesting names are all operators - once again
- barring the caveat below. Skip this process if any method in the
- group is a stub, to prevent our fouling up the workings of
- gdb_mangle_name.
-
- The caveat: GCC 2.95.x (and earlier?) put constructors and
- destructors in the same method group. We need to split this
- into two groups, because they should have different names.
- So for each method group we check whether it contains both
- routines whose physname appears to be a destructor (the physnames
- for and destructors are always provided, due to quirks in v2
- mangling) and routines whose physname does not appear to be a
- destructor. If so then we break up the list into two halves.
- Even if the constructors and destructors aren't in the same group
- the destructor will still lack the leading tilde, so that also
- needs to be fixed.
-
- So, to summarize what we expect and handle here:
-
- Given Given Real Real Action
- method name physname physname method name
-
- __opi [none] __opi__3Foo operator int opname
- [now or later]
- Foo _._3Foo _._3Foo ~Foo separate and
- rename
- operator i _ZN3FoocviEv _ZN3FoocviEv operator int demangle
- __comp_ctor _ZN3FooC1ERKS_ _ZN3FooC1ERKS_ Foo demangle
- */
-
- tmp_sublist = sublist;
- while (tmp_sublist != NULL)
- {
- if (tmp_sublist->fn_field.physname[0] == '_'
- && tmp_sublist->fn_field.physname[1] == 'Z')
- is_v3 = 1;
-
- if (is_destructor_name (tmp_sublist->fn_field.physname))
- has_destructor++;
- else
- has_other++;
-
- tmp_sublist = tmp_sublist->next;
- }
-
- if (has_destructor && has_other)
- {
- struct next_fnfieldlist *destr_fnlist;
- struct next_fnfield *last_sublist;
-
- /* Create a new fn_fieldlist for the destructors. */
-
- destr_fnlist = OBSTACK_ZALLOC (&fip->obstack,
- struct next_fnfieldlist);
-
- destr_fnlist->fn_fieldlist.name
- = obconcat (&objfile->objfile_obstack, "~",
- new_fnlist->fn_fieldlist.name, (char *) NULL);
-
- destr_fnlist->fn_fieldlist.fn_fields =
- XOBNEWVEC (&objfile->objfile_obstack,
- struct fn_field, has_destructor);
- memset (destr_fnlist->fn_fieldlist.fn_fields, 0,
- sizeof (struct fn_field) * has_destructor);
- tmp_sublist = sublist;
- last_sublist = NULL;
- i = 0;
- while (tmp_sublist != NULL)
- {
- if (!is_destructor_name (tmp_sublist->fn_field.physname))
- {
- tmp_sublist = tmp_sublist->next;
- continue;
- }
-
- destr_fnlist->fn_fieldlist.fn_fields[i++]
- = tmp_sublist->fn_field;
- if (last_sublist)
- last_sublist->next = tmp_sublist->next;
- else
- sublist = tmp_sublist->next;
- last_sublist = tmp_sublist;
- tmp_sublist = tmp_sublist->next;
- }
-
- destr_fnlist->fn_fieldlist.length = has_destructor;
- destr_fnlist->next = fip->fnlist;
- fip->fnlist = destr_fnlist;
- nfn_fields++;
- length -= has_destructor;
- }
- else if (is_v3)
- {
- /* v3 mangling prevents the use of abbreviated physnames,
- so we can do this here. There are stubbed methods in v3
- only:
- - in -gstabs instead of -gstabs+
- - or for static methods, which are output as a function type
- instead of a method type. */
- char *new_method_name =
- stabs_method_name_from_physname (sublist->fn_field.physname);
-
- if (new_method_name != NULL
- && strcmp (new_method_name,
- new_fnlist->fn_fieldlist.name) != 0)
- {
- new_fnlist->fn_fieldlist.name = new_method_name;
- xfree (main_fn_name);
- }
- else
- xfree (new_method_name);
- }
- else if (has_destructor && new_fnlist->fn_fieldlist.name[0] != '~')
- {
- new_fnlist->fn_fieldlist.name =
- obconcat (&objfile->objfile_obstack,
- "~", main_fn_name, (char *)NULL);
- xfree (main_fn_name);
- }
-
- new_fnlist->fn_fieldlist.fn_fields
- = OBSTACK_CALLOC (&objfile->objfile_obstack, length, fn_field);
- for (i = length; (i--, sublist); sublist = sublist->next)
- {
- new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field;
- }
-
- new_fnlist->fn_fieldlist.length = length;
- new_fnlist->next = fip->fnlist;
- fip->fnlist = new_fnlist;
- nfn_fields++;
- }
- }
-
- if (nfn_fields)
- {
- ALLOCATE_CPLUS_STRUCT_TYPE (type);
- TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
- TYPE_ZALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields);
- TYPE_NFN_FIELDS (type) = nfn_fields;
- }
-
- return 1;
-}
-
-/* Special GNU C++ name.
-
- Returns 1 for success, 0 for failure. "failure" means that we can't
- keep parsing and it's time for error_type(). */
-
-static int
-read_cpp_abbrev (struct stab_field_info *fip, const char **pp,
- struct type *type, struct objfile *objfile)
-{
- const char *p;
- const char *name;
- char cpp_abbrev;
- struct type *context;
-
- p = *pp;
- if (*++p == 'v')
- {
- name = NULL;
- cpp_abbrev = *++p;
-
- *pp = p + 1;
-
- /* At this point, *pp points to something like "22:23=*22...",
- where the type number before the ':' is the "context" and
- everything after is a regular type definition. Lookup the
- type, find it's name, and construct the field name. */
-
- context = read_type (pp, objfile);
-
- switch (cpp_abbrev)
- {
- case 'f': /* $vf -- a virtual function table pointer */
- name = context->name ();
- if (name == NULL)
- {
- name = "";
- }
- fip->list->field.set_name (obconcat (&objfile->objfile_obstack,
- vptr_name, name, (char *) NULL));
- break;
-
- case 'b': /* $vb -- a virtual bsomethingorother */
- name = context->name ();
- if (name == NULL)
- {
- complaint (_("C++ abbreviated type name "
- "unknown at symtab pos %d"),
- symnum);
- name = "FOO";
- }
- fip->list->field.set_name (obconcat (&objfile->objfile_obstack,
- vb_name, name, (char *) NULL));
- break;
-
- default:
- invalid_cpp_abbrev_complaint (*pp);
- fip->list->field.set_name (obconcat (&objfile->objfile_obstack,
- "INVALID_CPLUSPLUS_ABBREV",
- (char *) NULL));
- break;
- }
-
- /* At this point, *pp points to the ':'. Skip it and read the
- field type. */
-
- p = ++(*pp);
- if (p[-1] != ':')
- {
- invalid_cpp_abbrev_complaint (*pp);
- return 0;
- }
- fip->list->field.set_type (read_type (pp, objfile));
- if (**pp == ',')
- (*pp)++; /* Skip the comma. */
- else
- return 0;
-
- {
- int nbits;
-
- fip->list->field.set_loc_bitpos (read_huge_number (pp, ';', &nbits, 0));
- if (nbits != 0)
- return 0;
- }
- /* This field is unpacked. */
- fip->list->field.set_bitsize (0);
- fip->list->field.set_accessibility (accessibility::PRIVATE);
- }
- else
- {
- invalid_cpp_abbrev_complaint (*pp);
- /* We have no idea what syntax an unrecognized abbrev would have, so
- better return 0. If we returned 1, we would need to at least advance
- *pp to avoid an infinite loop. */
- return 0;
- }
- return 1;
-}
-
-static void
-read_one_struct_field (struct stab_field_info *fip, const char **pp,
- const char *p, struct type *type,
- struct objfile *objfile)
-{
- struct gdbarch *gdbarch = objfile->arch ();
-
- fip->list->field.set_name
- (obstack_strndup (&objfile->objfile_obstack, *pp, p - *pp));
- *pp = p + 1;
-
- /* This means we have a visibility for a field coming. */
- int visibility;
- if (**pp == '/')
- {
- (*pp)++;
- visibility = *(*pp)++;
- }
- else
- {
- /* normal dbx-style format, no explicit visibility */
- visibility = VISIBILITY_PUBLIC;
- }
-
- switch (visibility)
- {
- case VISIBILITY_PRIVATE:
- fip->list->field.set_accessibility (accessibility::PRIVATE);
- break;
-
- case VISIBILITY_PROTECTED:
- fip->list->field.set_accessibility (accessibility::PROTECTED);
- break;
-
- case VISIBILITY_IGNORE:
- fip->list->field.set_ignored ();
- break;
-
- case VISIBILITY_PUBLIC:
- break;
-
- default:
- /* Unknown visibility. Complain and treat it as public. */
- {
- complaint (_("Unknown visibility `%c' for field"),
- visibility);
- }
- break;
- }
-
- fip->list->field.set_type (read_type (pp, objfile));
- if (**pp == ':')
- {
- p = ++(*pp);
-#if 0
- /* Possible future hook for nested types. */
- if (**pp == '!')
- {
- fip->list->field.bitpos = (long) -2; /* nested type */
- p = ++(*pp);
- }
- else
- ...;
-#endif
- while (*p != ';')
- {
- p++;
- }
- /* Static class member. */
- fip->list->field.set_loc_physname (savestring (*pp, p - *pp));
- *pp = p + 1;
- return;
- }
- else if (**pp != ',')
- {
- /* Bad structure-type format. */
- stabs_general_complaint ("bad structure-type format");
- return;
- }
-
- (*pp)++; /* Skip the comma. */
-
- {
- int nbits;
-
- fip->list->field.set_loc_bitpos (read_huge_number (pp, ',', &nbits, 0));
- if (nbits != 0)
- {
- stabs_general_complaint ("bad structure-type format");
- return;
- }
- fip->list->field.set_bitsize (read_huge_number (pp, ';', &nbits, 0));
- if (nbits != 0)
- {
- stabs_general_complaint ("bad structure-type format");
- return;
- }
- }
-
- if (fip->list->field.loc_bitpos () == 0
- && fip->list->field.bitsize () == 0)
- {
- /* This can happen in two cases: (1) at least for gcc 2.4.5 or so,
- it is a field which has been optimized out. The correct stab for
- this case is to use VISIBILITY_IGNORE, but that is a recent
- invention. (2) It is a 0-size array. For example
- union { int num; char str[0]; } foo. Printing _("<no value>" for
- str in "p foo" is OK, since foo.str (and thus foo.str[3])
- will continue to work, and a 0-size array as a whole doesn't
- have any contents to print.
-
- I suspect this probably could also happen with gcc -gstabs (not
- -gstabs+) for static fields, and perhaps other C++ extensions.
- Hopefully few people use -gstabs with gdb, since it is intended
- for dbx compatibility. */
-
- /* Ignore this field. */
- fip->list->field.set_ignored ();
- }
- else
- {
- /* Detect an unpacked field and mark it as such.
- dbx gives a bit size for all fields.
- Note that forward refs cannot be packed,
- and treat enums as if they had the width of ints. */
-
- struct type *field_type = check_typedef (fip->list->field.type ());
-
- if (field_type->code () != TYPE_CODE_INT
- && field_type->code () != TYPE_CODE_RANGE
- && field_type->code () != TYPE_CODE_BOOL
- && field_type->code () != TYPE_CODE_ENUM)
- {
- fip->list->field.set_bitsize (0);
- }
- if ((fip->list->field.bitsize ()
- == TARGET_CHAR_BIT * field_type->length ()
- || (field_type->code () == TYPE_CODE_ENUM
- && (fip->list->field.bitsize ()
- == gdbarch_int_bit (gdbarch)))
- )
- &&
- fip->list->field.loc_bitpos () % 8 == 0)
- {
- fip->list->field.set_bitsize (0);
- }
- }
-}
-
-
-/* Read struct or class data fields. They have the form:
-
- NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
-
- At the end, we see a semicolon instead of a field.
-
- In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
- a static field.
-
- The optional VISIBILITY is one of:
-
- '/0' (VISIBILITY_PRIVATE)
- '/1' (VISIBILITY_PROTECTED)
- '/2' (VISIBILITY_PUBLIC)
- '/9' (VISIBILITY_IGNORE)
-
- or nothing, for C style fields with public visibility.
-
- Returns 1 for success, 0 for failure. */
-
-static int
-read_struct_fields (struct stab_field_info *fip, const char **pp,
- struct type *type, struct objfile *objfile)
-{
- const char *p;
- struct stabs_nextfield *newobj;
-
- /* We better set p right now, in case there are no fields at all... */
-
- p = *pp;
-
- /* Read each data member type until we find the terminating ';' at the end of
- the data member list, or break for some other reason such as finding the
- start of the member function list. */
- /* Stab string for structure/union does not end with two ';' in
- SUN C compiler 5.3 i.e. F6U2, hence check for end of string. */
-
- while (**pp != ';' && **pp != '\0')
- {
- STABS_CONTINUE (pp, objfile);
- /* Get space to record the next field's data. */
- newobj = OBSTACK_ZALLOC (&fip->obstack, struct stabs_nextfield);
-
- newobj->next = fip->list;
- fip->list = newobj;
-
- /* Get the field name. */
- p = *pp;
-
- /* If is starts with CPLUS_MARKER it is a special abbreviation,
- unless the CPLUS_MARKER is followed by an underscore, in
- which case it is just the name of an anonymous type, which we
- should handle like any other type name. */
-
- if (is_cplus_marker (p[0]) && p[1] != '_')
- {
- if (!read_cpp_abbrev (fip, pp, type, objfile))
- return 0;
- continue;
- }
-
- /* Look for the ':' that separates the field name from the field
- values. Data members are delimited by a single ':', while member
- functions are delimited by a pair of ':'s. When we hit the member
- functions (if any), terminate scan loop and return. */
-
- while (*p != ':' && *p != '\0')
- {
- p++;
- }
- if (*p == '\0')
- return 0;
-
- /* Check to see if we have hit the member functions yet. */
- if (p[1] == ':')
- {
- break;
- }
- read_one_struct_field (fip, pp, p, type, objfile);
- }
- if (p[0] == ':' && p[1] == ':')
- {
- /* (the deleted) chill the list of fields: the last entry (at
- the head) is a partially constructed entry which we now
- scrub. */
- fip->list = fip->list->next;
- }
- return 1;
-}
-/* The stabs for C++ derived classes contain baseclass information which
- is marked by a '!' character after the total size. This function is
- called when we encounter the baseclass marker, and slurps up all the
- baseclass information.
-
- Immediately following the '!' marker is the number of base classes that
- the class is derived from, followed by information for each base class.
- For each base class, there are two visibility specifiers, a bit offset
- to the base class information within the derived class, a reference to
- the type for the base class, and a terminating semicolon.
-
- A typical example, with two base classes, would be "!2,020,19;0264,21;".
- ^^ ^ ^ ^ ^ ^ ^
- Baseclass information marker __________________|| | | | | | |
- Number of baseclasses __________________________| | | | | | |
- Visibility specifiers (2) ________________________| | | | | |
- Offset in bits from start of class _________________| | | | |
- Type number for base class ___________________________| | | |
- Visibility specifiers (2) _______________________________| | |
- Offset in bits from start of class ________________________| |
- Type number of base class ____________________________________|
-
- Return 1 for success, 0 for (error-type-inducing) failure. */
-
-
-
-static int
-read_baseclasses (struct stab_field_info *fip, const char **pp,
- struct type *type, struct objfile *objfile)
-{
- int i;
- struct stabs_nextfield *newobj;
-
- if (**pp != '!')
- {
- return 1;
- }
- else
- {
- /* Skip the '!' baseclass information marker. */
- (*pp)++;
- }
-
- ALLOCATE_CPLUS_STRUCT_TYPE (type);
- {
- int nbits;
-
- TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits, 0);
- if (nbits != 0)
- return 0;
- }
-
- for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
- {
- newobj = OBSTACK_ZALLOC (&fip->obstack, struct stabs_nextfield);
-
- newobj->next = fip->list;
- fip->list = newobj;
- newobj->field.set_bitsize (0); /* This should be an unpacked
- field! */
-
- STABS_CONTINUE (pp, objfile);
- switch (**pp)
- {
- case '0':
- /* Nothing to do. */
- break;
- case '1':
- newobj->field.set_virtual ();
- break;
- default:
- /* Unknown character. Complain and treat it as non-virtual. */
- {
- complaint (_("Unknown virtual character `%c' for baseclass"),
- **pp);
- }
- }
- ++(*pp);
-
- int visibility = *(*pp)++;
- switch (visibility)
- {
- case VISIBILITY_PRIVATE:
- newobj->field.set_accessibility (accessibility::PRIVATE);
- break;
- case VISIBILITY_PROTECTED:
- newobj->field.set_accessibility (accessibility::PROTECTED);
- break;
- case VISIBILITY_PUBLIC:
- break;
- default:
- /* Bad visibility format. Complain and treat it as
- public. */
- {
- complaint (_("Unknown visibility `%c' for baseclass"),
- visibility);
- }
- }
-
- {
- int nbits;
-
- /* The remaining value is the bit offset of the portion of the object
- corresponding to this baseclass. Always zero in the absence of
- multiple inheritance. */
-
- newobj->field.set_loc_bitpos (read_huge_number (pp, ',', &nbits, 0));
- if (nbits != 0)
- return 0;
- }
-
- /* The last piece of baseclass information is the type of the
- base class. Read it, and remember it's type name as this
- field's name. */
-
- newobj->field.set_type (read_type (pp, objfile));
- newobj->field.set_name (newobj->field.type ()->name ());
-
- /* Skip trailing ';' and bump count of number of fields seen. */
- if (**pp == ';')
- (*pp)++;
- else
- return 0;
- }
- return 1;
-}
-
-/* The tail end of stabs for C++ classes that contain a virtual function
- pointer contains a tilde, a %, and a type number.
- The type number refers to the base class (possibly this class itself) which
- contains the vtable pointer for the current class.
-
- This function is called when we have parsed all the method declarations,
- so we can look for the vptr base class info. */
-
-static int
-read_tilde_fields (struct stab_field_info *fip, const char **pp,
- struct type *type, struct objfile *objfile)
-{
- const char *p;
-
- STABS_CONTINUE (pp, objfile);
-
- /* If we are positioned at a ';', then skip it. */
- if (**pp == ';')
- {
- (*pp)++;
- }
-
- if (**pp == '~')
- {
- (*pp)++;
-
- if (**pp == '=' || **pp == '+' || **pp == '-')
- {
- /* Obsolete flags that used to indicate the presence
- of constructors and/or destructors. */
- (*pp)++;
- }
-
- /* Read either a '%' or the final ';'. */
- if (*(*pp)++ == '%')
- {
- /* The next number is the type number of the base class
- (possibly our own class) which supplies the vtable for
- this class. Parse it out, and search that class to find
- its vtable pointer, and install those into TYPE_VPTR_BASETYPE
- and TYPE_VPTR_FIELDNO. */
-
- struct type *t;
- int i;
-
- t = read_type (pp, objfile);
- p = (*pp)++;
- while (*p != '\0' && *p != ';')
- {
- p++;
- }
- if (*p == '\0')
- {
- /* Premature end of symbol. */
- return 0;
- }
-
- set_type_vptr_basetype (type, t);
- if (type == t) /* Our own class provides vtbl ptr. */
- {
- for (i = t->num_fields () - 1;
- i >= TYPE_N_BASECLASSES (t);
- --i)
- {
- const char *name = t->field (i).name ();
-
- if (!strncmp (name, vptr_name, sizeof (vptr_name) - 2)
- && is_cplus_marker (name[sizeof (vptr_name) - 2]))
- {
- set_type_vptr_fieldno (type, i);
- goto gotit;
- }
- }
- /* Virtual function table field not found. */
- complaint (_("virtual function table pointer "
- "not found when defining class `%s'"),
- type->name ());
- return 0;
- }
- else
- {
- set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t));
- }
-
- gotit:
- *pp = p + 1;
- }
- }
- return 1;
-}
-
-static int
-attach_fn_fields_to_type (struct stab_field_info *fip, struct type *type)
-{
- int n;
-
- for (n = TYPE_NFN_FIELDS (type);
- fip->fnlist != NULL;
- fip->fnlist = fip->fnlist->next)
- {
- --n; /* Circumvent Sun3 compiler bug. */
- TYPE_FN_FIELDLISTS (type)[n] = fip->fnlist->fn_fieldlist;
- }
- return 1;
-}
-
-/* Create the vector of fields, and record how big it is.
- We need this info to record proper virtual function table information
- for this class's virtual functions. */
-
-static int
-attach_fields_to_type (struct stab_field_info *fip, struct type *type,
- struct objfile *objfile)
-{
- int nfields = 0;
- struct stabs_nextfield *scan;
-
- /* Count up the number of fields that we have. */
-
- for (scan = fip->list; scan != NULL; scan = scan->next)
- nfields++;
-
- /* Now we know how many fields there are, and whether or not there are any
- non-public fields. Record the field count, allocate space for the
- array of fields. */
-
- type->alloc_fields (nfields);
-
- /* Copy the saved-up fields into the field vector. Start from the
- head of the list, adding to the tail of the field array, so that
- they end up in the same order in the array in which they were
- added to the list. */
-
- while (nfields-- > 0)
- {
- type->field (nfields) = fip->list->field;
- fip->list = fip->list->next;
- }
- return 1;
-}
-
-
-/* Complain that the compiler has emitted more than one definition for the
- structure type TYPE. */
-static void
-complain_about_struct_wipeout (struct type *type)
-{
- const char *name = "";
- const char *kind = "";
-
- if (type->name ())
- {
- name = type->name ();
- switch (type->code ())
- {
- case TYPE_CODE_STRUCT: kind = "struct "; break;
- case TYPE_CODE_UNION: kind = "union "; break;
- case TYPE_CODE_ENUM: kind = "enum "; break;
- default: kind = "";
- }
- }
- else
- {
- name = "<unknown>";
- kind = "";
- }
-
- complaint (_("struct/union type gets multiply defined: %s%s"), kind, name);
-}
-
-/* Set the length for all variants of a same main_type, which are
- connected in the closed chain.
-
- This is something that needs to be done when a type is defined *after*
- some cross references to this type have already been read. Consider
- for instance the following scenario where we have the following two
- stabs entries:
-
- .stabs "t:p(0,21)=*(0,22)=k(0,23)=xsdummy:",160,0,28,-24
- .stabs "dummy:T(0,23)=s16x:(0,1),0,3[...]"
-
- A stubbed version of type dummy is created while processing the first
- stabs entry. The length of that type is initially set to zero, since
- it is unknown at this point. Also, a "constant" variation of type
- "dummy" is created as well (this is the "(0,22)=k(0,23)" section of
- the stabs line).
-
- The second stabs entry allows us to replace the stubbed definition
- with the real definition. However, we still need to adjust the length
- of the "constant" variation of that type, as its length was left
- untouched during the main type replacement... */
-
-static void
-set_length_in_type_chain (struct type *type)
-{
- struct type *ntype = TYPE_CHAIN (type);
-
- while (ntype != type)
- {
- if (ntype->length () == 0)
- ntype->set_length (type->length ());
- else
- complain_about_struct_wipeout (ntype);
- ntype = TYPE_CHAIN (ntype);
- }
-}
-
-/* Read the description of a structure (or union type) and return an object
- describing the type.
-
- PP points to a character pointer that points to the next unconsumed token
- in the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;",
- *PP will point to "4a:1,0,32;;".
-
- TYPE points to an incomplete type that needs to be filled in.
-
- OBJFILE points to the current objfile from which the stabs information is
- being read. (Note that it is redundant in that TYPE also contains a pointer
- to this same objfile, so it might be a good idea to eliminate it. FIXME).
- */
-
-static struct type *
-read_struct_type (const char **pp, struct type *type, enum type_code type_code,
- struct objfile *objfile)
-{
- struct stab_field_info fi;
-
- /* When describing struct/union/class types in stabs, G++ always drops
- all qualifications from the name. So if you've got:
- struct A { ... struct B { ... }; ... };
- then G++ will emit stabs for `struct A::B' that call it simply
- `struct B'. Obviously, if you've got a real top-level definition for
- `struct B', or other nested definitions, this is going to cause
- problems.
-
- Obviously, GDB can't fix this by itself, but it can at least avoid
- scribbling on existing structure type objects when new definitions
- appear. */
- if (! (type->code () == TYPE_CODE_UNDEF
- || type->is_stub ()))
- {
- complain_about_struct_wipeout (type);
-
- /* It's probably best to return the type unchanged. */
- return type;
- }
-
- INIT_CPLUS_SPECIFIC (type);
- type->set_code (type_code);
- type->set_is_stub (false);
-
- /* First comes the total size in bytes. */
-
- {
- int nbits;
-
- type->set_length (read_huge_number (pp, 0, &nbits, 0));
- if (nbits != 0)
- return error_type (pp, objfile);
- set_length_in_type_chain (type);
- }
-
- /* Now read the baseclasses, if any, read the regular C struct or C++
- class member fields, attach the fields to the type, read the C++
- member functions, attach them to the type, and then read any tilde
- field (baseclass specifier for the class holding the main vtable). */
-
- if (!read_baseclasses (&fi, pp, type, objfile)
- || !read_struct_fields (&fi, pp, type, objfile)
- || !attach_fields_to_type (&fi, type, objfile)
- || !read_member_functions (&fi, pp, type, objfile)
- || !attach_fn_fields_to_type (&fi, type)
- || !read_tilde_fields (&fi, pp, type, objfile))
- {
- type = error_type (pp, objfile);
- }
-
- return (type);
-}
-
-/* Read a definition of an array type,
- and create and return a suitable type object.
- Also creates a range type which represents the bounds of that
- array. */
-
-static struct type *
-read_array_type (const char **pp, struct type *type,
- struct objfile *objfile)
-{
- struct type *index_type, *element_type, *range_type;
- int lower, upper;
- int adjustable = 0;
- int nbits;
-
- /* Format of an array type:
- "ar<index type>;lower;upper;<array_contents_type>".
- OS9000: "arlower,upper;<array_contents_type>".
-
- Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
- for these, produce a type like float[][]. */
-
- {
- index_type = read_type (pp, objfile);
- if (**pp != ';')
- /* Improper format of array type decl. */
- return error_type (pp, objfile);
- ++*pp;
- }
-
- if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
- {
- (*pp)++;
- adjustable = 1;
- }
- lower = read_huge_number (pp, ';', &nbits, 0);
-
- if (nbits != 0)
- return error_type (pp, objfile);
-
- if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
- {
- (*pp)++;
- adjustable = 1;
- }
- upper = read_huge_number (pp, ';', &nbits, 0);
- if (nbits != 0)
- return error_type (pp, objfile);
-
- element_type = read_type (pp, objfile);
-
- if (adjustable)
- {
- lower = 0;
- upper = -1;
- }
-
- type_allocator alloc (objfile, get_current_subfile ()->language);
- range_type =
- create_static_range_type (alloc, index_type, lower, upper);
- type_allocator smash_alloc (type, type_allocator::SMASH);
- type = create_array_type (smash_alloc, element_type, range_type);
-
- return type;
-}
-
-
-/* Read a definition of an enumeration type,
- and create and return a suitable type object.
- Also defines the symbols that represent the values of the type. */
-
-static struct type *
-read_enum_type (const char **pp, struct type *type,
- struct objfile *objfile)
-{
- struct gdbarch *gdbarch = objfile->arch ();
- const char *p;
- char *name;
- long n;
- struct symbol *sym;
- int nsyms = 0;
- struct pending **symlist;
- struct pending *osyms, *syms;
- int o_nsyms;
- int nbits;
- int unsigned_enum = 1;
-
-#if 0
- /* FIXME! The stabs produced by Sun CC merrily define things that ought
- to be file-scope, between N_FN entries, using N_LSYM. What's a mother
- to do? For now, force all enum values to file scope. */
- if (within_function)
- symlist = get_local_symbols ();
- else
-#endif
- symlist = get_file_symbols ();
- osyms = *symlist;
- o_nsyms = osyms ? osyms->nsyms : 0;
-
- /* The aix4 compiler emits an extra field before the enum members;
- my guess is it's a type of some sort. Just ignore it. */
- if (**pp == '-')
- {
- /* Skip over the type. */
- while (**pp != ':')
- (*pp)++;
-
- /* Skip over the colon. */
- (*pp)++;
- }
-
- /* Read the value-names and their values.
- The input syntax is NAME:VALUE,NAME:VALUE, and so on.
- A semicolon or comma instead of a NAME means the end. */
- while (**pp && **pp != ';' && **pp != ',')
- {
- STABS_CONTINUE (pp, objfile);
- p = *pp;
- while (*p != ':')
- p++;
- name = obstack_strndup (&objfile->objfile_obstack, *pp, p - *pp);
- *pp = p + 1;
- n = read_huge_number (pp, ',', &nbits, 0);
- if (nbits != 0)
- return error_type (pp, objfile);
-
- sym = new (&objfile->objfile_obstack) symbol;
- sym->set_linkage_name (name);
- sym->set_language (get_current_subfile ()->language,
- &objfile->objfile_obstack);
- sym->set_loc_class_index (LOC_CONST);
- sym->set_domain (VAR_DOMAIN);
- sym->set_value_longest (n);
- if (n < 0)
- unsigned_enum = 0;
- add_symbol_to_list (sym, symlist);
- nsyms++;
- }
-
- if (**pp == ';')
- (*pp)++; /* Skip the semicolon. */
-
- /* Now fill in the fields of the type-structure. */
-
- type->set_length (gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT);
- set_length_in_type_chain (type);
- type->set_code (TYPE_CODE_ENUM);
- type->set_is_stub (false);
- if (unsigned_enum)
- type->set_is_unsigned (true);
- type->alloc_fields (nsyms);
-
- /* Find the symbols for the values and put them into the type.
- The symbols can be found in the symlist that we put them on
- to cause them to be defined. osyms contains the old value
- of that symlist; everything up to there was defined by us. */
- /* Note that we preserve the order of the enum constants, so
- that in something like "enum {FOO, LAST_THING=FOO}" we print
- FOO, not LAST_THING. */
-
- for (syms = *symlist, n = nsyms - 1; syms; syms = syms->next)
- {
- int last = syms == osyms ? o_nsyms : 0;
- int j = syms->nsyms;
-
- for (; --j >= last; --n)
- {
- struct symbol *xsym = syms->symbol[j];
-
- xsym->set_type (type);
- type->field (n).set_name (xsym->linkage_name ());
- type->field (n).set_loc_enumval (xsym->value_longest ());
- type->field (n).set_bitsize (0);
- }
- if (syms == osyms)
- break;
- }
-
- return type;
-}
-
-/* Sun's ACC uses a somewhat saner method for specifying the builtin
- typedefs in every file (for int, long, etc):
-
- type = b <signed> <width> <format type>; <offset>; <nbits>
- signed = u or s.
- optional format type = c or b for char or boolean.
- offset = offset from high order bit to start bit of type.
- width is # bytes in object of this type, nbits is # bits in type.
-
- The width/offset stuff appears to be for small objects stored in
- larger ones (e.g. `shorts' in `int' registers). We ignore it for now,
- FIXME. */
-
-static struct type *
-read_sun_builtin_type (const char **pp, int typenums[2], struct objfile *objfile)
-{
- int type_bits;
- int nbits;
- int unsigned_type;
- int boolean_type = 0;
-
- switch (**pp)
- {
- case 's':
- unsigned_type = 0;
- break;
- case 'u':
- unsigned_type = 1;
- break;
- default:
- return error_type (pp, objfile);
- }
- (*pp)++;
-
- /* For some odd reason, all forms of char put a c here. This is strange
- because no other type has this honor. We can safely ignore this because
- we actually determine 'char'acterness by the number of bits specified in
- the descriptor.
- Boolean forms, e.g Fortran logical*X, put a b here. */
-
- if (**pp == 'c')
- (*pp)++;
- else if (**pp == 'b')
- {
- boolean_type = 1;
- (*pp)++;
- }
-
- /* The first number appears to be the number of bytes occupied
- by this type, except that unsigned short is 4 instead of 2.
- Since this information is redundant with the third number,
- we will ignore it. */
- read_huge_number (pp, ';', &nbits, 0);
- if (nbits != 0)
- return error_type (pp, objfile);
-
- /* The second number is always 0, so ignore it too. */
- read_huge_number (pp, ';', &nbits, 0);
- if (nbits != 0)
- return error_type (pp, objfile);
-
- /* The third number is the number of bits for this type. */
- type_bits = read_huge_number (pp, 0, &nbits, 0);
- if (nbits != 0)
- return error_type (pp, objfile);
- /* The type *should* end with a semicolon. If it are embedded
- in a larger type the semicolon may be the only way to know where
- the type ends. If this type is at the end of the stabstring we
- can deal with the omitted semicolon (but we don't have to like
- it). Don't bother to complain(), Sun's compiler omits the semicolon
- for "void". */
- if (**pp == ';')
- ++(*pp);
-
- type_allocator alloc (objfile, get_current_subfile ()->language);
- if (type_bits == 0)
- {
- struct type *type = alloc.new_type (TYPE_CODE_VOID,
- TARGET_CHAR_BIT, nullptr);
- if (unsigned_type)
- type->set_is_unsigned (true);
-
- return type;
- }
-
- if (boolean_type)
- return init_boolean_type (alloc, type_bits, unsigned_type, NULL);
- else
- return init_integer_type (alloc, type_bits, unsigned_type, NULL);
-}
-
-static struct type *
-read_sun_floating_type (const char **pp, int typenums[2],
- struct objfile *objfile)
-{
- int nbits;
- int details;
- int nbytes;
- struct type *rettype;
-
- /* The first number has more details about the type, for example
- FN_COMPLEX. */
- details = read_huge_number (pp, ';', &nbits, 0);
- if (nbits != 0)
- return error_type (pp, objfile);
-
- /* The second number is the number of bytes occupied by this type. */
- nbytes = read_huge_number (pp, ';', &nbits, 0);
- if (nbits != 0)
- return error_type (pp, objfile);
-
- nbits = nbytes * TARGET_CHAR_BIT;
-
- if (details == NF_COMPLEX || details == NF_COMPLEX16
- || details == NF_COMPLEX32)
- {
- rettype = dbx_init_float_type (objfile, nbits / 2);
- return init_complex_type (NULL, rettype);
- }
-
- return dbx_init_float_type (objfile, nbits);
-}
-
-/* Read a number from the string pointed to by *PP.
- The value of *PP is advanced over the number.
- If END is nonzero, the character that ends the
- number must match END, or an error happens;
- and that character is skipped if it does match.
- If END is zero, *PP is left pointing to that character.
-
- If TWOS_COMPLEMENT_BITS is set to a strictly positive value and if
- the number is represented in an octal representation, assume that
- it is represented in a 2's complement representation with a size of
- TWOS_COMPLEMENT_BITS.
-
- If the number fits in a long, set *BITS to 0 and return the value.
- If not, set *BITS to be the number of bits in the number and return 0.
-
- If encounter garbage, set *BITS to -1 and return 0. */
-
-static long
-read_huge_number (const char **pp, int end, int *bits,
- int twos_complement_bits)
-{
- const char *p = *pp;
- int sign = 1;
- int sign_bit = 0;
- long n = 0;
- int radix = 10;
- char overflow = 0;
- int nbits = 0;
- int c;
- long upper_limit;
- int twos_complement_representation = 0;
-
- if (*p == '-')
- {
- sign = -1;
- p++;
- }
-
- /* Leading zero means octal. GCC uses this to output values larger
- than an int (because that would be hard in decimal). */
- if (*p == '0')
- {
- radix = 8;
- p++;
- }
-
- /* Skip extra zeros. */
- while (*p == '0')
- p++;
-
- if (sign > 0 && radix == 8 && twos_complement_bits > 0)
- {
- /* Octal, possibly signed. Check if we have enough chars for a
- negative number. */
-
- size_t len;
- const char *p1 = p;
-
- while ((c = *p1) >= '0' && c < '8')
- p1++;
-
- len = p1 - p;
- if (len > twos_complement_bits / 3
- || (twos_complement_bits % 3 == 0
- && len == twos_complement_bits / 3))
- {
- /* Ok, we have enough characters for a signed value, check
- for signedness by testing if the sign bit is set. */
- sign_bit = (twos_complement_bits % 3 + 2) % 3;
- c = *p - '0';
- if (c & (1 << sign_bit))
- {
- /* Definitely signed. */
- twos_complement_representation = 1;
- sign = -1;
- }
- }
- }
-
- upper_limit = LONG_MAX / radix;
-
- while ((c = *p++) >= '0' && c < ('0' + radix))
- {
- if (n <= upper_limit)
- {
- if (twos_complement_representation)
- {
- /* Octal, signed, twos complement representation. In
- this case, n is the corresponding absolute value. */
- if (n == 0)
- {
- long sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit));
-
- n = -sn;
- }
- else
- {
- n *= radix;
- n -= c - '0';
- }
- }
- else
- {
- /* unsigned representation */
- n *= radix;
- n += c - '0'; /* FIXME this overflows anyway. */
- }
- }
- else
- overflow = 1;
-
- /* This depends on large values being output in octal, which is
- what GCC does. */
- if (radix == 8)
- {
- if (nbits == 0)
- {
- if (c == '0')
- /* Ignore leading zeroes. */
- ;
- else if (c == '1')
- nbits = 1;
- else if (c == '2' || c == '3')
- nbits = 2;
- else
- nbits = 3;
- }
- else
- nbits += 3;
- }
- }
- if (end)
- {
- if (c && c != end)
- {
- if (bits != NULL)
- *bits = -1;
- return 0;
- }
- }
- else
- --p;
-
- if (radix == 8 && twos_complement_bits > 0 && nbits > twos_complement_bits)
- {
- /* We were supposed to parse a number with maximum
- TWOS_COMPLEMENT_BITS bits, but something went wrong. */
- if (bits != NULL)
- *bits = -1;
- return 0;
- }
-
- *pp = p;
- if (overflow)
- {
- if (nbits == 0)
- {
- /* Large decimal constants are an error (because it is hard to
- count how many bits are in them). */
- if (bits != NULL)
- *bits = -1;
- return 0;
- }
-
- /* -0x7f is the same as 0x80. So deal with it by adding one to
- the number of bits. Two's complement representation octals
- can't have a '-' in front. */
- if (sign == -1 && !twos_complement_representation)
- ++nbits;
- if (bits)
- *bits = nbits;
- }
- else
- {
- if (bits)
- *bits = 0;
- return n * sign;
- }
- /* It's *BITS which has the interesting information. */
- return 0;
-}
-
-static struct type *
-read_range_type (const char **pp, int typenums[2], int type_size,
- struct objfile *objfile)
-{
- struct gdbarch *gdbarch = objfile->arch ();
- const char *orig_pp = *pp;
- int rangenums[2];
- long n2, n3;
- int n2bits, n3bits;
- int self_subrange;
- struct type *result_type;
- struct type *index_type = NULL;
-
- /* First comes a type we are a subrange of.
- In C it is usually 0, 1 or the type being defined. */
- if (read_type_number (pp, rangenums) != 0)
- return error_type (pp, objfile);
- self_subrange = (rangenums[0] == typenums[0] &&
- rangenums[1] == typenums[1]);
-
- if (**pp == '=')
- {
- *pp = orig_pp;
- index_type = read_type (pp, objfile);
- }
-
- /* A semicolon should now follow; skip it. */
- if (**pp == ';')
- (*pp)++;
-
- /* The remaining two operands are usually lower and upper bounds
- of the range. But in some special cases they mean something else. */
- n2 = read_huge_number (pp, ';', &n2bits, type_size);
- n3 = read_huge_number (pp, ';', &n3bits, type_size);
-
- if (n2bits == -1 || n3bits == -1)
- return error_type (pp, objfile);
-
- type_allocator alloc (objfile, get_current_subfile ()->language);
-
- if (index_type)
- goto handle_true_range;
-
- /* If limits are huge, must be large integral type. */
- if (n2bits != 0 || n3bits != 0)
- {
- char got_signed = 0;
- char got_unsigned = 0;
- /* Number of bits in the type. */
- int nbits = 0;
-
- /* If a type size attribute has been specified, the bounds of
- the range should fit in this size. If the lower bounds needs
- more bits than the upper bound, then the type is signed. */
- if (n2bits <= type_size && n3bits <= type_size)
- {
- if (n2bits == type_size && n2bits > n3bits)
- got_signed = 1;
- else
- got_unsigned = 1;
- nbits = type_size;
- }
- /* Range from 0 to <large number> is an unsigned large integral type. */
- else if ((n2bits == 0 && n2 == 0) && n3bits != 0)
- {
- got_unsigned = 1;
- nbits = n3bits;
- }
- /* Range from <large number> to <large number>-1 is a large signed
- integral type. Take care of the case where <large number> doesn't
- fit in a long but <large number>-1 does. */
- else if ((n2bits != 0 && n3bits != 0 && n2bits == n3bits + 1)
- || (n2bits != 0 && n3bits == 0
- && (n2bits == sizeof (long) * HOST_CHAR_BIT)
- && n3 == LONG_MAX))
- {
- got_signed = 1;
- nbits = n2bits;
- }
-
- if (got_signed || got_unsigned)
- return init_integer_type (alloc, nbits, got_unsigned, NULL);
- else
- return error_type (pp, objfile);
- }
-
- /* A type defined as a subrange of itself, with bounds both 0, is void. */
- if (self_subrange && n2 == 0 && n3 == 0)
- return alloc.new_type (TYPE_CODE_VOID, TARGET_CHAR_BIT, nullptr);
-
- /* If n3 is zero and n2 is positive, we want a floating type, and n2
- is the width in bytes.
-
- Fortran programs appear to use this for complex types also. To
- distinguish between floats and complex, g77 (and others?) seem
- to use self-subranges for the complexes, and subranges of int for
- the floats.
-
- Also note that for complexes, g77 sets n2 to the size of one of
- the member floats, not the whole complex beast. My guess is that
- this was to work well with pre-COMPLEX versions of gdb. */
-
- if (n3 == 0 && n2 > 0)
- {
- struct type *float_type
- = dbx_init_float_type (objfile, n2 * TARGET_CHAR_BIT);
-
- if (self_subrange)
- return init_complex_type (NULL, float_type);
- else
- return float_type;
- }
-
- /* If the upper bound is -1, it must really be an unsigned integral. */
-
- else if (n2 == 0 && n3 == -1)
- {
- int bits = type_size;
-
- if (bits <= 0)
- {
- /* We don't know its size. It is unsigned int or unsigned
- long. GCC 2.3.3 uses this for long long too, but that is
- just a GDB 3.5 compatibility hack. */
- bits = gdbarch_int_bit (gdbarch);
- }
-
- return init_integer_type (alloc, bits, 1, NULL);
- }
-
- /* Special case: char is defined (Who knows why) as a subrange of
- itself with range 0-127. */
- else if (self_subrange && n2 == 0 && n3 == 127)
- {
- struct type *type = init_integer_type (alloc, TARGET_CHAR_BIT,
- 0, NULL);
- type->set_has_no_signedness (true);
- return type;
- }
- /* We used to do this only for subrange of self or subrange of int. */
- else if (n2 == 0)
- {
- /* -1 is used for the upper bound of (4 byte) "unsigned int" and
- "unsigned long", and we already checked for that,
- so don't need to test for it here. */
-
- if (n3 < 0)
- /* n3 actually gives the size. */
- return init_integer_type (alloc, -n3 * TARGET_CHAR_BIT, 1, NULL);
-
- /* Is n3 == 2**(8n)-1 for some integer n? Then it's an
- unsigned n-byte integer. But do require n to be a power of
- two; we don't want 3- and 5-byte integers flying around. */
- {
- int bytes;
- unsigned long bits;
-
- bits = n3;
- for (bytes = 0; (bits & 0xff) == 0xff; bytes++)
- bits >>= 8;
- if (bits == 0
- && ((bytes - 1) & bytes) == 0) /* "bytes is a power of two" */
- return init_integer_type (alloc, bytes * TARGET_CHAR_BIT, 1, NULL);
- }
- }
- /* I think this is for Convex "long long". Since I don't know whether
- Convex sets self_subrange, I also accept that particular size regardless
- of self_subrange. */
- else if (n3 == 0 && n2 < 0
- && (self_subrange
- || n2 == -gdbarch_long_long_bit
- (gdbarch) / TARGET_CHAR_BIT))
- return init_integer_type (alloc, -n2 * TARGET_CHAR_BIT, 0, NULL);
- else if (n2 == -n3 - 1)
- {
- if (n3 == 0x7f)
- return init_integer_type (alloc, 8, 0, NULL);
- if (n3 == 0x7fff)
- return init_integer_type (alloc, 16, 0, NULL);
- if (n3 == 0x7fffffff)
- return init_integer_type (alloc, 32, 0, NULL);
- }
-
- /* We have a real range type on our hands. Allocate space and
- return a real pointer. */
-handle_true_range:
-
- if (self_subrange)
- index_type = builtin_type (objfile)->builtin_int;
- else
- index_type = *dbx_lookup_type (rangenums, objfile);
- if (index_type == NULL)
- {
- /* Does this actually ever happen? Is that why we are worrying
- about dealing with it rather than just calling error_type? */
-
- complaint (_("base type %d of range type is not defined"), rangenums[1]);
-
- index_type = builtin_type (objfile)->builtin_int;
- }
-
- result_type
- = create_static_range_type (alloc, index_type, n2, n3);
- return (result_type);
-}
-
-/* Read in an argument list. This is a list of types, separated by commas
- and terminated with END. Return the list of types read in, or NULL
- if there is an error. */
-
-static struct field *
-read_args (const char **pp, int end, struct objfile *objfile, int *nargsp,
- int *varargsp)
-{
- /* FIXME! Remove this arbitrary limit! */
- struct type *types[1024]; /* Allow for fns of 1023 parameters. */
- int n = 0, i;
- struct field *rval;
-
- while (**pp != end)
- {
- if (**pp != ',')
- /* Invalid argument list: no ','. */
- return NULL;
- (*pp)++;
- STABS_CONTINUE (pp, objfile);
- types[n++] = read_type (pp, objfile);
- }
- (*pp)++; /* get past `end' (the ':' character). */
-
- if (n == 0)
- {
- /* We should read at least the THIS parameter here. Some broken stabs
- output contained `(0,41),(0,42)=@s8;-16;,(0,43),(0,1);' where should
- have been present ";-16,(0,43)" reference instead. This way the
- excessive ";" marker prematurely stops the parameters parsing. */
-
- complaint (_("Invalid (empty) method arguments"));
- *varargsp = 0;
- }
- else if (types[n - 1]->code () != TYPE_CODE_VOID)
- *varargsp = 1;
- else
- {
- n--;
- *varargsp = 0;
- }
-
- rval = XCNEWVEC (struct field, n);
- for (i = 0; i < n; i++)
- rval[i].set_type (types[i]);
- *nargsp = n;
- return rval;
-}
-\f
-/* Common block handling. */
-
-/* List of symbols declared since the last BCOMM. This list is a tail
- of local_symbols. When ECOMM is seen, the symbols on the list
- are noted so their proper addresses can be filled in later,
- using the common block base address gotten from the assembler
- stabs. */
-
-static struct pending *common_block;
-static int common_block_i;
-
-/* Name of the current common block. We get it from the BCOMM instead of the
- ECOMM to match IBM documentation (even though IBM puts the name both places
- like everyone else). */
-static char *common_block_name;
-
-/* Process a N_BCOMM symbol. The storage for NAME is not guaranteed
- to remain after this function returns. */
-
-void
-common_block_start (const char *name, struct objfile *objfile)
-{
- if (common_block_name != NULL)
- {
- complaint (_("Invalid symbol data: common block within common block"));
- }
- common_block = *get_local_symbols ();
- common_block_i = common_block ? common_block->nsyms : 0;
- common_block_name = obstack_strdup (&objfile->objfile_obstack, name);
-}
-
-/* Process a N_ECOMM symbol. */
-
-void
-common_block_end (struct objfile *objfile)
-{
- /* Symbols declared since the BCOMM are to have the common block
- start address added in when we know it. common_block and
- common_block_i point to the first symbol after the BCOMM in
- the local_symbols list; copy the list and hang it off the
- symbol for the common block name for later fixup. */
- int i;
- struct symbol *sym;
- struct pending *newobj = 0;
- struct pending *next;
- int j;
-
- if (common_block_name == NULL)
- {
- complaint (_("ECOMM symbol unmatched by BCOMM"));
- return;
- }
-
- sym = new (&objfile->objfile_obstack) symbol;
- /* Note: common_block_name already saved on objfile_obstack. */
- sym->set_linkage_name (common_block_name);
- sym->set_loc_class_index (LOC_BLOCK);
-
- /* Now we copy all the symbols which have been defined since the BCOMM. */
-
- /* Copy all the struct pendings before common_block. */
- for (next = *get_local_symbols ();
- next != NULL && next != common_block;
- next = next->next)
- {
- for (j = 0; j < next->nsyms; j++)
- add_symbol_to_list (next->symbol[j], &newobj);
- }
-
- /* Copy however much of COMMON_BLOCK we need. If COMMON_BLOCK is
- NULL, it means copy all the local symbols (which we already did
- above). */
-
- if (common_block != NULL)
- for (j = common_block_i; j < common_block->nsyms; j++)
- add_symbol_to_list (common_block->symbol[j], &newobj);
-
- sym->set_type ((struct type *) newobj);
-
- /* Should we be putting local_symbols back to what it was?
- Does it matter? */
-
- i = hashname (sym->linkage_name ());
- sym->set_value_chain (global_sym_chain[i]);
- global_sym_chain[i] = sym;
- common_block_name = NULL;
-}
-
-/* Add a common block's start address to the offset of each symbol
- declared to be in it (by being between a BCOMM/ECOMM pair that uses
- the common block name). */
-
-static void
-fix_common_block (struct symbol *sym, CORE_ADDR valu, int section_index)
-{
- struct pending *next = (struct pending *) sym->type ();
-
- for (; next; next = next->next)
- {
- int j;
-
- for (j = next->nsyms - 1; j >= 0; j--)
- {
- next->symbol[j]->set_value_address
- (next->symbol[j]->value_address () + valu);
- next->symbol[j]->set_section_index (section_index);
- }
- }
-}
-\f
-
-
-/* Add {TYPE, TYPENUMS} to the NONAME_UNDEFS vector.
- See add_undefined_type for more details. */
-
-static void
-add_undefined_type_noname (struct type *type, int typenums[2])
-{
- struct nat nat;
-
- nat.typenums[0] = typenums [0];
- nat.typenums[1] = typenums [1];
- nat.type = type;
-
- if (noname_undefs_length == noname_undefs_allocated)
- {
- noname_undefs_allocated *= 2;
- noname_undefs = (struct nat *)
- xrealloc ((char *) noname_undefs,
- noname_undefs_allocated * sizeof (struct nat));
- }
- noname_undefs[noname_undefs_length++] = nat;
-}
-
-/* Add TYPE to the UNDEF_TYPES vector.
- See add_undefined_type for more details. */
-
-static void
-add_undefined_type_1 (struct type *type)
-{
- if (undef_types_length == undef_types_allocated)
- {
- undef_types_allocated *= 2;
- undef_types = (struct type **)
- xrealloc ((char *) undef_types,
- undef_types_allocated * sizeof (struct type *));
- }
- undef_types[undef_types_length++] = type;
-}
-
-/* What about types defined as forward references inside of a small lexical
- scope? */
-/* Add a type to the list of undefined types to be checked through
- once this file has been read in.
-
- In practice, we actually maintain two such lists: The first list
- (UNDEF_TYPES) is used for types whose name has been provided, and
- concerns forward references (eg 'xs' or 'xu' forward references);
- the second list (NONAME_UNDEFS) is used for types whose name is
- unknown at creation time, because they were referenced through
- their type number before the actual type was declared.
- This function actually adds the given type to the proper list. */
-
-static void
-add_undefined_type (struct type *type, int typenums[2])
-{
- if (type->name () == NULL)
- add_undefined_type_noname (type, typenums);
- else
- add_undefined_type_1 (type);
-}
-
-/* Try to fix all undefined types pushed on the UNDEF_TYPES vector. */
-
-static void
-cleanup_undefined_types_noname (struct objfile *objfile)
-{
- int i;
-
- for (i = 0; i < noname_undefs_length; i++)
- {
- struct nat nat = noname_undefs[i];
- struct type **type;
-
- type = dbx_lookup_type (nat.typenums, objfile);
- if (nat.type != *type && (*type)->code () != TYPE_CODE_UNDEF)
- {
- /* The instance flags of the undefined type are still unset,
- and needs to be copied over from the reference type.
- Since replace_type expects them to be identical, we need
- to set these flags manually before hand. */
- nat.type->set_instance_flags ((*type)->instance_flags ());
- replace_type (nat.type, *type);
- }
- }
-
- noname_undefs_length = 0;
-}
-
-/* Go through each undefined type, see if it's still undefined, and fix it
- up if possible. We have two kinds of undefined types:
-
- TYPE_CODE_ARRAY: Array whose target type wasn't defined yet.
- Fix: update array length using the element bounds
- and the target type's length.
- TYPE_CODE_STRUCT, TYPE_CODE_UNION: Structure whose fields were not
- yet defined at the time a pointer to it was made.
- Fix: Do a full lookup on the struct/union tag. */
-
-static void
-cleanup_undefined_types_1 (void)
-{
- struct type **type;
-
- /* Iterate over every undefined type, and look for a symbol whose type
- matches our undefined type. The symbol matches if:
- 1. It is a typedef in the STRUCT domain;
- 2. It has the same name, and same type code;
- 3. The instance flags are identical.
-
- It is important to check the instance flags, because we have seen
- examples where the debug info contained definitions such as:
-
- "foo_t:t30=B31=xefoo_t:"
-
- In this case, we have created an undefined type named "foo_t" whose
- instance flags is null (when processing "xefoo_t"), and then created
- another type with the same name, but with different instance flags
- ('B' means volatile). I think that the definition above is wrong,
- since the same type cannot be volatile and non-volatile at the same
- time, but we need to be able to cope with it when it happens. The
- approach taken here is to treat these two types as different. */
-
- for (type = undef_types; type < undef_types + undef_types_length; type++)
- {
- switch ((*type)->code ())
- {
-
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- case TYPE_CODE_ENUM:
- {
- /* Check if it has been defined since. Need to do this here
- as well as in check_typedef to deal with the (legitimate in
- C though not C++) case of several types with the same name
- in different source files. */
- if ((*type)->is_stub ())
- {
- struct pending *ppt;
- int i;
- /* Name of the type, without "struct" or "union". */
- const char *type_name = (*type)->name ();
-
- if (type_name == NULL)
- {
- complaint (_("need a type name"));
- break;
- }
- for (ppt = *get_file_symbols (); ppt; ppt = ppt->next)
- {
- for (i = 0; i < ppt->nsyms; i++)
- {
- struct symbol *sym = ppt->symbol[i];
-
- if (sym->loc_class () == LOC_TYPEDEF
- && sym->domain () == STRUCT_DOMAIN
- && (sym->type ()->code () == (*type)->code ())
- && ((*type)->instance_flags ()
- == sym->type ()->instance_flags ())
- && strcmp (sym->linkage_name (), type_name) == 0)
- replace_type (*type, sym->type ());
- }
- }
- }
- }
- break;
-
- default:
- {
- complaint (_("forward-referenced types left unresolved, "
- "type code %d."),
- (*type)->code ());
- }
- break;
- }
- }
-
- undef_types_length = 0;
-}
-
-/* Try to fix all the undefined types we encountered while processing
- this unit. */
-
-void
-cleanup_undefined_stabs_types (struct objfile *objfile)
-{
- cleanup_undefined_types_1 ();
- cleanup_undefined_types_noname (objfile);
-}
-
-/* See stabsread.h. */
-
-void
-scan_file_globals (struct objfile *objfile)
-{
- int hash;
- struct symbol *sym, *prev;
- struct objfile *resolve_objfile;
-
- /* SVR4 based linkers copy referenced global symbols from shared
- libraries to the main executable.
- If we are scanning the symbols for a shared library, try to resolve
- them from the minimal symbols of the main executable first. */
-
- if (current_program_space->symfile_object_file
- && objfile != current_program_space->symfile_object_file)
- resolve_objfile = current_program_space->symfile_object_file;
- else
- resolve_objfile = objfile;
-
- while (1)
- {
- /* Avoid expensive loop through all minimal symbols if there are
- no unresolved symbols. */
- for (hash = 0; hash < HASHSIZE; hash++)
- {
- if (global_sym_chain[hash])
- break;
- }
- if (hash >= HASHSIZE)
- return;
-
- for (minimal_symbol *msymbol : resolve_objfile->msymbols ())
- {
- QUIT;
-
- /* Skip static symbols. */
- switch (msymbol->type ())
- {
- case mst_file_text:
- case mst_file_data:
- case mst_file_bss:
- continue;
- default:
- break;
- }
-
- prev = NULL;
-
- /* Get the hash index and check all the symbols
- under that hash index. */
-
- hash = hashname (msymbol->linkage_name ());
-
- for (sym = global_sym_chain[hash]; sym;)
- {
- if (strcmp (msymbol->linkage_name (), sym->linkage_name ()) == 0)
- {
- /* Splice this symbol out of the hash chain and
- assign the value we have to it. */
- if (prev)
- {
- prev->set_value_chain (sym->value_chain ());
- }
- else
- {
- global_sym_chain[hash] = sym->value_chain ();
- }
-
- /* Check to see whether we need to fix up a common block. */
- /* Note: this code might be executed several times for
- the same symbol if there are multiple references. */
- if (sym)
- {
- if (sym->loc_class () == LOC_BLOCK)
- fix_common_block
- (sym, msymbol->value_address (resolve_objfile),
- msymbol->section_index ());
- else
- sym->set_value_address
- (msymbol->value_address (resolve_objfile));
- sym->set_section_index (msymbol->section_index ());
- }
-
- if (prev)
- {
- sym = prev->value_chain ();
- }
- else
- {
- sym = global_sym_chain[hash];
- }
- }
- else
- {
- prev = sym;
- sym = sym->value_chain ();
- }
- }
- }
- if (resolve_objfile == objfile)
- break;
- resolve_objfile = objfile;
- }
-
- /* Change the storage class of any remaining unresolved globals to
- LOC_UNRESOLVED and remove them from the chain. */
- for (hash = 0; hash < HASHSIZE; hash++)
- {
- sym = global_sym_chain[hash];
- while (sym)
- {
- prev = sym;
- sym = sym->value_chain ();
-
- /* Change the symbol address from the misleading chain value
- to address zero. */
- prev->set_value_address (0);
-
- /* Complain about unresolved common block symbols. */
- if (prev->loc_class () == LOC_STATIC)
- prev->set_loc_class_index (LOC_UNRESOLVED);
- else
- complaint (_("%s: common block `%s' from "
- "global_sym_chain unresolved"),
- objfile_name (objfile), prev->print_name ());
- }
- }
- memset (global_sym_chain, 0, sizeof (global_sym_chain));
-}
-
-/* Initialize anything that needs initializing when starting to read
- a fresh piece of a symbol file, e.g. reading in the stuff corresponding
- to a psymtab. */
-
-void
-stabsread_init (void)
-{
-}
-
-/* Initialize anything that needs initializing when a completely new
- symbol file is specified (not just adding some symbols from another
- file, e.g. a shared library). */
-
-void
-stabsread_new_init (void)
-{
- /* Empty the hash table of global syms looking for values. */
- memset (global_sym_chain, 0, sizeof (global_sym_chain));
-}
-
-/* Initialize anything that needs initializing at the same time as
- start_compunit_symtab() is called. */
-
-void
-start_stabs (void)
-{
- global_stabs = NULL; /* AIX COFF */
- /* Leave FILENUM of 0 free for builtin types and this file's types. */
- n_this_object_header_files = 1;
- type_vector_length = 0;
- type_vector = (struct type **) 0;
- within_function = 0;
-
- /* FIXME: If common_block_name is not already NULL, we should complain(). */
- common_block_name = NULL;
-}
-
-/* Call after end_compunit_symtab(). */
-
-void
-end_stabs (void)
-{
- if (type_vector)
- {
- xfree (type_vector);
- }
- type_vector = 0;
- type_vector_length = 0;
- previous_stab_code = 0;
-}
-
-void
-finish_global_stabs (struct objfile *objfile)
-{
- if (global_stabs)
- {
- patch_block_stabs (*get_global_symbols (), global_stabs, objfile);
- xfree (global_stabs);
- global_stabs = NULL;
- }
-}
-
-/* Find the end of the name, delimited by a ':', but don't match
- ObjC symbols which look like -[Foo bar::]:bla. */
-static const char *
-find_name_end (const char *name)
-{
- const char *s = name;
-
- if (s[0] == '-' || *s == '+')
- {
- /* Must be an ObjC method symbol. */
- if (s[1] != '[')
- {
- error (_("invalid symbol name \"%s\""), name);
- }
- s = strchr (s, ']');
- if (s == NULL)
- {
- error (_("invalid symbol name \"%s\""), name);
- }
- return strchr (s, ':');
- }
- else
- {
- return strchr (s, ':');
- }
-}
-
-/* Initializer for this module. */
-
-INIT_GDB_FILE (stabsread)
-{
- undef_types_allocated = 20;
- undef_types_length = 0;
- undef_types = XNEWVEC (struct type *, undef_types_allocated);
-
- noname_undefs_allocated = 20;
- noname_undefs_length = 0;
- noname_undefs = XNEWVEC (struct nat, noname_undefs_allocated);
-
- stab_register_index = register_symbol_register_impl (LOC_REGISTER,
- &stab_register_funcs);
- stab_regparm_index = register_symbol_register_impl (LOC_REGPARM_ADDR,
- &stab_register_funcs);
-}
+++ /dev/null
-/* Include file for stabs debugging format support functions.
- Copyright (C) 1986-2025 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef GDB_STABSREAD_H
-#define GDB_STABSREAD_H
-
-#include "buildsym-legacy.h"
-
-struct objfile;
-struct legacy_psymtab;
-enum language;
-
-/* Definitions, prototypes, etc for stabs debugging format support
- functions. */
-
-/* Count symbols as they are processed, for error messages. */
-
-extern unsigned int symnum;
-
-#define next_symbol_text(objfile) (*next_symbol_text_func)(objfile)
-
-/* Function to invoke get the next symbol. Return the symbol name. */
-
-extern const char *(*next_symbol_text_func) (struct objfile *);
-
-/* Global variable which, when set, indicates that we are processing a
- .o file compiled with gcc */
-
-extern unsigned char processing_gcc_compilation;
-
-/* Nonzero if within a function (so symbols should be local, if
- nothing says specifically). */
-
-extern int within_function;
-
-/* Hash table of global symbols whose values are not known yet.
- They are chained through the SYMBOL_VALUE_CHAIN, since we don't
- have the correct data for that slot yet.
-
- The use of the LOC_BLOCK code in this chain is nonstandard--
- it refers to a FORTRAN common block rather than the usual meaning, and
- the such LOC_BLOCK symbols use their fields in nonstandard ways. */
-
-extern struct symbol *global_sym_chain[HASHSIZE];
-
-extern void common_block_start (const char *, struct objfile *);
-extern void common_block_end (struct objfile *);
-
-/* Kludge for xcoffread.c */
-
-struct pending_stabs
- {
- int count;
- int length;
- char *stab[1];
- };
-
-extern struct pending_stabs *global_stabs;
-
-/* The type code that process_one_symbol saw on its previous invocation.
- Used to detect pairs of N_SO symbols. */
-
-extern int previous_stab_code;
-\f
-/* Support for Sun changes to dbx symbol format. */
-
-/* For each identified header file, we have a table of types defined
- in that header file.
-
- header_files maps header file names to their type tables.
- It is a vector of n_header_files elements.
- Each element describes one header file.
- It contains a vector of types.
-
- Sometimes it can happen that the same header file produces
- different results when included in different places.
- This can result from conditionals or from different
- things done before including the file.
- When this happens, there are multiple entries for the file in this table,
- one entry for each distinct set of results.
- The entries are distinguished by the INSTANCE field.
- The INSTANCE field appears in the N_BINCL and N_EXCL symbol table and is
- used to match header-file references to their corresponding data. */
-
-struct header_file
- {
-
- /* Name of header file */
-
- char *name;
-
- /* Numeric code distinguishing instances of one header file that
- produced different results when included. It comes from the
- N_BINCL or N_EXCL. */
-
- int instance;
-
- /* Pointer to vector of types */
-
- struct type **vector;
-
- /* Allocated length (# elts) of that vector */
-
- int length;
-
- };
-
-/* The table of header_files of this OBJFILE. */
-#define HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->header_files)
-
-/* The actual length of HEADER_FILES. */
-#define N_HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->n_header_files)
-
-/* The allocated length of HEADER_FILES. */
-#define N_ALLOCATED_HEADER_FILES(OBJFILE) \
- (DBX_SYMFILE_INFO (OBJFILE)->n_allocated_header_files)
-
-/* Within each object file, various header files are assigned numbers.
- A type is defined or referred to with a pair of numbers
- (FILENUM,TYPENUM) where FILENUM is the number of the header file
- and TYPENUM is the number within that header file.
- TYPENUM is the index within the vector of types for that header file.
-
- FILENUM == 0 is special; it refers to the main source of the object file,
- and not to any header file. FILENUM != 1 is interpreted by looking it up
- in the following table, which contains indices in header_files. */
-
-extern int *this_object_header_files;
-
-extern int n_this_object_header_files;
-
-extern int n_allocated_this_object_header_files;
-
-extern void cleanup_undefined_stabs_types (struct objfile *);
-
-extern long read_number (char **, int);
-
-extern struct symbol *define_symbol (CORE_ADDR, const char *, int, int,
- struct objfile *);
-
-extern void stabsread_init (void);
-
-extern void stabsread_new_init (void);
-
-extern void start_stabs (void);
-
-extern void end_stabs (void);
-
-extern void finish_global_stabs (struct objfile *objfile);
-\f
-class psymtab_storage;
-
-/* Functions exported by dbxread.c. These are not in stabsread.c because
- they are only used by some stabs readers. */
-
-extern legacy_psymtab *stabs_end_psymtab
- (struct objfile *objfile, psymtab_storage *partial_symtabs,
- legacy_psymtab *pst,
- const char **include_list, int num_includes,
- int capping_symbol_offset, unrelocated_addr capping_text,
- legacy_psymtab **dependency_list, int number_dependencies,
- int textlow_not_set);
-
-extern void process_one_symbol (int, int, CORE_ADDR, const char *,
- const section_offsets &,
- struct objfile *, enum language);
-
-/* Setup partial_symtab's describing each source file for which
- debugging information is available. */
-
-void
-read_stabs_symtab (struct objfile *, symfile_add_flags);
-
-extern void elfstab_build_psymtabs (struct objfile *objfile,
- asection *stabsect,
- file_ptr stabstroffset,
- unsigned int stabstrsize);
-
-extern void coffstab_build_psymtabs
- (struct objfile *objfile,
- CORE_ADDR textaddr, unsigned int textsize,
- const std::vector<asection *> &stabs,
- file_ptr stabstroffset, unsigned int stabstrsize);
-
-extern int symbol_reference_defined (const char **);
-
-extern void ref_add (int, struct symbol *, const char *, CORE_ADDR);
-
-extern struct symbol *ref_search (int);
-
-extern void free_header_files (void);
-
-extern void init_header_files (void);
-
-/* Scan through all of the global symbols defined in the object file,
- assigning values to the debugging symbols that need to be assigned
- to. Get these symbols from the minimal symbol table. */
-
-extern void scan_file_globals (struct objfile *objfile);
-
-/* Complaints about the symbols we have encountered. */
-
-void
-unknown_symtype_complaint (const char *);
-
-void
-lbrac_mismatch_complaint (int);
-
-void
-repeated_header_complaint (const char *, int);
-
-bound_minimal_symbol
-find_stab_function (const char *, const char *, struct objfile *);
-
-/* This handles a single symbol from the symbol-file, building symbols
- into a GDB symtab. It takes these arguments and an implicit argument.
-
- TYPE is the type field of the ".stab" symbol entry.
- DESC is the desc field of the ".stab" entry.
- VALU is the value field of the ".stab" entry.
- NAME is the symbol name, in our address space.
- SECTION_OFFSETS is a set of amounts by which the sections of this
- object file were relocated when it was loaded into memory. Note
- that these section_offsets are not the objfile->section_offsets but
- the pst->section_offsets. All symbols that refer to memory
- locations need to be offset by these amounts.
- OBJFILE is the object file from which we are reading symbols. It
- is used in end_compunit_symtab.
- LANGUAGE is the language of the symtab.
-*/
-
-void
-process_one_symbol (int, int, CORE_ADDR, const char *,
- const section_offsets &,
- struct objfile *, enum language);
-
-#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
-#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
-#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
-#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
-#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
-#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
-#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
-#define PST_LANGUAGE(p) (SYMLOC(p)->pst_language)
-
-#define INTERNALIZE_SYMBOL(intern, extern, abfd) \
- { \
- (intern).n_strx = bfd_h_get_32 (abfd, (extern)->e_strx); \
- (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \
- (intern).n_other = 0; \
- (intern).n_desc = bfd_h_get_16 (abfd, (extern)->e_desc); \
- if (bfd_get_sign_extend_vma (abfd)) \
- (intern).n_value = bfd_h_get_signed_32 (abfd, (extern)->e_value); \
- else \
- (intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value); \
- }
-
-/* We put a pointer to this structure in the read_symtab_private field
- of the psymtab. */
-
-struct symloc
- {
- /* Offset within the file symbol table of first local symbol for this
- file. */
-
- int ldsymoff;
-
- /* Length (in bytes) of the section of the symbol table devoted to
- this file's symbols (actually, the section bracketed may contain
- more than just this file's symbols). If ldsymlen is 0, the only
- reason for this thing's existence is the dependency list. Nothing
- else will happen when it is read in. */
-
- int ldsymlen;
-
- /* The size of each symbol in the symbol file (in external form). */
-
- int symbol_size;
-
- /* Further information needed to locate the symbols if they are in
- an ELF file. */
-
- int symbol_offset;
- int string_offset;
- int file_string_offset;
- enum language pst_language;
- };
-
-static inline void
-stabs_deprecated_warning ()
-{
- warning (_("Stabs support is deprecated and will be removed soon."));
-}
-#endif /* GDB_STABSREAD_H */
{
QUIT;
gdb_printf (_("Statistics for '%s':\n"), objfile_name (&objfile));
- if (OBJSTAT ((&objfile), n_stabs) > 0)
- gdb_printf (_(" Number of \"stab\" symbols read: %d\n"),
- OBJSTAT ((&objfile), n_stabs));
if (objfile.per_bfd->n_minsyms > 0)
gdb_printf (_(" Number of \"minimal\" symbols read: %d\n"),
objfile.per_bfd->n_minsyms);
+++ /dev/null
-s/# Irix4 sed blows up if you have a sed command starting with "#"//
-s/# Avoid it by putting the comments within real sed commands.//
-s/# GDB legitimately expects a file name.//
-s/# The sun3 assembler bogusly requires that the value of this stab be a//
-s/# label. Placate it.//
-1i\
- .stabs "weird.c",0x64,0,0,Label0\
-Label0:
-s/N_LSYM/0x80/
-s/N_GSYM/0x20/
-s/# Replace a single backslash with a doubled backslash//
-/\.stabs/s/\\\([^"]\)/\\\\\1/g
-s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
-s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
-s/\.align_it/.align 2/
-/^#/d
+++ /dev/null
-# GDB legitimately expects a file name.
-1i\
- .file 1 "weird.c"\
-\ #@stabs\
-\ #.stabs "weird.c",0x64,0,0,0
-/^#/d
-s/" *, */",/g
-s/\([0-9]\) *, */\1,/g
-s/ *$//
-s/N_LSYM/0x80/
-s/N_GSYM/0x20/
-s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
-s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
-s/\.align_it/.align 2/
-/.if/d
-/.endif/d
-s/\.stabs/ #.stabs/
+++ /dev/null
-# Copyright 2004-2025 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please email any bugs, comments, and/or additions to this file to:
-# bug-gdb@gnu.org
-
-#
-# test running programs
-#
-
-standard_testfile exclfwd1.c exclfwd2.c
-
-include_file exclfwd.h
-
-if {[prepare_for_testing "failed to prepare" $testfile \
- [list $srcfile $srcfile2] debug]} {
- return -1
-}
-
-if {![runto_main]} {
- return
-}
-
-get_debug_format
-
-gdb_test "ptype v1" \
- [multi_line \
- "type = struct a {" \
- " int x;" \
- " int y;" \
- "}"]
-
-if {[test_debug_format "stabs"]} {
- setup_kfail "gdb/1602" *-*-*
-}
-gdb_test "ptype v2" \
- [multi_line \
- "type = struct a {" \
- " const char .c;" \
- "}"]
-
-if {[test_debug_format "stabs"]} {
- setup_kfail "gdb/1603" *-*-*
-}
-gdb_test "ptype v3" "type = const char ."
+++ /dev/null
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2004-2025 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- Please email any bugs, comments, and/or additions to this file to:
- bug-gdb@gnu.org */
-
-typedef struct a a_t;
+++ /dev/null
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2004-2025 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- Please email any bugs, comments, and/or additions to this file to:
- bug-gdb@gnu.org */
-
-#include "exclfwd.h"
-
-struct a
-{
- int x, y;
-};
-
-a_t v1;
-
-int
-main ()
-{
- return 0;
-}
+++ /dev/null
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2004-2025 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- Please email any bugs, comments, and/or additions to this file to:
- bug-gdb@gnu.org */
-
-#include "exclfwd.h"
-
-struct a
-{
- const char *c;
-};
-
-a_t v2;
-const char *v3;
+++ /dev/null
-/* This testcase is part of GDB, the GNU debugger.
-
- Copyright 2010-2025 Free Software Foundation, Inc.
-
- Contributed by Pierre Muller.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- Qualifiers of forward types are not resolved correctly with stabs. */
-
-struct dummy;
-
-enum dummy_enum;
-
-/* This function prevents the compiler from dropping local variables
- we need for the test. */
-void *hack (const struct dummy *t, const enum dummy_enum *e);
-
-const void *
-test (const struct dummy *t)
-{
- const struct dummy *tt;
- enum dummy_enum *e;
- tt = t;
- return hack (t, e);
-}
-
-void *
-test2 (struct dummy *t)
-{
- struct dummy *tt;
- const enum dummy_enum *e;
- tt = t;
- return hack (t, e);
-}
-
-
-struct dummy {
- int x;
- int y;
- double b;
-} tag_dummy;
-
-enum dummy_enum {
- enum1,
- enum2
-} tag_dummy_enum;
-
-void *
-hack (const struct dummy *t, const enum dummy_enum *e)
-{
- return (void *) t;
-}
-
-int
-main ()
-{
- struct dummy tt;
- tt.x = 5;
- tt.y = 25;
- tt.b = 2.5;
- test2 (&tt);
- test (&tt);
- return 0;
-}
+++ /dev/null
-# This testcase is part of GDB, the GNU debugger.
-
-# Copyright 2010-2025 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Test GDB stabs problem with qualified parameter of forward types.
-
-standard_testfile
-
-proc do_test {version} {
- with_test_prefix "$version" {
- if { ![runto_main] } {
- return -1
- }
- gdb_test "rb test" "" "set breakpoints"
- gdb_test "continue" "Breakpoint .* test2 .*" \
- "stop at first breakpoint in test2 function"
-
- # Check that the struct is read in correctly.
- gdb_test "print *t" ".*\{x = 5, y = 25, b = 2.5\}.*" \
- "Inspect t in test2"
-
- # Check that the enum type length has been set to a non-zero value.
- gdb_test "print sizeof (*e)" "= \[1-9\]*" "sizeof (*e) in test2"
-
- gdb_test "continue" "Breakpoint .* test .*" \
- "Stop at first breakpoint test function"
-
- gdb_test "print *t" ".*\{x = 5, y = 25, b = 2.5\}.*" \
- "Inspect t in test"
-
- # Check that the enum type length has been set to a non-zero value.
- gdb_test "print sizeof (*e)" "= \[1-9\]*" "sizeof (*e) in test"
- }
-}
-
-# Compile and test with stabs debug format.
-if { [prepare_for_testing "failed to prepare" ${testfile}-stabs $srcfile \
- {debug additional_flags=-gstabs quiet}] == 0 } {
- do_test forced_stabs
-}
-
-# Compile and test with the default debug format.
-if { [prepare_for_testing "failed to prepare" ${testfile}-default \
- $srcfile] == 0 } {
- do_test natural_debug_format
-}
+++ /dev/null
-s/# Old OSF sed blows up if you have a sed command starting with "#"//
-s/# Avoid it by putting the comments within real sed commands.//
-s/# GDB legitimately expects a file name.//
-s/# The sun3 assembler bogusly requires that the value of this stab be a//
-s/# label. Placate it.//
-1i\
-\ .stabs "weird.c",0x64,0,0,Label0\
-Label0:
-s/N_LSYM/0x80/
-s/N_GSYM/0x20/
-s/# Replace a single backslash with a doubled backslash//
-/\.stabs/s/\\/\\\\/g
-s/# Only labels should be at the beginning of a line, assembler directives//
-s/# and instructions should start somewhere after column zero.//
-/^\./s/^\./ ./
-s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
-s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
-s/\.align_it/.align 4/
-s/\.globl/.export/
-/^#/d
+++ /dev/null
-# We'll need an integer type.
-.stabs "inttype:t1=bu4;0;32;",N_LSYM,0,0,0
-
-# There are several kinds of tests in here. We mix up the order to see
-# if we can test for poor handling of a stab affecting the next or previous
-# stab.
-
-# Try all possible symbol descriptors. Note that GDB should merely
-# complain() even though these strings are totally bogus. This allows
-# future compilers to define new syntaxes.
-.stabs "sym32: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-# Type descriptors.
-.stabs "type32:t32= !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-# Note that a 'G', N_GSYM symbol needs no value. The name of the stab
-# is used to look up a non-stab symbol with the same name. On some
-# machines, the non-stab symbols will normally have underscores, but
-# if they lack the underscores, then GDB will simply put the symbol in
-# the minimal symbol table all the same. So we can use them without
-# underscores and that way we don't need to worry about which machines
-# need underscores.
-
-# Type attributes.
-.stabs "attr104:G404=@h !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr105:G405=@i !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# A few real type attributes.
-# Alignment.
-.stabs "var0:G300=@a8;1",N_GSYM,0,0, 0
-.globl var0
-.data
-.align_it
-var0:
-.long 42
-
-.stabs "sym33:! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym35:# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym36:$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym37:% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym38:& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym39:' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym40:( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym41:) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym42:* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym43:+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym44:, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym45:- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.globl attr122
-.data
-.align_it
-attr122:
-.long 42
-.globl attr123
-.data
-.align_it
-attr123:
-.long 42
-.globl attr124
-.data
-.align_it
-attr124:
-.long 42
-
-.stabs "sym46:. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym47:/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym48:0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym49:1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym50:2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "attr96:G396=@` !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr97:G397=@a !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr98:G398=@b !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr99:G399=@c !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "sym51:3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym52:4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym53:5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym54:6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym55:7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym56:8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym57:9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym58:: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym59:; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym60:< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym61:= !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym62:> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym63:? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym64:@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym65:A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym66:B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym67:C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym68:D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym69:E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym70:F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym71:G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym72:H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym73:I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym74:J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym75:K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym76:L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym77:M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym78:N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym79:O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym80:P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym81:Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym82:R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym83:S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym84:T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym85:U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym86:V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym87:W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym88:X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym89:Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym90:Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym91:[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "sym93:] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym94:^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym95:_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym96:` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym97:a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym98:b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym99:c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym100:d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym101:e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym102:f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym103:g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym104:h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym105:i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym106:j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym107:k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym108:l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym109:m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym110:n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym111:o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym112:p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym113:q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym114:r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym115:s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym116:t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym117:u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym118:v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym119:w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym120:x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym121:y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym122:z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym123:{ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym124:| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym125:} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym126:~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "type33:t33=! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type35:t35=# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type36:t36=$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type37:t37=% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type38:t38=& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type39:t39=' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type40:t40=( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type41:t41=) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type42:t42=* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type43:t43=+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type44:t44=, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type45:t45=- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type46:t46=. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type47:t47=/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type48:t48=0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type49:t49=1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type50:t50=2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type51:t51=3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type52:t52=4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type53:t53=5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type54:t54=6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type55:t55=7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type56:t56=8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type57:t57=9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type58:t58=: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type59:t59=; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type60:t60=< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type61:t61== !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type62:t62=> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type63:t63=? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type64:t64=@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type65:t65=A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type66:t66=B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type67:t67=C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.globl attr66
-.data
-.align_it
-attr66:
-.long 42
-.globl attr67
-.data
-.align_it
-attr67:
-.long 42
-.globl attr68
-.data
-.align_it
-attr68:
-.long 42
-.globl attr69
-.data
-.align_it
-attr69:
-.long 42
-
-.stabs "type68:t68=D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type69:t69=E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type70:t70=F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type71:t71=G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type72:t72=H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type73:t73=I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type74:t74=J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type75:t75=K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type76:t76=L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type77:t77=M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type78:t78=N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type79:t79=O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type80:t80=P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type81:t81=Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type82:t82=R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type83:t83=S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type84:t84=T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type85:t85=U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type86:t86=V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type87:t87=W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "attr69:G369=@E !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr70:G370=@F !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr71:G371=@G !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "type88:t88=X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type89:t89=Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type90:t90=Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type91:t91=[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "type93:t93=] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type94:t94=^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type95:t95=_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type96:t96=` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type97:t97=a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type98:t98=b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type99:t99=c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type100:t100=d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type101:t101=e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type102:t102=f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type103:t103=g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type104:t104=h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type105:t105=i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type106:t106=j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type107:t107=k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type108:t108=l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type109:t109=m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type110:t110=n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type111:t111=o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type112:t112=p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type113:t113=q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type114:t114=r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type115:t115=s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type116:t116=t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type117:t117=u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type118:t118=v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type119:t119=w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type120:t120=x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type121:t121=y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type122:t122=z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type123:t123={ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type124:t124=| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type125:t125=} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type126:t126=~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "attr32:G332=@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr33:G333=@! !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr35:G334=@# !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr36:G335=@$ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr37:G337=@% !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Test 'e' constant on non-enum type.
-.stabs "const69:c=e1,69", N_LSYM,0,0, 0
-
-# Test constant with the type embedded.
-.stabs "const70:c=e190=bs2;0;16;,70", N_LSYM,0,0, 0
-
-# Test char constant
-.stabs "constchar:c=c97", N_LSYM,0,0, 0
-
-# Test string constant
-.stabs "constString1:c=s'Single quote String1'", N_LSYM,0,0, 0
-# Using double quotes requires an escaping, as the stabs string
-# is a double quote delimited string.
-.stabs "constString2:c=s\"Double quote String2\"", N_LSYM,0,0, 0
-# Escaping single quote with is easy
-.stabs "constString3:c=s'String3 with embedded quote \' in the middle'", N_LSYM,0,0, 0
-# Esaping double quotes is less clear...
-.stabs "constString4:c=s\"String4 with embedded quote \\" in the middle\"", N_LSYM,0,0, 0
-
-
-.stabs "attr38:G338=@& !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Unrecognized negative type number.
-.stabs "bad_neg0type:t201=s16field0:1,0,32;field2:-534,32,64;field3:-1,96,32;;", N_LSYM,0,0, 0
-
-.stabs "bad_neg0:G201", N_GSYM,0,0, 0
-
-.globl bad_neg0
-.data
-.align_it
-bad_neg0:
-.long 42
- .long 43, 44, 45
-
-.stabs "attr39:G339=@' !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr41:G341=@) !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr42:G342=@* !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr43:G343=@+ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr44:G344=@, !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr46:G346=@. !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr47:G347=@/ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr58:G358=@: !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Test two type attributes for one type.
-.stabs "attr59:G359=@;@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr60:G360=@< !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr61:G361=@= !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr62:G362=@> !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr63:G363=@? !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr64:G364=@@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr65:G365=@A !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr66:G366=@B !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr67:G367=@C !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr68:G368=@D !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr72:G372=@H !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr73:G373=@I !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr74:G374=@J !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr75:G375=@K !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr76:G376=@L !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr77:G377=@M !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr78:G378=@N !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr79:G379=@O !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr80:G380=@P !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr81:G381=@Q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr82:G382=@R !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr83:G383=@S !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr84:G384=@T !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr85:G385=@U !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr86:G386=@V !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr87:G387=@W !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr88:G388=@X !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr89:G389=@Y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr90:G390=@Z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr91:G391=@[ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr93:G393=@] !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Do with and without underscore, so this wins regardless of whether
-# names have underscores.
-
-.globl _common0
-.data
-.align_it
-_common0:
-.long 42
- .long 24
- .long 22
-.globl common0
-.data
-.align_it
-common0:
-.long 42
- .long 24
- .long 22
-.begin_common "common0"
-.stabs "common0var0:S1", N_GSYM,0,0, 0
-.stabs "common0var1:S1", N_GSYM,0,0, 4
-.stabs "common0var2:S1", N_GSYM,0,0, 8
-.end_common "common0"
-
-.stabs "attr94:G394=@^ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr95:G395=@_ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr100:G400=@d !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr101:G401=@e !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr102:G402=@f !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr103:G403=@g !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr106:G406=@j !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr107:G407=@k !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr108:G408=@l !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr109:G409=@m !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr110:G410=@n !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr111:G411=@o !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr112:G412=@p !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr113:G413=@q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr114:G414=@r !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr115:G415=@s !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr116:G416=@t !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr117:G417=@u !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr118:G418=@v !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr119:G419=@w !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr120:G420=@x !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr121:G421=@y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr122:G422=@z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr123:G423=@{ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr124:G424=@| !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr125:G425=@} !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr126:G426=@~ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Define a variable for all the above stabs.
-.globl attr32
-.data
-.align_it
-attr32:
-.long 42
-.globl attr33
-.data
-.align_it
-attr33:
-.long 42
-.globl attr35
-.data
-.align_it
-attr35:
-.long 42
-.globl attr36
-.data
-.align_it
-attr36:
-.long 42
-.globl attr37
-.data
-.align_it
-attr37:
-.long 42
-.globl attr38
-.data
-.align_it
-attr38:
-.long 42
-.globl attr39
-.data
-.align_it
-attr39:
-.long 42
-.globl attr41
-.data
-.align_it
-attr41:
-.long 42
-.globl attr42
-.data
-.align_it
-attr42:
-.long 42
-.globl attr43
-.data
-.align_it
-attr43:
-.long 42
-.globl attr44
-.data
-.align_it
-attr44:
-.long 42
-.globl attr46
-.data
-.align_it
-attr46:
-.long 42
-.globl attr47
-.data
-.align_it
-attr47:
-.long 42
-.globl attr58
-.data
-.align_it
-attr58:
-.long 42
-.globl attr59
-.data
-.align_it
-attr59:
-.long 42
-.globl attr60
-.data
-.align_it
-attr60:
-.long 42
-.globl attr61
-.data
-.align_it
-attr61:
-.long 42
-.globl attr62
-.data
-.align_it
-attr62:
-.long 42
-.globl attr63
-.data
-.align_it
-attr63:
-.long 42
-.globl attr64
-.data
-.align_it
-attr64:
-.long 42
-.globl attr65
-.data
-.align_it
-attr65:
-.long 42
-.globl attr70
-.data
-.align_it
-attr70:
-.long 42
-.globl attr71
-.data
-.align_it
-attr71:
-.long 42
-.globl attr72
-.data
-.align_it
-attr72:
-.long 42
-.globl attr73
-.data
-.align_it
-attr73:
-.long 42
-.globl attr74
-.data
-.align_it
-attr74:
-.long 42
-.globl attr75
-.data
-.align_it
-attr75:
-.long 42
-.globl attr76
-.data
-.align_it
-attr76:
-.long 42
-.globl attr77
-.data
-.align_it
-attr77:
-.long 42
-.globl attr78
-.data
-.align_it
-attr78:
-.long 42
-.globl attr79
-.data
-.align_it
-attr79:
-.long 42
-.globl attr80
-.data
-.align_it
-attr80:
-.long 42
-.globl attr81
-.data
-.align_it
-attr81:
-.long 42
-.globl attr82
-.data
-.align_it
-attr82:
-.long 42
-.globl attr83
-.data
-.align_it
-attr83:
-.long 42
-.globl attr84
-.data
-.align_it
-attr84:
-.long 42
-
-# Unrecognized floating point code.
-.stabs "float72type:t202=R87;9;", N_LSYM,0,0, 0
-
-# 256-bit integer. The point is obviously not that GDB should have a
-# special case for this size, but that an integer of any size should
-# work (at least for printing in hex, not necessarily for arithmetic.
-.stabs "int256var:G203=bu32;0;256;", N_GSYM,0,0, 0
-# The value is palindromic, so it works whether words are big or little
-# endian.
-.globl int256var
-.data
-.align_it
- int256var:
-.long 42
- .long 0x2b, 0x2c, 0x2d, 0x2d, 0x2c, 0x2b, 0x2a
-
-# Huge value in constant should at least get the type right.
-
-# This value is just big enough not to fit in 32 bits.
-.stabs "consth:c=e1,4294967296", N_LSYM,0,0, 0
-
-.stabs "consth2:c=e1,-734723985732642758928475678987234563284937456", N_LSYM,0,0, 0
-
-# Test a struct constant using S.
-.stabs "bad_neg0const:c=S201,128,128,11222211343434345656565677888877", N_LSYM,0,0, 0
-
-# Bad filenumbers.
-# This one is totally bogus.
-.stabs "bad_type0:t(-3,7)", N_LSYM,0,0, 0
-# This one probably gets interpreted as a forward reference.
-.stabs "bad_type1:t(42,6)", N_LSYM,0,0, 0
-
-# Arrays indexed by weird things.
-.stabs "array_index0:t205=r1;0;5;", N_LSYM,0,0, 0
-.stabs "array0:G206=a205;1", N_GSYM,0,0, 0
-.globl array0
-.data
-.align_it
- array0:
-.long 42
- .long 43, 44, 45, 46, 47
-
-.stabs "array_index1:t207=", N_LSYM,0,0, 0
-.stabs "array1:G208=aeai1_red:0,ai1_green:1,ai1_blue:2,;;1", N_GSYM,0,0, 0
-.globl array1
-.data
-.align_it
- array1:
-.long 42
- .long 43, 44
-
-# See if GDB can deal with it if the compiler gets smarter about saying
-# which variables were defined with which types.
-.stabs "inttype_one:t209=1", N_LSYM,0,0, 0
-.stabs "inttype_two:t210=1", N_LSYM,0,0, 0
-.stabs "one_var:G209", N_GSYM,0,0, 0
-.globl one_var
-.data
-.align_it
-one_var:
-.long 42
-.stabs "two_var:G210", N_GSYM,0,0, 0
-.globl two_var
-.data
-.align_it
-two_var:
-.long 42
-
-# And see if the caddr_t hack can deal with the same thing.
-.stabs "intp:t211=*1", N_LSYM,0,0, 0
-# If it weren't for this variable, we'd need to ignore the intp name.
-.stabs "pointer_to_int_var:G212=*1", N_LSYM,0,0, 0
-.stabs "intp_var:G211", N_GSYM,0,0, 0
-.globl intp_var
-.data
-.align_it
-intp_var:
-.long 42
-
-# Unrecognized constant code.
-.stabs "unrecog_const:c=xjksdflskd33,4;473;", N_LSYM,0,0, 0
-
-.globl attr85
-.data
-.align_it
-attr85:
-.long 42
-.globl attr86
-.data
-.align_it
-attr86:
-.long 42
-.globl attr87
-.data
-.align_it
-attr87:
-.long 42
-.globl attr88
-.data
-.align_it
-attr88:
-.long 42
-.globl attr89
-.data
-.align_it
-attr89:
-.long 42
-.globl attr90
-.data
-.align_it
-attr90:
-.long 42
-.globl attr91
-.data
-.align_it
-attr91:
-.long 42
-.globl attr92
-.data
-.align_it
-attr92:
-.long 42
-.globl attr93
-.data
-.align_it
-attr93:
-.long 42
-.globl attr94
-.data
-.align_it
-attr94:
-.long 42
-.globl attr95
-.data
-.align_it
-attr95:
-.long 42
-.globl attr96
-.data
-.align_it
-attr96:
-.long 42
-.globl attr97
-.data
-.align_it
-attr97:
-.long 42
-.globl attr98
-.data
-.align_it
-attr98:
-.long 42
-.globl attr99
-.data
-.align_it
-attr99:
-.long 42
-.globl attr100
-.data
-.align_it
-attr100:
-.long 42
-.globl attr101
-.data
-.align_it
-attr101:
-.long 42
-.globl attr102
-.data
-.align_it
-attr102:
-.long 42
-.globl attr103
-.data
-.align_it
-attr103:
-.long 42
-.globl attr104
-.data
-.align_it
-attr104:
-.long 42
-.globl attr105
-.data
-.align_it
-attr105:
-.long 42
-.globl attr106
-.data
-.align_it
-attr106:
-.long 42
-.globl attr107
-.data
-.align_it
-attr107:
-.long 42
-.globl attr108
-.data
-.align_it
-attr108:
-.long 42
-.globl attr109
-.data
-.align_it
-attr109:
-.long 42
-.globl attr110
-.data
-.align_it
-attr110:
-.long 42
-.globl attr111
-.data
-.align_it
-attr111:
-.long 42
-.globl attr112
-.data
-.align_it
-attr112:
-.long 42
-.globl attr113
-.data
-.align_it
-attr113:
-.long 42
-.globl attr114
-.data
-.align_it
-attr114:
-.long 42
-.globl attr115
-.data
-.align_it
-attr115:
-.long 42
-.globl attr116
-.data
-.align_it
-attr116:
-.long 42
-.globl attr117
-.data
-.align_it
-attr117:
-.long 42
-.globl attr118
-.data
-.align_it
-attr118:
-.long 42
-.globl attr119
-.data
-.align_it
-attr119:
-.long 42
-.globl attr120
-.data
-.align_it
-attr120:
-.long 42
-.globl attr121
-.data
-.align_it
-attr121:
-.long 42
-.globl attr125
-.data
-.align_it
-attr125:
-.long 42
-.globl attr126
-.data
-.align_it
-attr126:
-.long 42
-
-# Size.
-.stabs "var1:G301=@s32;1",N_GSYM,0,0, 0
-.globl var1
-.data
-.align_it
-var1:
-.long 42
-# Pointer class.
-.stabs "var2:G302=@p42;1",N_GSYM,0,0, 0
-.globl var2
-.data
-.align_it
-var2:
-.long 42
-# Packed type.
-.stabs "var3:G303=@P;1",N_GSYM,0,0, 0
-.globl var3
-.data
-.align_it
-var3:
-.long 42
-
-.stabs "sym92:\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type92:t92=\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "attr92:G392=@\ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# See read_args "Invalid (empty) method arguments" error; there is an
-# unexpected semi-colon after =@s8;-16 that used to cause a GDB crash.
-.stabs "args93:G93=#(0,93),(0,93)=@s8;-16;,(0,93),(0,93);",N_GSYM,0,0,0
+++ /dev/null
-# Put everything in this csect, which seems to make things work.
-# The compiler actually puts the stabs in .csect [PR], but that didn't
-# work here (I guess because there is no text section).
-1i\
- .csect .data[RW]
-# .stabs string,type,0,0,value -> .stabx string,value,type,0
-s/^[ ]*\.stabs[ ]*("(\"|[^"])*"),[ ]*([^,]*),[ ]*0,0,[ ]*(.*)$/.stabx \1,\4,\3,0/
-s/N_GSYM/128/
-# This needs to be C_DECL, which is used for types, not C_LSYM, which is
-# ignored on the initial scan.
-s/N_LSYM/140/
-s/\.begin_common/.bc/
-# The AIX assembler doesn't want the name in a .ec directive
-s/\.end_common.*/.ec/
-s/\.align_it/.align 1/
-/\.data/d
-/^#/d