📄 stabs.html
字号:
43 LM3:44 LBE2:45 .stabn 68,0,6,LM446 LM4:47 L1:48 ret49 restore50 .stabs "main:F1",36,0,0,_main51 .stabn 192,0,0,LBB252 .stabn 224,0,0,LBE2</PRE><H1><A NAME="SEC7" HREF="stabs_toc.html#TOC7">Encoding the Structure of the Program</A></H1><P>The elements of the program structure that stabs encode include the nameof the main function, the names of the source and include files, theline numbers, procedure names and types, and the beginnings and ends ofblocks of code.</P><H2><A NAME="SEC8" HREF="stabs_toc.html#TOC8">Main Program</A></H2><P><A NAME="IDX1"></A>Most languages allow the main program to have any name. The<CODE>N_MAIN</CODE> stab type tells the debugger the name that is used in thisprogram. Only the string field is significant; it is the name ofa function which is the main program. Most C compilers do not use thisstab (they expect the debugger to assume that the name is <CODE>main</CODE>),but some C compilers emit an <CODE>N_MAIN</CODE> stab for the <CODE>main</CODE>function. I'm not sure how XCOFF handles this.</P><H2><A NAME="SEC9" HREF="stabs_toc.html#TOC9">Paths and Names of the Source Files</A></H2><P><A NAME="IDX2"></A>Before any other stabs occur, there must be a stab specifying the sourcefile. This information is contained in a symbol of stab type<CODE>N_SO</CODE>; the string field contains the name of the file. Thevalue of the symbol is the start address of the portion of thetext section corresponding to that file.</P><P>With the Sun Solaris2 compiler, the desc field contains asource-language code.</P><P>Some compilers (for example, GCC2 and SunOS4 <TT>`/bin/cc'</TT>) alsoinclude the directory in which the source was compiled, in a second<CODE>N_SO</CODE> symbol preceding the one containing the file name. Thissymbol can be distinguished by the fact that it ends in a slash. Codefrom the <CODE>cfront</CODE> C++ compiler can have additional <CODE>N_SO</CODE> symbols fornonexistent source files after the <CODE>N_SO</CODE> for the real source file;these are believed to contain no useful information.</P><P>For example:</P><PRE>.stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0 # 100 is N_SO.stabs "hello.c",100,0,0,Ltext0 .textLtext0:</PRE><P><A NAME="IDX3"></A>Instead of <CODE>N_SO</CODE> symbols, XCOFF uses a <CODE>.file</CODE> assemblerdirective which assembles to a <CODE>C_FILE</CODE> symbol; explaining this indetail is outside the scope of this document.</P><P>If it is useful to indicate the end of a source file, this is done withan <CODE>N_SO</CODE> symbol with an empty string for the name. The value isthe address of the end of the text section for the file. For somesystems, there is no indication of the end of a source file, and youjust need to figure it ended when you see an <CODE>N_SO</CODE> for a differentsource file, or a symbol ending in <CODE>.o</CODE> (which at least somelinkers insert to mark the start of a new <CODE>.o</CODE> file).</P><H2><A NAME="SEC10" HREF="stabs_toc.html#TOC10">Names of Include Files</A></H2><P>There are several schemes for dealing with include files: thetraditional <CODE>N_SOL</CODE> approach, Sun's <CODE>N_BINCL</CODE> approach, and theXCOFF <CODE>C_BINCL</CODE> approach (which despite the similar name has little incommon with <CODE>N_BINCL</CODE>).</P><P><A NAME="IDX4"></A>An <CODE>N_SOL</CODE> symbol specifies which include file subsequent symbolsrefer to. The string field is the name of the file and the value is thetext address corresponding to the end of the previous include file andthe start of this one. To specify the main source file again, use an<CODE>N_SOL</CODE> symbol with the name of the main source file.</P><P><A NAME="IDX5"></A><A NAME="IDX6"></A><A NAME="IDX7"></A>The <CODE>N_BINCL</CODE> approach works as follows. An <CODE>N_BINCL</CODE> symbolspecifies the start of an include file. In an object file, only thestring is significant; the linker puts data into some of the otherfields. The end of the include file is marked by an <CODE>N_EINCL</CODE>symbol (which has no string field). In an object file, there is nosignificant data in the <CODE>N_EINCL</CODE> symbol. <CODE>N_BINCL</CODE> and<CODE>N_EINCL</CODE> can be nested.</P><P>If the linker detects that two source files have identical stabs betweenan <CODE>N_BINCL</CODE> and <CODE>N_EINCL</CODE> pair (as will generally be the casefor a header file), then it only puts out the stabs once. Eachadditional occurrence is replaced by an <CODE>N_EXCL</CODE> symbol. I believethe GNU linker and the Sun (both SunOS4 and Solaris) linker are the onlyones which supports this feature.</P><P>A linker which supports this feature will set the value of a<CODE>N_BINCL</CODE> symbol to the total of all the characters in the stabsstrings included in the header file, omitting any file numbers. Thevalue of an <CODE>N_EXCL</CODE> symbol is the same as the value of the<CODE>N_BINCL</CODE> symbol it replaces. This information can be used tomatch up <CODE>N_EXCL</CODE> and <CODE>N_BINCL</CODE> symbols which have the samefilename. The <CODE>N_EINCL</CODE> value, and the values of the other anddescription fields for all three, appear to always be zero.</P><P><A NAME="IDX8"></A><A NAME="IDX9"></A>For the start of an include file in XCOFF, use the <TT>`.bi'</TT> assemblerdirective, which generates a <CODE>C_BINCL</CODE> symbol. A <TT>`.ei'</TT>directive, which generates a <CODE>C_EINCL</CODE> symbol, denotes the end ofthe include file. Both directives are followed by the name of thesource file in quotes, which becomes the string for the symbol.The value of each symbol, produced automatically by the assemblerand 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 includefile. <CODE>C_BINCL</CODE> and <CODE>C_EINCL</CODE> do not nest.</P><H2><A NAME="SEC11" HREF="stabs_toc.html#TOC11">Line Numbers</A></H2><P><A NAME="IDX10"></A>An <CODE>N_SLINE</CODE> symbol represents the start of a source line. Thedesc field contains the line number and the value contains the codeaddress for the start of that source line. On most machines the addressis absolute; for stabs in sections (see section <A HREF="stabs.html#SEC87">Using Stabs in Their Own Sections</A>), it isrelative to the function in which the <CODE>N_SLINE</CODE> symbol occurs.</P><P><A NAME="IDX11"></A><A NAME="IDX12"></A>GNU documents <CODE>N_DSLINE</CODE> and <CODE>N_BSLINE</CODE> symbols for linenumbers in the data or bss segments, respectively. They are identicalto <CODE>N_SLINE</CODE> but are relocated differently by the linker. Theywere intended to be used to describe the source location of a variabledeclaration, but I believe that GCC2 actually puts the line number inthe desc field of the stab for the variable itself. GDB has beenignoring these symbols (unless they contain a string field) sinceat least GDB 3.5.</P><P>For single source lines that generate discontiguous code, such as flowof control statements, there may be more than one line number entry forthe same source line. In this case there is a line number entry at thestart of each code range, each with the same line number.</P><P>XCOFF does not use stabs for line numbers. Instead, it uses COFF linenumbers (which are outside the scope of this document). Standard COFFline numbers cannot deal with include files, but in XCOFF this is fixedwith the <CODE>C_BINCL</CODE> method of marking include files (see section <A HREF="stabs.html#SEC10">Names of Include Files</A>).</P><H2><A NAME="SEC12" HREF="stabs_toc.html#TOC12">Procedures</A></H2><P><A NAME="IDX13"></A><A NAME="IDX14"></A><A NAME="IDX15"></A><A NAME="IDX16"></A>All of the following stabs normally use the <CODE>N_FUN</CODE> symbol type.However, Sun's <CODE>acc</CODE> compiler on SunOS4 uses <CODE>N_GSYM</CODE> and<CODE>N_STSYM</CODE>, which means that the value of the stab for the functionis useless and the debugger must get the address of the function fromthe non-stab symbols instead. On systems where non-stab symbols haveleading underscores, the stabs will lack underscores and the debuggerneeds to know about the leading underscore to match up the stab and thenon-stab symbol. BSD Fortran is said to use <CODE>N_FNAME</CODE> with thesame restriction; the value of the symbol is not useful (I'm not sure itreally does use this, because GDB doesn't handle this and no one hascomplained).</P><P><A NAME="IDX17"></A>A function is represented by an <SAMP>`F'</SAMP> symbol descriptor for a global(extern) function, and <SAMP>`f'</SAMP> for a static (local) function. Fora.out, the value of the symbol is the address of the start of thefunction; it is already relocated. For stabs in ELF, the SunPROcompiler version 2.0.1 and GCC put out an address which gets relocatedby 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'mnot sure how to find which symbol of that name is the right one, andthis doesn't provide any way to deal with nested functions, it wouldprobably be better to make the value of the stab an address relative tothe start of the file, or just absolute. See section <A HREF="stabs.html#SEC89">Having the Linker Relocate Stabs in ELF</A> for more information on linker relocation of stabs in ELFfiles. For XCOFF, the stab uses the <CODE>C_FUN</CODE> storage class and thevalue of the stab is meaningless; the address of the function can befound from the csect symbol (XTY_LD/XMC_PR).</P><P>The type information of the stab represents the return type of thefunction; thus <SAMP>`foo:f5'</SAMP> means that foo is a function returning type5. There is no need to try to get the line number of the start of thefunction from the stab for the function; it is in the next<CODE>N_SLINE</CODE> symbol.</P><P>Some compilers (such as Sun's Solaris compiler) support an extension forspecifying the types of the arguments. I suspect this extension is notused for old (non-prototyped) function definitions in C. If theextension is in use, the type information of the stab for the functionis followed by type information for each argument, with each argumentpreceded by <SAMP>`;'</SAMP>. An argument type of 0 means that additionalarguments are being passed, whose types and number may vary (<SAMP>`...'</SAMP>in ANSI C). GDB has tolerated this extension (parsed the syntax, if notnecessarily used the information) since at least version 4.8; I don'tknow whether all versions of dbx tolerate it. The argument types givenhere are not redundant with the symbols for the formal parameters(see section <A HREF="stabs.html#SEC24">Parameters</A>); they are the types of the arguments as they arepassed, before any conversions might take place. For example, if a Cfunction which is declared without a prototype takes a <CODE>float</CODE>argument, the value is passed as a <CODE>double</CODE> but then converted to a<CODE>float</CODE>. Debuggers need to use the types given in the argumentswhen printing values, but when calling the function they need to use thetypes given in the symbol defining the function.</P><P>If the return type and types of arguments of a function which is definedin another source file are specified (i.e., a function prototype in ANSIC), traditionally compilers emit no stab; the only way for the debuggerto find the information is if the source file where the function isdefined was also compiled with debugging symbols. As an extension theSolaris compiler uses symbol descriptor <SAMP>`P'</SAMP> followed by the returntype of the function, followed by the arguments, each preceded by<SAMP>`;'</SAMP>, as in a stab with symbol descriptor <SAMP>`f'</SAMP> or <SAMP>`F'</SAMP>.This use of symbol descriptor <SAMP>`P'</SAMP> can be distinguished from its usefor register parameters (see section <A HREF="stabs.html#SEC25">Passing Parameters in Registers</A>) by the fact that it hassymbol type <CODE>N_FUN</CODE>.</P><P>The AIX documentation also defines symbol descriptor <SAMP>`J'</SAMP> as aninternal function. I assume this means a function nested within anotherfunction. It also says symbol descriptor <SAMP>`m'</SAMP> is a module inModula-2 or extended Pascal.</P><P>Procedures (functions which do not return values) are represented asfunctions returning the <CODE>void</CODE> type in C. I don't see why this couldn'tbe used for all languages (inventing a <CODE>void</CODE> type for this purpose ifnecessary), but the AIX documentation defines <SAMP>`I'</SAMP>, <SAMP>`P'</SAMP>, and<SAMP>`Q'</SAMP> for internal, global, and static procedures, respectively.These symbol descriptors are unusual in that they are not followed bytype information.</P><P>The following example shows a stab for a function <CODE>main</CODE> whichreturns type number <CODE>1</CODE>. The <CODE>_main</CODE> specified for the valueis a reference to an assembler label which is used to fill in the startaddress of the function.</P><PRE>.stabs "main:F1",36,0,0,_main # 36 is N_FUN</PRE><P>The stab representing a procedure is located immediately following thecode of the procedure. This stab is in turn directly followed by agroup of other stabs describing elements of the procedure. These otherstabs describe the procedure's parameters, its block local variables, andits block structure.</P><P>If functions can appear in different sections, then the debugger may notbe able to find the end of a function. Recent versions of GCC will markthe end of a function with an <CODE>N_FUN</CODE> symbol with an empty stringfor the name. The value is the address of the end of the currentfunction. Without such a symbol, there is no indication of the addressof the end of a function, and you must assume that it ended at thestarting address of the next function or at the end of the text sectionfor the program.</P><H2><A NAME="SEC13" HREF="stabs_toc.html#TOC13">Nested Procedures</A></H2><P>For any of the symbol descriptors representing procedures, after thesymbol descriptor and the type information is optionally a scopespecifier. This consists of a comma, the name of the procedure, anothercomma, and the name of the enclosing procedure. The first name is localto the scope specified, and seems to be redundant with the name of thesymbol (before the <SAMP>`:'</SAMP>). This feature is used by GCC, andpresumably Pascal, Modula-2, etc., compilers, for nested functions.</P><P>If procedures are nested more than one level deep, only the immediatelycontaining scope is specified. For example, this code:</P><PRE>int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -