struct gdbarch *gdbarch = get_objfile_arch (objfile);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
+ int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
/* Adjust base_address for relocatable objects. */
CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
if (buf_end - loc_ptr < 2 * addr_size)
error (_("find_location_expression: Corrupted DWARF expression."));
- low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+ if (signed_addr_p)
+ low = extract_signed_integer (loc_ptr, addr_size, byte_order);
+ else
+ low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+ loc_ptr += addr_size;
+
+ if (signed_addr_p)
+ high = extract_signed_integer (loc_ptr, addr_size, byte_order);
+ else
+ high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
loc_ptr += addr_size;
/* A base-address-selection entry. */
- if (low == base_mask)
+ if ((low & base_mask) == base_mask)
{
- base_address = dwarf2_read_address (gdbarch,
- loc_ptr, buf_end, addr_size);
- loc_ptr += addr_size;
+ base_address = high + base_offset;
continue;
}
- high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
- loc_ptr += addr_size;
-
/* An end-of-list entry. */
if (low == 0 && high == 0)
return NULL;
contents = value_contents_raw (v);
bits_to_skip = 8 * value_offset (v);
- type_len = 8 * TYPE_LENGTH (value_type (v));
+ if (value_bitsize (v))
+ {
+ bits_to_skip += value_bitpos (v);
+ type_len = value_bitsize (v);
+ }
+ else
+ type_len = 8 * TYPE_LENGTH (value_type (v));
for (i = 0; i < c->n_pieces && offset < type_len; i++)
{
case DWARF_VALUE_REGISTER:
{
struct gdbarch *arch = get_frame_arch (frame);
- int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch,
- p->v.expr.value);
+ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
int reg_offset = source_offset;
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
else
{
error (_("Unable to access DWARF register number %s"),
- paddress (arch, p->v.expr.value));
+ paddress (arch, p->v.value));
}
}
break;
case DWARF_VALUE_MEMORY:
- if (p->v.expr.in_stack_memory)
- read_stack (p->v.expr.value + source_offset, buffer, this_size);
+ if (p->v.mem.in_stack_memory)
+ read_stack (p->v.mem.addr + source_offset, buffer, this_size);
else
- read_memory (p->v.expr.value + source_offset, buffer, this_size);
+ read_memory (p->v.mem.addr + source_offset, buffer, this_size);
break;
case DWARF_VALUE_STACK:
else if (source_offset == 0)
store_unsigned_integer (buffer, n,
gdbarch_byte_order (gdbarch),
- p->v.expr.value);
+ p->v.value);
else
{
gdb_byte bytes[sizeof (ULONGEST)];
store_unsigned_integer (bytes, n + source_offset,
gdbarch_byte_order (gdbarch),
- p->v.expr.value);
+ p->v.value);
memcpy (buffer, bytes + source_offset, n);
}
}
break;
case DWARF_VALUE_OPTIMIZED_OUT:
- /* We just leave the bits empty for now. This is not ideal
- but gdb currently does not have a nice way to represent
- optimized-out pieces. */
- warning (_("bits %ld-%ld in computed object were optimized out; "
- "replacing with zeroes"),
- offset,
- offset + (long) this_size_bits);
+ set_value_optimized_out (v, 1);
break;
default:
contents = value_contents (from);
bits_to_skip = 8 * value_offset (to);
- type_len = 8 * TYPE_LENGTH (value_type (to));
+ if (value_bitsize (to))
+ {
+ bits_to_skip += value_bitpos (to);
+ type_len = value_bitsize (to);
+ }
+ else
+ type_len = 8 * TYPE_LENGTH (value_type (to));
+
for (i = 0; i < c->n_pieces && offset < type_len; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
case DWARF_VALUE_REGISTER:
{
struct gdbarch *arch = get_frame_arch (frame);
- int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.expr.value);
+ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
int reg_offset = dest_offset;
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
else
{
error (_("Unable to write to DWARF register number %s"),
- paddress (arch, p->v.expr.value));
+ paddress (arch, p->v.value));
}
}
break;
{
/* Only the first and last bytes can possibly have any
bits reused. */
- read_memory (p->v.expr.value + dest_offset, buffer, 1);
- read_memory (p->v.expr.value + dest_offset + this_size - 1,
+ read_memory (p->v.mem.addr + dest_offset, buffer, 1);
+ read_memory (p->v.mem.addr + dest_offset + this_size - 1,
buffer + this_size - 1, 1);
copy_bitwise (buffer, dest_offset_bits,
contents, source_offset_bits,
bits_big_endian);
}
- write_memory (p->v.expr.value + dest_offset,
+ write_memory (p->v.mem.addr + dest_offset,
source_buffer, this_size);
break;
default:
set_value_optimized_out (to, 1);
- goto done;
+ break;
}
offset += this_size_bits;
}
- done:
do_cleanups (cleanup);
}
+static int
+check_pieced_value_bits (const struct value *value, int bit_offset,
+ int bit_length, int validity)
+{
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (value);
+ int i;
+
+ bit_offset += 8 * value_offset (value);
+ if (value_bitsize (value))
+ bit_offset += value_bitpos (value);
+
+ for (i = 0; i < c->n_pieces && bit_length > 0; i++)
+ {
+ struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t this_size_bits = p->size;
+
+ if (bit_offset > 0)
+ {
+ if (bit_offset >= this_size_bits)
+ {
+ bit_offset -= this_size_bits;
+ continue;
+ }
+
+ bit_length -= this_size_bits - bit_offset;
+ bit_offset = 0;
+ }
+ else
+ bit_length -= this_size_bits;
+
+ if (p->location == DWARF_VALUE_OPTIMIZED_OUT)
+ {
+ if (validity)
+ return 0;
+ }
+ else
+ {
+ if (!validity)
+ return 1;
+ }
+ }
+
+ return validity;
+}
+
+static int
+check_pieced_value_validity (const struct value *value, int bit_offset,
+ int bit_length)
+{
+ return check_pieced_value_bits (value, bit_offset, bit_length, 1);
+}
+
+static int
+check_pieced_value_invalid (const struct value *value)
+{
+ return check_pieced_value_bits (value, 0,
+ 8 * TYPE_LENGTH (value_type (value)), 0);
+}
+
static void *
-copy_pieced_value_closure (struct value *v)
+copy_pieced_value_closure (const struct value *v)
{
struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
static struct lval_funcs pieced_value_funcs = {
read_pieced_value,
write_pieced_value,
+ check_pieced_value_validity,
+ check_pieced_value_invalid,
copy_pieced_value_closure,
free_pieced_value_closure
};
case DWARF_VALUE_REGISTER:
{
struct gdbarch *arch = get_frame_arch (frame);
- CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
+ ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0);
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
if (gdb_regnum != -1)
case DWARF_VALUE_MEMORY:
{
- CORE_ADDR address = dwarf_expr_fetch (ctx, 0);
+ CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
retval = allocate_value (type);
case DWARF_VALUE_STACK:
{
- ULONGEST value = (ULONGEST) dwarf_expr_fetch (ctx, 0);
+ ULONGEST value = dwarf_expr_fetch (ctx, 0);
bfd_byte *contents;
size_t n = ctx->addr_size;
while (op_ptr < op_end)
{
enum dwarf_location_atom op = *op_ptr;
- CORE_ADDR result;
ULONGEST uoffset, reg;
LONGEST offset;
int i;
break;
case DW_OP_addr:
- result = dwarf2_read_address (arch, op_ptr, op_end, addr_size);
- ax_const_l (expr, result);
+ ax_const_l (expr, extract_unsigned_integer (op_ptr,
+ addr_size, byte_order));
op_ptr += addr_size;
break;
&& data[1 + addr_size] == DW_OP_GNU_push_tls_address
&& piece_end_p (data + 2 + addr_size, end))
{
- CORE_ADDR offset = dwarf2_read_address (gdbarch,
- data + 1,
- end,
- addr_size);
+ ULONGEST offset;
+ offset = extract_unsigned_integer (data + 1, addr_size,
+ gdbarch_byte_order (gdbarch));
fprintf_filtered (stream,
- _("a thread-local variable at offset %s "
+ _("a thread-local variable at offset 0x%s "
"in the thread-local storage for `%s'"),
- paddress (gdbarch, offset), objfile->name);
+ phex_nz (offset, addr_size), objfile->name);
data += 1 + addr_size + 1;
}
|| (data[0] != DW_OP_piece && data[0] != DW_OP_bit_piece)))
{
enum dwarf_location_atom op = *data++;
- CORE_ADDR addr;
ULONGEST ul;
LONGEST l;
const char *name;
switch (op)
{
case DW_OP_addr:
- addr = dwarf2_read_address (arch, data, end, addr_size);
+ ul = extract_unsigned_integer (data, addr_size,
+ gdbarch_byte_order (arch));
data += addr_size;
- fprintf_filtered (stream, " %s", paddress (arch, addr));
+ fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size));
break;
case DW_OP_const1u:
struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
- compile_dwarf_to_ax (ax, value, gdbarch, addr_size,
- dlbaton->data, dlbaton->data + dlbaton->size,
- dlbaton->per_cu);
+ if (dlbaton->data == NULL || dlbaton->size == 0)
+ value->optimized_out = 1;
+ else
+ compile_dwarf_to_ax (ax, value, gdbarch, addr_size,
+ dlbaton->data, dlbaton->data + dlbaton->size,
+ dlbaton->per_cu);
}
/* The set of location functions used with the DWARF-2 expression
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
int offset_size = dwarf2_per_cu_offset_size (dlbaton->per_cu);
+ int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
/* Adjust base_address for relocatable objects. */
CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
error (_("Corrupted DWARF expression for symbol \"%s\"."),
SYMBOL_PRINT_NAME (symbol));
- low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+ if (signed_addr_p)
+ low = extract_signed_integer (loc_ptr, addr_size, byte_order);
+ else
+ low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+ loc_ptr += addr_size;
+
+ if (signed_addr_p)
+ high = extract_signed_integer (loc_ptr, addr_size, byte_order);
+ else
+ high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
loc_ptr += addr_size;
/* A base-address-selection entry. */
- if (low == base_mask)
+ if ((low & base_mask) == base_mask)
{
- base_address = dwarf2_read_address (gdbarch,
- loc_ptr, buf_end, addr_size);
+ base_address = high + base_offset;
fprintf_filtered (stream, _(" Base address %s"),
paddress (gdbarch, base_address));
- loc_ptr += addr_size;
continue;
}
- high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
- loc_ptr += addr_size;
-
/* An end-of-list entry. */
if (low == 0 && high == 0)
break;
unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
data = find_location_expression (dlbaton, &size, ax->scope);
-
- compile_dwarf_to_ax (ax, value, gdbarch, addr_size, data, data + size,
- dlbaton->per_cu);
+ if (data == NULL || size == 0)
+ value->optimized_out = 1;
+ else
+ compile_dwarf_to_ax (ax, value, gdbarch, addr_size, data, data + size,
+ dlbaton->per_cu);
}
/* The set of location functions used with the DWARF-2 expression