From 7c1bdff7ebe416071b2a498db50c48f3fdb74879 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Thu, 27 Mar 2014 10:58:54 +0100 Subject: [PATCH] [mc] Really fix DW_AT_high_pc for DWARF4 In DWARF4, DW_AT_high_pc can be an offset from DW_AT_low_pc instead of a relocatable address. MC works with DWARF4! --- src/mc/mc_dwarf.c | 53 ++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/mc/mc_dwarf.c b/src/mc/mc_dwarf.c index 253350064e..6b51647d8f 100644 --- a/src/mc/mc_dwarf.c +++ b/src/mc/mc_dwarf.c @@ -811,29 +811,40 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die* die, Dwa // Variables are filled in the (recursive) call of MC_dwarf_handle_children: frame->variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp); - frame->low_pc = ((char*) base) + MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc); - // DW_AT_high_pc: - { + // TODO, support DW_AT_ranges + uint64_t low_pc = MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc); + frame->low_pc = low_pc ? ((char*) base) + low_pc : 0; + if(low_pc) { + // DW_AT_high_pc: Dwarf_Attribute attr; - if(dwarf_attr_integrate(die, DW_AT_high_pc, &attr)) { - uint64_t high_pc; - Dwarf_Addr value; - if (dwarf_formaddr(&attr, &value) == 0) - high_pc = (uint64_t) value; - else - high_pc = 0; - - int form = dwarf_whatform(&attr); - int klass = MC_dwarf_form_get_class(form); - if (klass == MC_DW_CLASS_CONSTANT) - frame->high_pc = (void*) ((Dwarf_Off)frame->low_pc + high_pc); - else if(klass == MC_DW_CLASS_ADDRESS) - frame->high_pc = ((char*) base) + high_pc; - else - xbt_die("Unexpected class for DW_AT_high_pc"); - } else { - frame->high_pc = 0; + if(!dwarf_attr_integrate(die, DW_AT_high_pc, &attr)) { + xbt_die("Missing DW_AT_high_pc matching with DW_AT_low_pc"); + } + + Dwarf_Sword offset; + Dwarf_Addr high_pc; + + switch(MC_dwarf_form_get_class(dwarf_whatform(&attr))) { + + // DW_AT_high_pc if an offset from the low_pc: + case MC_DW_CLASS_CONSTANT: + + if (dwarf_formsdata(&attr, &offset) !=0) + xbt_die("Could not read constant"); + frame->high_pc = (void*) ((Dwarf_Off)frame->low_pc + offset); + break; + + // DW_AT_high_pc is a relocatable address: + case MC_DW_CLASS_ADDRESS: + if (dwarf_formaddr(&attr, &high_pc) != 0) + xbt_die("Could not read address"); + frame->high_pc = ((char*) base) + high_pc; + break; + + default: + xbt_die("Unexpected class for DW_AT_high_pc"); + } } -- 2.20.1