📄 stabs.html
字号:
type declarations using <CODE>C_DECL</CODE>) can also be between the<CODE>N_BCOMM</CODE> and the <CODE>N_ECOMM</CODE>.</P><H2><A NAME="SEC22" HREF="stabs_toc.html#TOC22">Static Variables</A></H2><P>Initialized static variables are represented by the <SAMP>`S'</SAMP> and<SAMP>`V'</SAMP> symbol descriptors. <SAMP>`S'</SAMP> means file scope static, and<SAMP>`V'</SAMP> means procedure scope static. One exception: in XCOFF, IBM'sxlc compiler always uses <SAMP>`V'</SAMP>, and whether it is file scope or notis distinguished by whether the stab is located within a function.</P><P><A NAME="IDX37"></A><A NAME="IDX38"></A><A NAME="IDX39"></A><A NAME="IDX40"></A>In a.out files, <CODE>N_STSYM</CODE> means the data section, <CODE>N_FUN</CODE>means the text section, and <CODE>N_LCSYM</CODE> means the bss section. Forthose systems with a read-only data section separate from the textsection (Solaris), <CODE>N_ROSYM</CODE> means the read-only data section.</P><P>For example, the source lines:</P><PRE>static const int var_const = 5;static int var_init = 2;static int var_noinit;</PRE><P>yield the following stabs:</P><PRE>.stabs "var_const:S1",36,0,0,_var_const # 36 is N_FUN....stabs "var_init:S1",38,0,0,_var_init # 38 is N_STSYM....stabs "var_noinit:S1",40,0,0,_var_noinit # 40 is N_LCSYM</PRE><P><A NAME="IDX41"></A><A NAME="IDX42"></A><A NAME="IDX43"></A>In XCOFF files, the stab type need not indicate the section;<CODE>C_STSYM</CODE> can be used for all statics. Also, each static variableis enclosed in a static block. A <CODE>C_BSTAT</CODE> (emitted with a<SAMP>`.bs'</SAMP> assembler directive) symbol begins the static block; itsvalue is the symbol number of the csect symbol whose value is theaddress of the static block, its section is the section of the variablesin that static block, and its name is <SAMP>`.bs'</SAMP>. A <CODE>C_ESTAT</CODE>(emitted with a <SAMP>`.es'</SAMP> assembler directive) symbol ends the staticblock; its name is <SAMP>`.es'</SAMP> and its value and section are ignored.</P><P>In ECOFF files, the storage class is used to specify the section, so thestab type need not indicate the section.</P><P>In ELF files, for the SunPRO compiler version 2.0.1, symbol descriptor<SAMP>`S'</SAMP> means that the address is absolute (the linker relocates it)and symbol descriptor <SAMP>`V'</SAMP> means that the address is relative to thestart of the relevant section for that compilation unit. SunPRO hasplans to have the linker stop relocating stabs; I suspect that their thedebugger 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 a the value of a symboldescriptor <SAMP>`S'</SAMP> symbol be an offset relative to the start of thefile, just like everything else, but that introduces obviouscompatibility problems. For more information on linker stab relocation,See section <A HREF="stabs.html#SEC89">Having the Linker Relocate Stabs in ELF</A>.</P><H2><A NAME="SEC23" HREF="stabs_toc.html#TOC23">Fortran Based Variables</A></H2><P>Fortran (at least, the Sun and SGI dialects of FORTRAN-77) has a featurewhich allows allocating arrays with <CODE>malloc</CODE>, but which avoidsblurring the line between arrays and pointers the way that C does. Instabs such a variable uses the <SAMP>`b'</SAMP> symbol descriptor.</P><P>For example, the Fortran declarations</P><PRE>real foo, foo10(10), foo10_5(10,5)pointer (foop, foo)pointer (foo10p, foo10)pointer (foo105p, foo10_5)</PRE><P>produce the stabs</P><PRE>foo:b6foo10:bar3;1;10;6foo10_5:bar3;1;5;ar3;1;10;6</PRE><P>In this example, <CODE>real</CODE> is type 6 and type 3 is an integral typewhich is the type of the subscripts of the array (probably<CODE>integer</CODE>).</P><P>The <SAMP>`b'</SAMP> symbol descriptor is like <SAMP>`V'</SAMP> in that it denotes astatically allocated symbol whose scope is local to a function; seeSee section <A HREF="stabs.html#SEC22">Static Variables</A>. The value of the symbol, instead of being the addressof the variable itself, is the address of a pointer to that variable.So in the above example, the value of the <CODE>foo</CODE> stab is the addressof a pointer to a real, the value of the <CODE>foo10</CODE> stab is theaddress of a pointer to a 10-element array of reals, and the value ofthe <CODE>foo10_5</CODE> stab is the address of a pointer to a 5-element arrayof 10-element arrays of reals.</P><H2><A NAME="SEC24" HREF="stabs_toc.html#TOC24">Parameters</A></H2><P>Formal parameters to a function are represented by a stab (or sometimestwo; see below) for each parameter. The stabs are in the order in whichthe debugger should print the parameters (i.e., the order in which theparameters are declared in the source file). The exact form of the stabdepends on how the parameter is being passed.</P><P><A NAME="IDX44"></A><A NAME="IDX45"></A>Parameters passed on the stack use the symbol descriptor <SAMP>`p'</SAMP> andthe <CODE>N_PSYM</CODE> symbol type (or <CODE>C_PSYM</CODE> for XCOFF). The valueof 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 anoffset from the frame pointer.</P><P>As a simple example, the code:</P><PRE>main (argc, argv) int argc; char **argv;</PRE><P>produces the stabs:</P><PRE>.stabs "main:F1",36,0,0,_main # 36 is N_FUN.stabs "argc:p1",160,0,0,68 # 160 is N_PSYM.stabs "argv:p20=*21=*2",160,0,0,72</PRE><P>The type definition of <CODE>argv</CODE> is interesting because it containsseveral type definitions. Type 21 is pointer to type 2 (char) and<CODE>argv</CODE> (type 20) is pointer to type 21.</P><P>The following symbol descriptors are also said to go with <CODE>N_PSYM</CODE>.The value of the symbol is said to be an offset from the argumentpointer (I'm not sure whether this is true or not).</P><PRE>pP (<<??>>)pF Fortran function parameterX (function result variable)</PRE><H3><A NAME="SEC25" HREF="stabs_toc.html#TOC25">Passing Parameters in Registers</A></H3><P>If the parameter is passed in a register, then traditionally there aretwo symbols for each argument:</P><PRE>.stabs "arg:p1" . . . ; N_PSYM.stabs "arg:r1" . . . ; N_RSYM</PRE><P>Debuggers use the second one to find the value, and the first one toknow that it is an argument.</P><P><A NAME="IDX46"></A><A NAME="IDX47"></A>Because that approach is kind of ugly, some compilers use symboldescriptor <SAMP>`P'</SAMP> or <SAMP>`R'</SAMP> to indicate an argument which is in aregister. Symbol type <CODE>C_RPSYM</CODE> is used in XCOFF and <CODE>N_RSYM</CODE>is used otherwise. The symbol's value is the register number. <SAMP>`P'</SAMP>and <SAMP>`R'</SAMP> mean the same thing; the difference is that <SAMP>`P'</SAMP> is aGNU invention and <SAMP>`R'</SAMP> is an IBM (XCOFF) invention. As of version4.9, GDB should handle either one.</P><P>There is at least one case where GCC uses a <SAMP>`p'</SAMP> and <SAMP>`r'</SAMP> pairrather than <SAMP>`P'</SAMP>; this is where the argument is passed in theargument list and then loaded into a register.</P><P>According to the AIX documentation, symbol descriptor <SAMP>`D'</SAMP> is for aparameter passed in a floating point register. This seemsunnecessary--why not just use <SAMP>`R'</SAMP> with a register number whichindicates that it's a floating point register? I haven't verifiedwhether the system actually does what the documentation indicates.</P><P>On the sparc and hppa, for a <SAMP>`P'</SAMP> symbol whose type is a structureor union, the register contains the address of the structure. On thesparc, this is also true of a <SAMP>`p'</SAMP> and <SAMP>`r'</SAMP> pair (using Sun<CODE>cc</CODE>) or a <SAMP>`p'</SAMP> symbol. However, if a (small) structure isreally in a register, <SAMP>`r'</SAMP> is used. And, to top it all off, on thehppa it might be a structure which was passed on the stack and loadedinto a register and for which there is a <SAMP>`p'</SAMP> and <SAMP>`r'</SAMP> pair! Ibelieve that symbol descriptor <SAMP>`i'</SAMP> is supposed to deal with thiscase (it is said to mean "value parameter by reference, indirectaccess"; I don't know the source for this information), but I don't knowdetails 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 withdifferently than parameters passed by reference (see section <A HREF="stabs.html#SEC27">Passing Parameters by Reference</A>).</P><H3><A NAME="SEC26" HREF="stabs_toc.html#TOC26">Storing Parameters as Local Variables</A></H3><P>There is a case similar to an argument in a register, which is anargument that is actually stored as a local variable. Sometimes thishappens when the argument was passed in a register and then the compilerstores it as a local variable. If possible, the compiler should claimthat it's in a register, but this isn't always done.</P><P>If a parameter is passed as one type and converted to a smaller type bythe prologue (for example, the parameter is declared as a <CODE>float</CODE>,but the calling conventions specify that it is passed as a<CODE>double</CODE>), then GCC2 (sometimes) uses a pair of symbols. The firstsymbol uses symbol descriptor <SAMP>`p'</SAMP> and the type which is passed.The second symbol has the type and location which the parameter actuallyhas after the prologue. For example, suppose the following C codeappears with no prototypes involved:</P><PRE>voidsubr (f) float f;{</PRE><P>if <CODE>f</CODE> is passed as a double at stack offset 8, and the prologueconverts it to a float in register number 0, then the stabs look like:</P><PRE>.stabs "f:p13",160,0,3,8 # 160 is <CODE>N_PSYM</CODE>, here 13 is <CODE>double</CODE>.stabs "f:r12",64,0,3,0 # 64 is <CODE>N_RSYM</CODE>, here 12 is <CODE>float</CODE></PRE><P>In both stabs 3 is the line number where <CODE>f</CODE> is declared(see section <A HREF="stabs.html#SEC11">Line Numbers</A>).</P><P><A NAME="IDX48"></A>GCC, at least on the 960, has another solution to the same problem. Ituses a single <SAMP>`p'</SAMP> symbol descriptor for an argument which is storedas a local variable but uses <CODE>N_LSYM</CODE> instead of <CODE>N_PSYM</CODE>. Inthis case, the value of the symbol is an offset relative to the localvariables for that function, not relative to the arguments; on somemachines those are the same thing, but not on all.</P><P>On the VAX or on other machines in which the calling convention includesthe number of words of arguments actually passed, the debugger (GDB atleast) uses the parameter symbols to keep track of whether it needs toprint nameless arguments in addition to the formal parameters which ithas printed because each one has a stab. For example, in </P><PRE>extern int fprintf (FILE *stream, char *format, ...);...fprintf (stdout, "%d\n", x);</PRE><P>there are stabs for <CODE>stream</CODE> and <CODE>format</CODE>. On most machines,the debugger can only print those two arguments (because it has no wayof knowing that additional arguments were passed), but on the VAX orother machines with a calling convention which indicates the number ofwords of arguments, the debugger can print all three arguments. To doso, the parameter symbol (symbol descriptor <SAMP>`p'</SAMP>) (not necessarily<SAMP>`r'</SAMP> or symbol descriptor omitted symbols) needs to contain theactual type as passed (for example, <CODE>double</CODE> not <CODE>float</CODE> if itis passed as a double and converted to a float).</P><H3><A NAME="SEC27" HREF="stabs_toc.html#TOC27">Passing Parameters by Reference</A></H3><P>If the parameter is passed by reference (e.g., Pascal <CODE>VAR</CODE>parameters), then the symbol descriptor is <SAMP>`v'</SAMP> if it is in theargument list, or <SAMP>`a'</SAMP> if it in a register. Other than the factthat these contain the address of the parameter rather than theparameter itself, they are identical to <SAMP>`p'</SAMP> and <SAMP>`R'</SAMP>,respectively. I believe <SAMP>`a'</SAMP> is an AIX invention; <SAMP>`v'</SAMP> issupported by all stabs-using systems as far as I know.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -