X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libdw%2Fdwarf_getlocation_attr.c;h=8b6a4afda3d40e59afd8d3222f304624c3f95326;hb=82c3b58b54026d061a4d81ad95f3023d5d883ab2;hp=cb290456be55cf237ad2c2867bb75b8809add237;hpb=a286dd013ef8d46edf013efc0908822a59d8ac81;p=platform%2Fupstream%2Felfutils.git diff --git a/libdw/dwarf_getlocation_attr.c b/libdw/dwarf_getlocation_attr.c index cb29045..8b6a4af 100644 --- a/libdw/dwarf_getlocation_attr.c +++ b/libdw/dwarf_getlocation_attr.c @@ -1,5 +1,5 @@ /* Return DWARF attribute associated with a location expression op. - Copyright (C) 2013 Red Hat, Inc. + Copyright (C) 2013, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -33,36 +33,52 @@ #include #include +static Dwarf_CU * +attr_form_cu (Dwarf_Attribute *attr) +{ + /* If the attribute has block/expr form the data comes from the + .debug_info from the same cu as the attr. Otherwise it comes from + the .debug_loc data section. */ + switch (attr->form) + { + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + case DW_FORM_block: + case DW_FORM_exprloc: + return attr->cu; + default: + return attr->cu->dbg->fake_loc_cu; + } +} int -dwarf_getlocation_attr (attr, op, result) - Dwarf_Attribute *attr; - const Dwarf_Op *op; - Dwarf_Attribute *result; +dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribute *result) { if (attr == NULL) return -1; - result->cu = attr->cu; - switch (op->atom) { case DW_OP_implicit_value: result->code = DW_AT_const_value; result->form = DW_FORM_block; result->valp = (unsigned char *) (uintptr_t) op->number2; + result->cu = attr_form_cu (attr); break; case DW_OP_GNU_entry_value: result->code = DW_AT_location; result->form = DW_FORM_exprloc; result->valp = (unsigned char *) (uintptr_t) op->number2; + result->cu = attr_form_cu (attr); break; case DW_OP_GNU_const_type: result->code = DW_AT_const_value; result->form = DW_FORM_block1; result->valp = (unsigned char *) (uintptr_t) op->number2; + result->cu = attr_form_cu (attr); break; case DW_OP_call2: @@ -74,7 +90,7 @@ dwarf_getlocation_attr (attr, op, result) return -1; if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL) { - __libdw_empty_loc_attr (result, attr->cu); + __libdw_empty_loc_attr (result); return 0; } } @@ -88,7 +104,7 @@ dwarf_getlocation_attr (attr, op, result) if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL && INTUSE(dwarf_attr) (&die, DW_AT_const_value, result) == NULL) { - __libdw_empty_loc_attr (result, attr->cu); + __libdw_empty_loc_attr (result); return 0; } }