Re: [Core] [RFC] dwarf debug information: Handle Free Pascal virtual table indexes

Jonas Maebe
2010-05-13T17:51:59Z

On 13 May 2010, at 19:17, Tom Tromey wrote:

> The value of DW_AT_vtable_elem_location is a DWARF location expression.
> From the DWARF 4 (review) spec:
>
> An entry for a virtual function also has a DW_AT_vtable_elem_location
> attribute whose value contains a location description yielding the
> address of the slot for the function within the virtual function table
> for the enclosing class. The address of an object of the enclosing type
> is pushed onto the expression stack before the location description is
> evaluated.
>
> One thing that would be helpful is if you ran "readelf -w" (or some
> other DWARF dumper) on a program created by FPC that has this attribute,
> then posted the DIE in question.

I agree with you that from reading the DWARF spec it seems that we are generating an incomplete location. Here's a dwarfdump of what we generate (Mac OS X):

0x000000f1: TAG_subprogram [12] *
AT_name( "TEST" )
AT_prototyped( 0x01 )
AT_calling_convention( 0x41 )
AT_external( 0x01 )
AT_virtuality( DW_VIRTUALITY_virtual )
AT_vtable_elem_location( <0x2> 10 03 )
AT_low_pc( 0x00000050 )
AT_high_pc( 0x00000096 )

I based that on what I saw gcc 4.0 (and 4.2) generate under Mac OS X for a virtual C++ method:

0x00007d35: TAG_subprogram [115] *
AT_external( 0x01 )
AT_name( "eat" )
AT_decl_file( "/Volumes/Leopard/Data/dev/fpc/test/virtmeth.cpp" )
AT_decl_line( 7 )
AT_MIPS_linkage_name( "_ZN6Animal3eatEv" )
AT_virtuality( DW_VIRTUALITY_virtual )
AT_vtable_elem_location( <0x2> 10 00 )
AT_containing_type( {0x00007d0f} )
AT_declaration( 0x01 )
AT_sibling( {0x00007d55} )

In fact, it seem to be the same for g++ 4.1.2 under Linux/x86-64:

<2><5ce5>: Abbrev Number: 102 (DW_TAG_subprogram)
DW_AT_external : 1
DW_AT_name : eat
DW_AT_decl_file : 1
DW_AT_decl_line : 7
DW_AT_MIPS_linkage_name: _ZN6Animal3eatEv
DW_AT_virtuality : 1 (virtual)
DW_AT_vtable_elem_location: 2 byte block: 10 0 (DW_OP_constu: 0)
DW_AT_containing_type: <5c94>
DW_AT_declaration : 1

So I'm not sure what's going on here. The C++ code I used is below (some example I took from the web).

Jonas

#include <iostream>
using namespace std;

class Animal
{
public:
virtual void eat() { cout << "I eat like a generic Animal." << endl;
}
};

class Wolf : public Animal
{
public:
void eat() { cout << "I eat like a wolf!" << endl; }
};

class Fish : public Animal
{
public:
void eat() { cout << "I eat like a fish!" << endl; }
};

class OtherAnimal : public Animal
{
};

int main()
{
Animal* anAnimal[4];

anAnimal[0] = new Animal();
anAnimal[1] = new Wolf();
anAnimal[2] = new Fish();
anAnimal[3] = new OtherAnimal();

for (int i = 0; i < 4; i++) {
anAnimal[i]->eat();
delete anAnimal[i];
}

return 0;
}