From: Guinevere Larsen Date: Wed, 12 Feb 2025 13:40:06 +0000 (-0300) Subject: gdb: Fully remove stabs code from GDB X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eaea19f98d87e95d6b9a05a902e6a0c5d736774d;p=thirdparty%2Fbinutils-gdb.git gdb: Fully remove stabs code from GDB 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 Approved-By: Tom Tromey --- diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 29b4efa58e9..381c064bc4e 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1199,7 +1199,6 @@ COMMON_SFILES = \ source.c \ source-cache.c \ split-name.c \ - stabsread.c \ stack.c \ std-regs.c \ symfile.c \ @@ -1674,7 +1673,6 @@ HFILES_NO_SRCDIR = \ sparc-ravenscar-thread.h \ sparc-tdep.h \ split-name.h \ - stabsread.h \ stack.h \ stap-probe.h \ svr4-tls-tdep.h \ diff --git a/gdb/NEWS b/gdb/NEWS index b0146852c5c..2c94e786f41 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -31,6 +31,8 @@ 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* diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 2b9628e2439..8e3f79089d4 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -324,12 +324,6 @@ generic_convert_register_p (struct gdbarch *gdbarch, int regnum, 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) diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 14a84b74733..6aa4270a118 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -261,9 +261,6 @@ extern int default_code_of_frame_writable (struct gdbarch *gdbarch, 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); diff --git a/gdb/buildsym.c b/gdb/buildsym.c index b4b8b0a5215..af3f5f792fc 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -34,11 +34,6 @@ #include "dictionary.h" #include -/* 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. */ @@ -806,19 +801,6 @@ buildsym_compunit::end_compunit_symtab_get_static_block (CORE_ADDR end_addr, 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 diff --git a/gdb/dbxread.c b/gdb/dbxread.c index da2156e3380..0a6e13f08d2 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -74,6 +74,15 @@ explicit_lookup_type (int real_filenum, int index) } #endif + +const registry::key 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", diff --git a/gdb/doc/Makefile.in b/gdb/doc/Makefile.in index a2953b4d34a..c22865a1dff 100644 --- a/gdb/doc/Makefile.in +++ b/gdb/doc/Makefile.in @@ -94,15 +94,15 @@ SET_TEXINPUTS = \ 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 @@ -156,17 +156,6 @@ GDB_DOC_FILES = \ $(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 @@ -207,7 +196,7 @@ all: info 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) @@ -593,29 +582,6 @@ gdb/index.html: ${GDB_DOC_FILES} $(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) \ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index e0fc0ff98ab..da211d9c8d6 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -20453,7 +20453,7 @@ if the debug information provides it, the program that compiled the file (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. @@ -22038,9 +22038,7 @@ Warnings and Messages}.) 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 @@ -23148,7 +23146,7 @@ Instead you must do, for example, $ gdb -iex "set use-deprecated-index-sections on" @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 @@ -42476,14 +42474,13 @@ and the full path if known. 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 diff --git a/gdb/doc/stabs.texinfo b/gdb/doc/stabs.texinfo deleted file mode 100644 index eac342a6f73..00000000000 --- a/gdb/doc/stabs.texinfo +++ /dev/null @@ -1,4130 +0,0 @@ -\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. - -<> -@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 diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c index 7887b1386c6..9623a75f4df 100644 --- a/gdb/gdbarch-gen.c +++ b/gdb/gdbarch-gen.c @@ -140,7 +140,6 @@ struct gdbarch 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; @@ -409,7 +408,6 @@ verify_gdbarch (struct gdbarch *gdbarch) /* 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. */ @@ -910,9 +908,6 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) 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)); @@ -3174,23 +3169,6 @@ set_gdbarch_frame_align (struct gdbarch *gdbarch, 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) { diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index 24fa8bab2db..180e7ced7ed 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -666,10 +666,6 @@ typedef CORE_ADDR (gdbarch_frame_align_ftype) (struct gdbarch *gdbarch, CORE_ADD 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); diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index 3820ae3c94c..eac068028ed 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -1201,14 +1201,6 @@ Method( 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", diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c index d2641779906..72233444f34 100644 --- a/gdb/microblaze-tdep.c +++ b/gdb/microblaze-tdep.c @@ -584,12 +584,6 @@ microblaze_return_value (struct gdbarch *gdbarch, struct value *function, 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 @@ -794,8 +788,6 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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); diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 3c4e568b98c..35ef6035bc7 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -152,9 +152,6 @@ struct objstats /* 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; diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index bbc33dcbad7..926afa3b930 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1540,14 +1540,6 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function, 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) { @@ -1859,8 +1851,6 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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); diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c index 4cf60458bce..32beb9bb250 100644 --- a/gdb/sparc64-tdep.c +++ b/gdb/sparc64-tdep.c @@ -1838,8 +1838,6 @@ sparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 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); diff --git a/gdb/stabsread.c b/gdb/stabsread.c deleted file mode 100644 index 05a7c27c5df..00000000000 --- a/gdb/stabsread.c +++ /dev/null @@ -1,7209 +0,0 @@ -/* 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 . */ - -/* 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::key 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 - - -/* 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)); - } - } - } - } -} - - -/* 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; -} - - -/* 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 = ""; - } - 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 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 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 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 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 - ":" ("t" | "T") [ "="] "e" - { ":" ","} ";". */ - - /* 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 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; -} - - -/* 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 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 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; -} - -/* 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::key> - 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; -} - -/* 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 _("" 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 = ""; - 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;lower;upper;". - OS9000: "arlower,upper;". - - 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 = 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 is an unsigned large integral type. */ - else if ((n2bits == 0 && n2 == 0) && n3bits != 0) - { - got_unsigned = 1; - nbits = n3bits; - } - /* Range from to -1 is a large signed - integral type. Take care of the case where doesn't - fit in a long but -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; -} - -/* 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); - } - } -} - - - -/* 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); -} diff --git a/gdb/stabsread.h b/gdb/stabsread.h deleted file mode 100644 index 1c9ce854dff..00000000000 --- a/gdb/stabsread.h +++ /dev/null @@ -1,309 +0,0 @@ -/* 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 . */ - -#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; - -/* 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); - -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 &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 */ diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 78c44e89948..06b11a47784 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -59,9 +59,6 @@ print_objfile_statistics (void) { 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); diff --git a/gdb/testsuite/gdb.stabs/aout.sed b/gdb/testsuite/gdb.stabs/aout.sed deleted file mode 100644 index 1bc5b1d7bc3..00000000000 --- a/gdb/testsuite/gdb.stabs/aout.sed +++ /dev/null @@ -1,16 +0,0 @@ -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 diff --git a/gdb/testsuite/gdb.stabs/ecoff.sed b/gdb/testsuite/gdb.stabs/ecoff.sed deleted file mode 100644 index 3411c294198..00000000000 --- a/gdb/testsuite/gdb.stabs/ecoff.sed +++ /dev/null @@ -1,17 +0,0 @@ -# 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/ diff --git a/gdb/testsuite/gdb.stabs/exclfwd.exp b/gdb/testsuite/gdb.stabs/exclfwd.exp deleted file mode 100644 index b2adbf87e8e..00000000000 --- a/gdb/testsuite/gdb.stabs/exclfwd.exp +++ /dev/null @@ -1,57 +0,0 @@ -# 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 . - -# 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 ." diff --git a/gdb/testsuite/gdb.stabs/exclfwd.h b/gdb/testsuite/gdb.stabs/exclfwd.h deleted file mode 100644 index d9ce9ffc36b..00000000000 --- a/gdb/testsuite/gdb.stabs/exclfwd.h +++ /dev/null @@ -1,21 +0,0 @@ -/* 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 . - - Please email any bugs, comments, and/or additions to this file to: - bug-gdb@gnu.org */ - -typedef struct a a_t; diff --git a/gdb/testsuite/gdb.stabs/exclfwd1.c b/gdb/testsuite/gdb.stabs/exclfwd1.c deleted file mode 100644 index 23700ecb507..00000000000 --- a/gdb/testsuite/gdb.stabs/exclfwd1.c +++ /dev/null @@ -1,34 +0,0 @@ -/* 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 . - - 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; -} diff --git a/gdb/testsuite/gdb.stabs/exclfwd2.c b/gdb/testsuite/gdb.stabs/exclfwd2.c deleted file mode 100644 index 9bd4a7065d9..00000000000 --- a/gdb/testsuite/gdb.stabs/exclfwd2.c +++ /dev/null @@ -1,29 +0,0 @@ -/* 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 . - - 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; diff --git a/gdb/testsuite/gdb.stabs/gdb11479.c b/gdb/testsuite/gdb.stabs/gdb11479.c deleted file mode 100644 index d094899d7f8..00000000000 --- a/gdb/testsuite/gdb.stabs/gdb11479.c +++ /dev/null @@ -1,76 +0,0 @@ -/* 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 . - - 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; -} diff --git a/gdb/testsuite/gdb.stabs/gdb11479.exp b/gdb/testsuite/gdb.stabs/gdb11479.exp deleted file mode 100644 index 2318c0f6cdc..00000000000 --- a/gdb/testsuite/gdb.stabs/gdb11479.exp +++ /dev/null @@ -1,59 +0,0 @@ -# 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 . - -# 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 -} diff --git a/gdb/testsuite/gdb.stabs/hppa.sed b/gdb/testsuite/gdb.stabs/hppa.sed deleted file mode 100644 index bc1cf90f7b2..00000000000 --- a/gdb/testsuite/gdb.stabs/hppa.sed +++ /dev/null @@ -1,20 +0,0 @@ -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 diff --git a/gdb/testsuite/gdb.stabs/weird.def b/gdb/testsuite/gdb.stabs/weird.def deleted file mode 100644 index f809963e82f..00000000000 --- a/gdb/testsuite/gdb.stabs/weird.def +++ /dev/null @@ -1,900 +0,0 @@ -# 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 diff --git a/gdb/testsuite/gdb.stabs/xcoff.sed b/gdb/testsuite/gdb.stabs/xcoff.sed deleted file mode 100644 index 6dc81985096..00000000000 --- a/gdb/testsuite/gdb.stabs/xcoff.sed +++ /dev/null @@ -1,17 +0,0 @@ -# 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