along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-
-/* Standard C++ includes. */
-#include <algorithm>
-#include <unordered_set>
-#include <vector>
-
-/* Local non-gdb includes. */
-#include "ax-gdb.h"
+#include "ui-out.h"
+#include "value.h"
+#include "frame.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "inferior.h"
#include "ax.h"
+#include "ax-gdb.h"
+#include "regcache.h"
+#include "objfiles.h"
#include "block.h"
-#include "common/byte-vector.h"
-#include "common/selftest.h"
-#include "common/underlying.h"
-#include "compile/compile.h"
+#include "gdbcmd.h"
#include "complaints.h"
-#include "dwarf2-frame.h"
#include "dwarf2.h"
#include "dwarf2expr.h"
#include "dwarf2loc.h"
-#include "frame.h"
-#include "gdbcmd.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "objfiles.h"
-#include "regcache.h"
-#include "target.h"
-#include "ui-out.h"
-#include "value.h"
+#include "dwarf2read.h"
+#include "dwarf2-frame.h"
+#include "compile/compile.h"
+#include "gdbsupport/selftest.h"
+#include <algorithm>
+#include <vector>
+#include <unordered_set>
+#include "gdbsupport/underlying.h"
+#include "gdbsupport/byte-vector.h"
extern int dwarf_always_disassemble;
}
/* Callback function for dwarf2_evaluate_loc_desc.
- Fetch the address indexed by DW_OP_GNU_addr_index. */
+ Fetch the address indexed by DW_OP_addrx or DW_OP_GNU_addr_index. */
CORE_ADDR get_addr_index (unsigned int index) override
{
{
struct call_site_chain *retval = NULL;
- TRY
+ try
{
retval = call_site_find_chain_1 (gdbarch, caller_pc, callee_pc);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
if (e.error == NO_ENTRY_VALUE_ERROR)
{
return NULL;
}
else
- throw_exception (e);
+ throw;
}
- END_CATCH
return retval;
}
ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu);
ctx.offset = dwarf2_per_cu_text_offset (per_cu);
- TRY
+ try
{
ctx.eval (data, size);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error == NOT_AVAILABLE_ERROR)
{
return allocate_optimized_out_value (subobj_type);
}
else
- throw_exception (ex);
+ throw;
}
- END_CATCH
if (ctx.pieces.size () > 0)
{
ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
ctx.offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
- TRY
+ try
{
ctx.eval (dlbaton->data, dlbaton->size);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error == NOT_AVAILABLE_ERROR)
{
return 0;
}
else
- throw_exception (ex);
+ throw;
}
- END_CATCH
switch (ctx.location)
{
/* See dwarf2loc.h. */
-int
+bool
dwarf2_evaluate_property (const struct dynamic_prop *prop,
struct frame_info *frame,
struct property_addr_info *addr_stack,
CORE_ADDR *value)
{
if (prop == NULL)
- return 0;
+ return false;
if (frame == NULL && has_stack_frames ())
frame = get_selected_frame (NULL);
{
const struct dwarf2_property_baton *baton
= (const struct dwarf2_property_baton *) prop->data.baton;
+ gdb_assert (baton->property_type != NULL);
if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame,
addr_stack ? addr_stack->addr : 0,
value))
{
- if (baton->referenced_type)
+ if (baton->locexpr.is_reference)
{
- struct value *val = value_at (baton->referenced_type, *value);
-
+ struct value *val = value_at (baton->property_type, *value);
*value = value_as_address (val);
}
- return 1;
+ else
+ {
+ gdb_assert (baton->property_type != NULL);
+
+ struct type *type = check_typedef (baton->property_type);
+ if (TYPE_LENGTH (type) < sizeof (CORE_ADDR)
+ && !TYPE_UNSIGNED (type))
+ {
+ /* If we have a valid return candidate and it's value
+ is signed, we have to sign-extend the value because
+ CORE_ADDR on 64bit machine has 8 bytes but address
+ size of an 32bit application is bytes. */
+ const int addr_size
+ = (dwarf2_per_cu_addr_size (baton->locexpr.per_cu)
+ * TARGET_CHAR_BIT);
+ const CORE_ADDR neg_mask
+ = (~((CORE_ADDR) 0) << (addr_size - 1));
+
+ /* Check if signed bit is set and sign-extend values. */
+ if (*value & neg_mask)
+ *value |= neg_mask;
+ }
+ }
+ return true;
}
}
break;
data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
if (data != NULL)
{
- val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data,
+ val = dwarf2_evaluate_loc_desc (baton->property_type, frame, data,
size, baton->loclist.per_cu);
if (!value_optimized_out (val))
{
*value = value_as_address (val);
- return 1;
+ return true;
}
}
}
case PROP_CONST:
*value = prop->data.const_val;
- return 1;
+ return true;
case PROP_ADDR_OFFSET:
{
struct value *val;
for (pinfo = addr_stack; pinfo != NULL; pinfo = pinfo->next)
- if (pinfo->type == baton->referenced_type)
- break;
+ {
+ /* This approach lets us avoid checking the qualifiers. */
+ if (TYPE_MAIN_TYPE (pinfo->type)
+ == TYPE_MAIN_TYPE (baton->property_type))
+ break;
+ }
if (pinfo == NULL)
error (_("cannot find reference address for offset property"));
if (pinfo->valaddr != NULL)
val = value_at (baton->offset_info.type,
pinfo->addr + baton->offset_info.offset);
*value = value_as_address (val);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
/* See dwarf2loc.h. */
push_address (0, 0);
}
- /* DW_OP_GNU_addr_index doesn't require a frame. */
+ /* DW_OP_addrx and DW_OP_GNU_addr_index doesn't require a frame. */
CORE_ADDR get_addr_index (unsigned int index) override
{
fprintf_filtered (stream, " offset %s", phex_nz (ul, 4));
break;
+ case DW_OP_addrx:
case DW_OP_GNU_addr_index:
data = safe_read_uleb128 (data, end, &ul);
ul = dwarf2_read_addr_index (per_cu, ul);