+2013-12-09 Mark Wielaard <mjw@redhat.com>
+
+ * dwarf_getlocation.c (__libdw_intern_expression): Handle empty
+ location expressions.
+ * dwarf_getlocation_attr.c (dwarf_getlocation_attr): When no
+ location found, return empty location expression.
+ * dwarf_getlocation_implicit_pointer.c
+ (dwarf_getlocation_implicit_pointer): Likewise.
+ (__libdw_empty_loc_attr): New internal function.
+ * libdwP.h (__libdw_empty_loc_attr): Define.
+
2013-11-27 Mark Wielaard <mjw@redhat.com>
* libdw.map (ELFUTILS_0.158): Add dwfl_module_addrsym_elf and
bool cfap, bool valuep,
Dwarf_Op **llbuf, size_t *listlen, int sec_index)
{
+ /* Empty location expressions don't have any ops to intern. */
+ if (block->length == 0)
+ {
+ *listlen = 0;
+ return 0;
+ }
+
/* Check whether we already looked at this list. */
struct loc_s fake = { .addr = block->data };
struct loc_s **found = tfind (&fake, cache, loc_compare);
if (unlikely (n == 0))
{
/* This is not allowed.
-
- XXX Is it? */
+ It would mean an empty location expression, which we handled
+ already as a special case above. */
goto invalid;
}
return -1;
if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL)
{
- __libdw_seterrno (DWARF_E_INVALID_DWARF);
- return -1;
+ __libdw_empty_loc_attr (result, attr->cu);
+ return 0;
}
}
break;
if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL
&& INTUSE(dwarf_attr) (&die, DW_AT_const_value, result) == NULL)
{
- __libdw_seterrno (DWARF_E_INVALID_DWARF);
- return -1;
+ __libdw_empty_loc_attr (result, attr->cu);
+ return 0;
}
}
break;
#include <dwarf.h>
+static unsigned char empty_exprloc = 0;
+
+void
+internal_function
+__libdw_empty_loc_attr (Dwarf_Attribute *attr, struct Dwarf_CU *cu )
+{
+ attr->code = DW_AT_location;
+ attr->form = DW_FORM_exprloc;
+ attr->valp = &empty_exprloc;
+ attr->cu = cu;
+}
+
int
dwarf_getlocation_implicit_pointer (attr, op, result)
Dwarf_Attribute *attr;
if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL
&& INTUSE(dwarf_attr) (&die, DW_AT_const_value, result) == NULL)
{
- __libdw_seterrno (DWARF_E_INVALID_DWARF);
- return -1;
+ __libdw_empty_loc_attr (result, attr->cu);
+ return 0;
}
return 0;
internal_function;
#endif /* ENABLE_DWZ */
+/* Fills in the given attribute to point at an empty location expression. */
+void __libdw_empty_loc_attr (Dwarf_Attribute *attr, struct Dwarf_CU *cu)
+ internal_function;
+
/* Aliases to avoid PLTs. */
INTDECL (dwarf_aggregate_size)
+2013-12-09 Mark Wielaard <mjw@redhat.com>
+
+ * varlocs.c (print_expr): Update comment to explain empty location
+ associated with DW_OP_GNU_implicit_pointer.
+
2013-12-05 Jan Kratochvil <jan.kratochvil@redhat.com>
Fix test FAIL with -O2.
int locs = dwarf_getlocation_addr (&attrval, addr,
&exprval, &exprval_len, 1);
if (locs == 0)
- printf ("<no location>"); // XXX should that be flagged?
+ printf ("<no location>"); // This means "optimized out".
else if (locs == 1)
print_expr_block (&attrval, exprval, exprval_len, addr);
else