Gabriel Corona [Thu, 6 Mar 2014 14:06:56 +0000 (15:06 +0100)]
[mc] Partial implementation of DWARF expression evaluator
In order to resolve complexe location expressions of (C++ object)
inheritance relationships, it is necessary to implement a real DWARF
expression stack machine.
Gabriel Corona [Thu, 6 Mar 2014 12:25:38 +0000 (13:25 +0100)]
[mc] Fix bug when trying to handle DW_OP_regN in MC_dwarf_resolve_location
MC_dwarf_resolve_location is supposed to return the *address* of a
given variable. However, the DW_OP_regN returned the value of the
register and not an address address of a variable with its content.
It should be possible to get such an addresse (the registers are saved
on the stack) but the feature does not seem to be implemented in
libunwind.
Gabriel Corona [Thu, 6 Mar 2014 12:07:19 +0000 (13:07 +0100)]
[mc] Support DWARF4 DW_FORM_sec_offset (found in libpthread_nonshared.a)
Add support to DWARF4 DW_FORM_sec_offset in order to handle DWARF4
libpthread_nonshared.a.
We do not yet handle DWARF3 and 4 but only DWARF2. It is not a big
problem as it is possible to ask GCC to generate DWARF2 with:
-gdwarf-2.
However, even with this option, some static/non-shared libraries might
be included such as libpthread_nonshared.a which might be compiled
with DWARF4 information. This happen in Debian testing (2014-03-06).
Dwarf_Attribute attr;
dwarf_attr_integrate(child, DW_AT_data_member_location, &attr);
- int form = dwarf_whatform(&attr);
+ int form = dwarf_whatform(&attr);
int klass = MC_dwarf_form_get_class(form);
switch (klass) {
case MC_DW_CLASS_EXPRLOC:
@@ -850,7 +850,8 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, D
variable->name = xbt_strdup(MC_dwarf_attr_string(die, DW_AT_name));
variable->type_origin = MC_dwarf_at_type(die);
- int klass = MC_dwarf_form_get_class(dwarf_whatform(&attr_location));
+ int form = dwarf_whatform(&attr_location);
+ int klass = form == DW_FORM_sec_offset ? MC_DW_CLASS_CONSTANT : MC_dwarf_form_get_class(form);
switch (klass) {
case MC_DW_CLASS_EXPRLOC:
case MC_DW_CLASS_BLOCK:
@@ -882,8 +883,8 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, D
variable->location = MC_dwarf_get_location_list(info, die, &attr_location);
break;
default:
- xbt_die("Unexpected calss 0x%x (%i) list for location in <%p>%s",
- klass, klass, (void*) variable->dwarf_offset, variable->name);
+ xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%p>%s",
+ form, form, klass, klass, (void*) variable->dwarf_offset, variable->name);
}
Gabriel Corona [Mon, 24 Feb 2014 12:54:45 +0000 (13:54 +0100)]
[mc] Add MC_dwarf_tag_classify()
Add MC_dwarf_tag_classify(tag) which regroupe different similar
DW_TAG_* items classes. This is in preparation for upcoming
modifications of the DIE handling code.
Gabriel Corona [Mon, 24 Feb 2014 12:22:10 +0000 (13:22 +0100)]
[mc] Do not try to handle scopes inside a subprogram
The variables of a subprogram scopes were merged in the information
about subprogram without any information on its range of validity (for
which range of IP the variable is valid).
As this handling of scopes was broken, this commit ignore the scopes within a
subprogram.
We need to:
* either add frame_t as child of frame_t to represent scope;
* or attach validity information on each variables
This one is needed anyway in order to handle DW_AT_start_scope.
* or both.
Use frame_t for DW_TAG_inlined_subprogram and validity range for
real scope.
Gabriel Corona [Tue, 18 Feb 2014 10:38:14 +0000 (11:38 +0100)]
[mc] Do not waste time calling libunwind get_proc_name in the hot spots
In typical executions, nearly 50% of the time was spent in libunwind
get_proc_name.
The algorithm to find the function for a given IP (instruction
pointer) was:
(proc_name, offset) = get_proc_name(ip) // Slow!
dwarf_ip = ip - offset
function = functions_by_name[proc_name]
We added a structure mapping IP ranges to functions and the algorithm
is now:
function = functions_by_ip[ip]
Instead of relying on libunwind, we use the DWARF information to find
the corresponding DWARF TAG_subprogram DIEs directly.
The secution time on some MPICH tests is nearly halved.
Notes:
* It was necessary to disable the support for inlined_subprograms
which was broken anyway: the inlined_subprogram entries should be
stored as children of their parent subprogram (as a block). We need
to add support for scope blocks inside a suprogram to handle this
correctly.
* Currently the translation between process virtual addresses and
DWARF virtual addresses is handled in many different places. We
should change this to process it only when parsing the DWARF DIEs
and be done with it.