📄 stabs.texinfo
字号:
describe structure types. However, once the class is defined, C stabswith no modifications can be used to describe class instances. Thefollowing source:@examplemain () @{ baseA AbaseA;@}@end example@noindentyields the following stab describing the class instance. It looks nodifferent 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 defintionThe class definition shown above declares Ameth. The C++ source belowdefines Ameth:@exampleint baseA::Ameth(int in, char other) @{ return in;@};@end exampleThis method definition yields three stabs following the code of themethod. One stab describes the method itself and following twodescribe its parameters. Although there is only one formal argumentall methods have an implicit argument which is the `this' pointer.The `this' pointer is a pointer to the object on which the method wascalled. Note that the method name is mangled to encode the class nameand argument types. << Name mangling is not described by thisdocument - Is there already such a doc? >>@example.stabs "name:symbol_desriptor(global function)return_type(int)", N_FUN, NIL, NIL, code_addr_of_method_start .stabs "Ameth__5baseAic:F1",36,0,0,_Ameth__5baseAic@end exampleHere is the stab for the `this' pointer implicit argument. The nameof the `this' pointer is always $t. Type 19, the `this' pointer isdefined as a pointer to type 20, baseA, but a stab defining baseA hasnot yet been emited. Since the compiler knows it will be emitedshortly, here it just outputs a cross reference to the undefinedsymbol, by prefixing the symbol name with xs.@example.stabs "name:sym_desc(register param)type_def(19)= type_desc(ptr to)type_ref(baseA)= type_desc(cross-reference to)baseA:",N_RSYM,NIL,NIL,register_number .stabs "$t:P19=*20=xsbaseA:",64,0,0,8@end exampleThe stab for the explicit integer argument looks just like a parameterto a C function. The last field of the stab is the offset from theargument pointer, which in most systems is the same as the framepointer.@example.stabs "name:sym_desc(value parameter)type_ref(int)", N_PSYM,NIL,NIL,offset_from_arg_ptr .stabs "in:p1",160,0,0,72@end example<< The examples that follow are based on A1.C >>@node Protections@section ProtectionsIn the simple class definition shown above all member data andfunctions were publicly accessable. The example that followscontrasts public, protected and privately accessable fields and showshow these protections are encoded in C++ stabs.Protections for class member data are signified by two charactersembeded in the stab defining the class type. These characters arelocated after the name: part of the string. /0 means private, /1means protected, and /2 means public. If these characters are omitedthis means that the member is public. The following C++ source:@exampleclass all_data @{private: int priv_dat;protected: char prot_dat;public: float pub_dat;@};@end example@noindentgenerates the following stab to describe the class type all_data.@display.stabs "class_name:sym_desc(type)type_def(19)=type_desc(struct)struct_bytes data_name:/protection(private)type_ref(int),bit_offset,num_bits; data_name:/protection(protected)type_ref(char),bit_offset,num_bits; data_name:(/num omited, private)type_ref(float),bit_offset,num_bits;;" N_LSYM,NIL,NIL,NIL@end display@smallexample.stabs "all_data:t19=s12 priv_dat:/01,0,32;prot_dat:/12,32,8;pub_dat:12,64,32;;",128,0,0,0@end smallexampleProtections for member functions are signified by one digit embeded inthe field part of the stab describing the method. The digit is 0 ifprivate, 1 if protected and 2 if public. Consider the C++ classdefinition below:@exampleclass 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 exampleIt generates the following stab. The digit in question is to the leftof an `A' in each case. Notice also that in this case two symboldescriptors apply to the class name struct tag and struct type.@display.stabs "class_name:sym_desc(struct tag&type)type_def(21)= sym_desc(struct)struct_bytes(1) meth_name::type_def(22)=sym_desc(method)returning(int); :args(int);protection(private)modifier(normal)virtual(no); meth_name::type_def(23)=sym_desc(method)returning(char); :args(char);protection(protected)modifier(normal)virual(no); meth_name::type_def(24)=sym_desc(method)returning(float); :args(float);protection(public)modifier(normal)virtual(no);;", N_LSYM,NIL,NIL,NIL@end display @smallexample.stabs "all_methods:Tt21=s1priv_meth::22=##1;:i;0A.;protMeth::23=##2;:c;1A.; pubMeth::24=##12;:f;2A.;;",128,0,0,0@end smallexample@node Method Modifiers@section Method Modifiers (const, volatile, const volatile)<< based on a6.C >>In the class example described above all the methods have the normalmodifier. This method modifier information is located just after theprotection information for the method. This field has four possiblecharacter values. Normal methods use A, const methods use B, volatilemethods use C, and const volatile methods use D. Consider the classdefinition below:@exampleclass 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 exampleThis class is described by the following stab:@display.stabs "class(A):sym_desc(struct)type_def(20)=type_desc(struct)struct_bytes(1) meth_name(ConstMeth)::type_def(21)sym_desc(method) returning(int);:arg(int);protection(public)modifier(const)virtual(no); meth_name(VolatileMeth)::type_def(22)=sym_desc(method) returning(char);:arg(char);protection(public)modifier(volatile)virt(no) meth_name(ConstVolMeth)::type_def(23)=sym_desc(method) returning(float);:arg(float);protection(public)modifer(const volatile) virtual(no);;", @dots{}@end display @example.stabs "A:T20=s1ConstMeth::21=##1;:i;2B.;VolatileMeth::22=##2;:c;2C.; ConstVolMeth::23=##12;:f;2D.;;",128,0,0,0@end example@node Virtual Methods@section Virtual Methods<< The following examples are based on a4.C >> The presence of virtual methods in a class definition adds additionaldata to the class description. The extra data is appended to thedescription of the virtual method and to the end of the classdescription. Consider the class definition below:@exampleclass 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 newtype (20) which is an 8 byte structure. The first field of the classstruct is Adat, an integer, starting at structure offset 0 andoccupying 32 bits. The second field in the class struct is not explicitly defined by theC++ class definition but is implied by the fact that the classcontains a virtual method. This field is the vtable pointer. Thename of the vtable pointer field starts with $vf and continues with atype reference to the class it is part of. In this example the typereference for class A is 20 so the name of its vtable pointer field is$vf20, followed by the usual colon.Next there is a type definition for the vtable pointer type (21).This is in turn defined as a pointer to another new type (22). Type 22 is the vtable itself, which is defined as an array, indexed byintegers, with a high bound of 1, and elements of type 17. Type 17was the vtable record type defined by the boilerplate C++ typedefinitions, as shown earlier. The bit offset of the vtable pointer field is 32. The number of bitsin the field are not specified when the field is a vtable pointer. Next is the method definition for the virtual member function A_virt.Its description starts out using the same format as the non-virtualmember functions described above, except instead of a dot after the`A' there is an asterisk, indicating that the function is virtual.Since is is virtual some addition information is appended to the endof the method description. The first number represents the vtable index of the method. This is a32 bit unsigned number with the high bit set, followed by asemi-colon.The second number is a type reference to the first base class in theinheritence hierarchy defining the virtual member function. In thiscase the class stab describes a base class so the virtual function isnot overriding any other definition of the method. Therefore thereference is to the type number of the class that the stab isdescribing (20). This is followed by three semi-colons. One marks the end of thecurrent sub-section, one marks the end of the method field, and thethird marks the end of the struct definition.For classes containing virtual functions the very last section of thestring part of the stab holds a type reference to the first baseclass. This is preceeded by `~%' and followed by a final semi-colon.@display.stabs "class_name(A):type_def(20)=sym_desc(struct)struct_bytes(8) field_name(Adat):type_ref(int),bit_offset(0),field_bits(32); field_name(A virt func ptr):type_def(21)=type_desc(ptr to)type_def(22)= sym_desc(array)index_type_ref(int);NIL;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@example.stabs "A:t20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0@end example@node Inheritence@section InheritenceStabs describing C++ derived classes include additional sections thatdescribe the inheritence hierarchy of the class. A derived class stabalso encodes the number of base classes. For each base class it tellsif the base class is virtual or not, and if the inheritence is privateor public. It also gives the offset into the object of the portion ofthe object corresponding to each base class. This additional information is embeded in the class stab following thenumber of bytes in the struct. First the number of base classesappears bracketed by an exclamation point and a comma. Then for each base type there repeats a series: two digits, a number,a comma, another number, and a semi-colon. The first of the two digits is 1 if the base class is virtual and 0 ifnot. The second digit is 2 if the derivation is public and 0 if not.The number following the first two digits is the offset from the startof 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 basetype. Finally a semi-colon ends the series, which repeats for eachbase class.The source below defines three base classes A, B, and C and thederived class D.@exampleclass 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 exampleClass stabs similar to the ones described earlier are generated foreach 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.@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 smallexampleIn the stab describing derived class D below, the information aboutthe derivation of this class is encoded as follows.@display.stabs "derived_class_name:symbol_descriptors(struct tag&type)= type_descriptor(struct)struct_bytes(32)!num_bases(3), base_virtual(no)inheritence_public(no)base_offset(0), base_class_type_ref(A); base_virtual(yes)inheritence_public(no)base_offset(NIL), base_class_type_ref(B); base_virtual(no)inheritence_public(yes)base_offset(64), base_class_type_ref(C); @dots{}@end display @c FIXME! fake linebreaks.@smallexample.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat: 1,160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt: :32:i;2A*-2147483647;25;;C_virt::32:i;2A*-2147483647; 28;;D_virt::32:i;2A*-2147483646;31;;;~%20;",128,0,0,0@end smallexample@node Virtual Base Classes@section Virtual Base ClassesA derived class object consists of a concatination in memory of thedata areas defined by each base class, starting with the leftmost andending with the rightmost in the list of base classes. The exceptionto this rule is for virtual inheritence. In the example above, classD inherits virtually from base class B. This means that an instanceof a D object will not contain it's own B part but merely a pointer toa B part, known as a virtual base pointer.In a derived class stab, the base offset part of the derivationinformation, described above, shows how the base class parts areordered. The base offset for a virtual base class is always given as0. Notice that the base offset for B is given as 0 even though B isnot the first base class. The first base class A starts at offset 0.The field information part of the stab for class D describes the fieldwhich is the pointer to the virtual base class B. The vbase pointername is $vb followed by a type reference to the virtual base class.Since the type id for B in this example is 25, the vbase pointer nameis $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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -