2008-03-18 Ulrich Weigand <uweigand@de.ibm.com>
Jim Blandy <jimb@codesourcery.com> Daniel Jacobowitz <drow@false.org> * dwarf2expr.h (struct dwarf_expr_context): Add ADDR_SIZE member. (dwarf2_read_address): Update prototype. * dwarf2expr.c (unsigned_address_type): Add ADDR_SIZE parameter. (signed_address_type): Likewise. (dwarf2_read_address): Replace BYTES_READ parameter with ADDR_SIZE. (execute_stack_op): Update calls to unsigned_address_type, signed_address_type and dwarf2_read_address. Fix implementation of DW_OP_deref_size. * dwarf2loc.h (dwarf2_per_cu_objfile): Add prototype. (dwarf2_per_cu_addr_size): Likewise. (struct dwarf2_locexpr_baton): Replace OBJFILE with PER_CU. (struct dwarf2_loclist_baton): Likewise. * dwarf2loc.c (find_location_expression): Update calls to dwarf2_read_address. Use dwarf2_per_cu_objfile and dwarf2_per_cu_addr_size to retrieve PER_CU parameters. (locexpr_describe_location): Likewise. (dwarf2_evaluate_loc_desc): Replace OBJFILE with PER_CU parameter. Set ctx->addr_size to dwarf2_per_cu_addr_size (per_cu). (dwarf2_loc_desc_needs_frame): Add PER_CU parameter. Set ctx->addr_size to dwarf2_per_cu_addr_size (per_cu). (locexpr_read_variable): Update dwarf2_evaluate_loc_desc call. (loclist_read_variable): Likewise. (locexpr_read_needs_frame): Update dwarf2_loc_desc_needs_frame call. * dwarf2read.c (dwarf2_symbol_mark_computed): Set baton->per_cu instead of baton->objfile. (dwarf2_per_cu_obfile): New function. (dwarf2_per_cu_addr_size): Likewise. * dwarf2-frame.c (struct comp_unit): Move higher. (struct dwarf2_cie): Add UNIT and ADDR_SIZE members. (execute_stack_op): Add ADDR_SIZE parameter; set ctx->addr_size. (execute_cfa_program): Add FDE parameter. Replace EH_FRAME_P parameter by using fde->eh_frame_p. Use read_encoded_value to implement DW_CFA_set_loc. (struct dwarf2_frame_cache): Add ADDR_SIZE member. (dwarf2_frame_cache): Set cache->addr_size. Update calls to execute_stack_op and execute_cfa_program. (dwarf2_frame_prev_register): Update calls to execute_stack_op. (size_of_encoded_value): Remove. (read_encoded_value): Add PTR_LEN and FUNC_BASE parameters. Remove call to size_of_encoded_value. Implement DW_EH_PE_funcrel. (add_cie): Set cie->unit backlink. (decode_frame_entry_1): Set cie->addr_size. Update calls to read_encoded_value. (dwarf2_build_frame_info): Allocate UNIT on objfile obstack.
This commit is contained in:
parent
188e2ff3a5
commit
ae0d2f24fd
@ -1,3 +1,57 @@
|
||||
2008-03-18 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
Jim Blandy <jimb@codesourcery.com>
|
||||
Daniel Jacobowitz <drow@false.org>
|
||||
|
||||
* dwarf2expr.h (struct dwarf_expr_context): Add ADDR_SIZE member.
|
||||
(dwarf2_read_address): Update prototype.
|
||||
|
||||
* dwarf2expr.c (unsigned_address_type): Add ADDR_SIZE parameter.
|
||||
(signed_address_type): Likewise.
|
||||
(dwarf2_read_address): Replace BYTES_READ parameter with ADDR_SIZE.
|
||||
(execute_stack_op): Update calls to unsigned_address_type,
|
||||
signed_address_type and dwarf2_read_address. Fix implementation
|
||||
of DW_OP_deref_size.
|
||||
|
||||
* dwarf2loc.h (dwarf2_per_cu_objfile): Add prototype.
|
||||
(dwarf2_per_cu_addr_size): Likewise.
|
||||
(struct dwarf2_locexpr_baton): Replace OBJFILE with PER_CU.
|
||||
(struct dwarf2_loclist_baton): Likewise.
|
||||
|
||||
* dwarf2loc.c (find_location_expression): Update calls to
|
||||
dwarf2_read_address. Use dwarf2_per_cu_objfile and
|
||||
dwarf2_per_cu_addr_size to retrieve PER_CU parameters.
|
||||
(locexpr_describe_location): Likewise.
|
||||
(dwarf2_evaluate_loc_desc): Replace OBJFILE with PER_CU parameter.
|
||||
Set ctx->addr_size to dwarf2_per_cu_addr_size (per_cu).
|
||||
(dwarf2_loc_desc_needs_frame): Add PER_CU parameter. Set ctx->addr_size
|
||||
to dwarf2_per_cu_addr_size (per_cu).
|
||||
(locexpr_read_variable): Update dwarf2_evaluate_loc_desc call.
|
||||
(loclist_read_variable): Likewise.
|
||||
(locexpr_read_needs_frame): Update dwarf2_loc_desc_needs_frame call.
|
||||
|
||||
* dwarf2read.c (dwarf2_symbol_mark_computed): Set baton->per_cu
|
||||
instead of baton->objfile.
|
||||
(dwarf2_per_cu_obfile): New function.
|
||||
(dwarf2_per_cu_addr_size): Likewise.
|
||||
|
||||
* dwarf2-frame.c (struct comp_unit): Move higher.
|
||||
(struct dwarf2_cie): Add UNIT and ADDR_SIZE members.
|
||||
(execute_stack_op): Add ADDR_SIZE parameter; set ctx->addr_size.
|
||||
(execute_cfa_program): Add FDE parameter. Replace EH_FRAME_P
|
||||
parameter by using fde->eh_frame_p. Use read_encoded_value
|
||||
to implement DW_CFA_set_loc.
|
||||
(struct dwarf2_frame_cache): Add ADDR_SIZE member.
|
||||
(dwarf2_frame_cache): Set cache->addr_size. Update calls to
|
||||
execute_stack_op and execute_cfa_program.
|
||||
(dwarf2_frame_prev_register): Update calls to execute_stack_op.
|
||||
(size_of_encoded_value): Remove.
|
||||
(read_encoded_value): Add PTR_LEN and FUNC_BASE parameters.
|
||||
Remove call to size_of_encoded_value. Implement DW_EH_PE_funcrel.
|
||||
(add_cie): Set cie->unit backlink.
|
||||
(decode_frame_entry_1): Set cie->addr_size. Update calls to
|
||||
read_encoded_value.
|
||||
(dwarf2_build_frame_info): Allocate UNIT on objfile obstack.
|
||||
|
||||
2008-03-17 Markus Deuling <deuling@de.ibm.com>
|
||||
|
||||
* i386-tdep.c (i386_print_insn): Remove unnecessary call to
|
||||
|
@ -38,12 +38,17 @@
|
||||
#include "complaints.h"
|
||||
#include "dwarf2-frame.h"
|
||||
|
||||
struct comp_unit;
|
||||
|
||||
/* Call Frame Information (CFI). */
|
||||
|
||||
/* Common Information Entry (CIE). */
|
||||
|
||||
struct dwarf2_cie
|
||||
{
|
||||
/* Computation Unit for this CIE. */
|
||||
struct comp_unit *unit;
|
||||
|
||||
/* Offset into the .debug_frame section where this CIE was found.
|
||||
Used to identify this CIE. */
|
||||
ULONGEST cie_pointer;
|
||||
@ -68,6 +73,9 @@ struct dwarf2_cie
|
||||
/* Encoding of addresses. */
|
||||
gdb_byte encoding;
|
||||
|
||||
/* Target address size in bytes. */
|
||||
int addr_size;
|
||||
|
||||
/* True if a 'z' augmentation existed. */
|
||||
unsigned char saw_z_augmentation;
|
||||
|
||||
@ -104,10 +112,44 @@ struct dwarf2_fde
|
||||
struct dwarf2_fde *next;
|
||||
};
|
||||
|
||||
/* A minimal decoding of DWARF2 compilation units. We only decode
|
||||
what's needed to get to the call frame information. */
|
||||
|
||||
struct comp_unit
|
||||
{
|
||||
/* Keep the bfd convenient. */
|
||||
bfd *abfd;
|
||||
|
||||
struct objfile *objfile;
|
||||
|
||||
/* Linked list of CIEs for this object. */
|
||||
struct dwarf2_cie *cie;
|
||||
|
||||
/* Pointer to the .debug_frame section loaded into memory. */
|
||||
gdb_byte *dwarf_frame_buffer;
|
||||
|
||||
/* Length of the loaded .debug_frame section. */
|
||||
unsigned long dwarf_frame_size;
|
||||
|
||||
/* Pointer to the .debug_frame section. */
|
||||
asection *dwarf_frame_section;
|
||||
|
||||
/* Base for DW_EH_PE_datarel encodings. */
|
||||
bfd_vma dbase;
|
||||
|
||||
/* Base for DW_EH_PE_textrel encodings. */
|
||||
bfd_vma tbase;
|
||||
};
|
||||
|
||||
static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc);
|
||||
|
||||
static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
|
||||
int eh_frame_p);
|
||||
|
||||
static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
|
||||
int ptr_len, gdb_byte *buf,
|
||||
unsigned int *bytes_read_ptr,
|
||||
CORE_ADDR func_base);
|
||||
|
||||
|
||||
/* Structure describing a frame state. */
|
||||
@ -299,13 +341,14 @@ register %s (#%d) at 0x%s"),
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
execute_stack_op (gdb_byte *exp, ULONGEST len,
|
||||
execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
|
||||
struct frame_info *next_frame, CORE_ADDR initial)
|
||||
{
|
||||
struct dwarf_expr_context *ctx;
|
||||
CORE_ADDR result;
|
||||
|
||||
ctx = new_dwarf_expr_context ();
|
||||
ctx->addr_size = addr_size;
|
||||
ctx->baton = next_frame;
|
||||
ctx->read_reg = read_reg;
|
||||
ctx->read_mem = read_mem;
|
||||
@ -326,10 +369,11 @@ execute_stack_op (gdb_byte *exp, ULONGEST len,
|
||||
|
||||
|
||||
static void
|
||||
execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end,
|
||||
struct frame_info *next_frame,
|
||||
struct dwarf2_frame_state *fs, int eh_frame_p)
|
||||
execute_cfa_program (struct dwarf2_fde *fde, gdb_byte *insn_ptr,
|
||||
gdb_byte *insn_end, struct frame_info *next_frame,
|
||||
struct dwarf2_frame_state *fs)
|
||||
{
|
||||
int eh_frame_p = fde->eh_frame_p;
|
||||
CORE_ADDR pc = frame_pc_unwind (next_frame);
|
||||
int bytes_read;
|
||||
struct gdbarch *gdbarch = get_frame_arch (next_frame);
|
||||
@ -362,7 +406,12 @@ execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end,
|
||||
switch (insn)
|
||||
{
|
||||
case DW_CFA_set_loc:
|
||||
fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read);
|
||||
fs->pc = read_encoded_value (fde->cie->unit, fde->cie->encoding,
|
||||
fde->cie->addr_size, insn_ptr,
|
||||
&bytes_read, fde->initial_location);
|
||||
/* Apply the objfile offset for relocatable objects. */
|
||||
fs->pc += ANOFFSET (fde->cie->unit->objfile->section_offsets,
|
||||
SECT_OFF_TEXT (fde->cie->unit->objfile));
|
||||
insn_ptr += bytes_read;
|
||||
break;
|
||||
|
||||
@ -813,6 +862,9 @@ struct dwarf2_frame_cache
|
||||
|
||||
/* Return address register. */
|
||||
struct dwarf2_frame_state_reg retaddr_reg;
|
||||
|
||||
/* Target address size in bytes. */
|
||||
int addr_size;
|
||||
};
|
||||
|
||||
static struct dwarf2_frame_cache *
|
||||
@ -863,21 +915,21 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
|
||||
fs->data_align = fde->cie->data_alignment_factor;
|
||||
fs->code_align = fde->cie->code_alignment_factor;
|
||||
fs->retaddr_column = fde->cie->return_address_register;
|
||||
cache->addr_size = fde->cie->addr_size;
|
||||
|
||||
/* Check for "quirks" - known bugs in producers. */
|
||||
dwarf2_frame_find_quirks (fs, fde);
|
||||
|
||||
/* First decode all the insns in the CIE. */
|
||||
execute_cfa_program (fde->cie->initial_instructions,
|
||||
fde->cie->end, next_frame, fs, fde->eh_frame_p);
|
||||
execute_cfa_program (fde, fde->cie->initial_instructions,
|
||||
fde->cie->end, next_frame, fs);
|
||||
|
||||
/* Save the initialized register set. */
|
||||
fs->initial = fs->regs;
|
||||
fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs);
|
||||
|
||||
/* Then decode the insns in the FDE up to our target PC. */
|
||||
execute_cfa_program (fde->instructions, fde->end, next_frame, fs,
|
||||
fde->eh_frame_p);
|
||||
execute_cfa_program (fde, fde->instructions, fde->end, next_frame, fs);
|
||||
|
||||
/* Caclulate the CFA. */
|
||||
switch (fs->cfa_how)
|
||||
@ -892,7 +944,8 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
|
||||
|
||||
case CFA_EXP:
|
||||
cache->cfa =
|
||||
execute_stack_op (fs->cfa_exp, fs->cfa_exp_len, next_frame, 0);
|
||||
execute_stack_op (fs->cfa_exp, fs->cfa_exp_len,
|
||||
cache->addr_size, next_frame, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1089,7 +1142,7 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
*lvalp = lval_memory;
|
||||
*addrp = execute_stack_op (cache->reg[regnum].loc.exp,
|
||||
cache->reg[regnum].exp_len,
|
||||
next_frame, cache->cfa);
|
||||
cache->addr_size, next_frame, cache->cfa);
|
||||
*realnump = -1;
|
||||
if (valuep)
|
||||
{
|
||||
@ -1117,7 +1170,8 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
store_unsigned_integer (valuep, register_size (gdbarch, regnum),
|
||||
execute_stack_op (cache->reg[regnum].loc.exp,
|
||||
cache->reg[regnum].exp_len,
|
||||
next_frame, cache->cfa));
|
||||
cache->addr_size, next_frame,
|
||||
cache->cfa));
|
||||
break;
|
||||
|
||||
case DWARF2_FRAME_REG_UNSPECIFIED:
|
||||
@ -1261,35 +1315,6 @@ dwarf2_frame_base_sniffer (struct frame_info *next_frame)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* A minimal decoding of DWARF2 compilation units. We only decode
|
||||
what's needed to get to the call frame information. */
|
||||
|
||||
struct comp_unit
|
||||
{
|
||||
/* Keep the bfd convenient. */
|
||||
bfd *abfd;
|
||||
|
||||
struct objfile *objfile;
|
||||
|
||||
/* Linked list of CIEs for this object. */
|
||||
struct dwarf2_cie *cie;
|
||||
|
||||
/* Pointer to the .debug_frame section loaded into memory. */
|
||||
gdb_byte *dwarf_frame_buffer;
|
||||
|
||||
/* Length of the loaded .debug_frame section. */
|
||||
unsigned long dwarf_frame_size;
|
||||
|
||||
/* Pointer to the .debug_frame section. */
|
||||
asection *dwarf_frame_section;
|
||||
|
||||
/* Base for DW_EH_PE_datarel encodings. */
|
||||
bfd_vma dbase;
|
||||
|
||||
/* Base for DW_EH_PE_textrel encodings. */
|
||||
bfd_vma tbase;
|
||||
};
|
||||
|
||||
const struct objfile_data *dwarf2_frame_objfile_data;
|
||||
|
||||
static unsigned int
|
||||
@ -1417,32 +1442,11 @@ encoding_for_size (unsigned int size)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
size_of_encoded_value (gdb_byte encoding)
|
||||
{
|
||||
if (encoding == DW_EH_PE_omit)
|
||||
return 0;
|
||||
|
||||
switch (encoding & 0x07)
|
||||
{
|
||||
case DW_EH_PE_absptr:
|
||||
return TYPE_LENGTH (builtin_type_void_data_ptr);
|
||||
case DW_EH_PE_udata2:
|
||||
return 2;
|
||||
case DW_EH_PE_udata4:
|
||||
return 4;
|
||||
case DW_EH_PE_udata8:
|
||||
return 8;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__, _("Invalid or unsupported encoding"));
|
||||
}
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
|
||||
gdb_byte *buf, unsigned int *bytes_read_ptr)
|
||||
int ptr_len, gdb_byte *buf, unsigned int *bytes_read_ptr,
|
||||
CORE_ADDR func_base)
|
||||
{
|
||||
int ptr_len = size_of_encoded_value (DW_EH_PE_absptr);
|
||||
ptrdiff_t offset;
|
||||
CORE_ADDR base;
|
||||
|
||||
@ -1470,12 +1474,7 @@ read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
|
||||
base = unit->tbase;
|
||||
break;
|
||||
case DW_EH_PE_funcrel:
|
||||
/* FIXME: kettenis/20040501: For now just pretend
|
||||
DW_EH_PE_funcrel is equivalent to DW_EH_PE_absptr. For
|
||||
reading the initial location of an FDE it should be treated
|
||||
as such, and currently that's the only place where this code
|
||||
is used. */
|
||||
base = 0;
|
||||
base = func_base;
|
||||
break;
|
||||
case DW_EH_PE_aligned:
|
||||
base = 0;
|
||||
@ -1561,6 +1560,7 @@ add_cie (struct comp_unit *unit, struct dwarf2_cie *cie)
|
||||
{
|
||||
cie->next = unit->cie;
|
||||
unit->cie = cie;
|
||||
cie->unit = unit;
|
||||
}
|
||||
|
||||
/* Find the FDE for *PC. Return a pointer to the FDE, and store the
|
||||
@ -1685,6 +1685,13 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
|
||||
depends on the target address size. */
|
||||
cie->encoding = DW_EH_PE_absptr;
|
||||
|
||||
/* The target address size. For .eh_frame FDEs this is considered
|
||||
equal to the size of a target pointer. For .dwarf_frame FDEs,
|
||||
this is supposed to be the target address size from the associated
|
||||
CU header. FIXME: We do not have a good way to determine the
|
||||
latter. Always use the target pointer size for now. */
|
||||
cie->addr_size = gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT;
|
||||
|
||||
/* We'll determine the final value later, but we need to
|
||||
initialize it conservatively. */
|
||||
cie->signal_frame = 0;
|
||||
@ -1773,7 +1780,8 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
|
||||
{
|
||||
/* Skip. Avoid indirection since we throw away the result. */
|
||||
gdb_byte encoding = (*buf++) & ~DW_EH_PE_indirect;
|
||||
read_encoded_value (unit, encoding, buf, &bytes_read);
|
||||
read_encoded_value (unit, encoding, cie->addr_size,
|
||||
buf, &bytes_read, 0);
|
||||
buf += bytes_read;
|
||||
augmentation++;
|
||||
}
|
||||
@ -1837,11 +1845,13 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
|
||||
gdb_assert (fde->cie != NULL);
|
||||
|
||||
fde->initial_location =
|
||||
read_encoded_value (unit, fde->cie->encoding, buf, &bytes_read);
|
||||
read_encoded_value (unit, fde->cie->encoding, fde->cie->addr_size,
|
||||
buf, &bytes_read, 0);
|
||||
buf += bytes_read;
|
||||
|
||||
fde->address_range =
|
||||
read_encoded_value (unit, fde->cie->encoding & 0x0f, buf, &bytes_read);
|
||||
read_encoded_value (unit, fde->cie->encoding & 0x0f,
|
||||
fde->cie->addr_size, buf, &bytes_read, 0);
|
||||
buf += bytes_read;
|
||||
|
||||
/* A 'z' augmentation in the CIE implies the presence of an
|
||||
@ -1975,14 +1985,16 @@ extern gdb_byte *dwarf2_read_section (struct objfile *objfile, asection *sectp);
|
||||
void
|
||||
dwarf2_build_frame_info (struct objfile *objfile)
|
||||
{
|
||||
struct comp_unit unit;
|
||||
struct comp_unit *unit;
|
||||
gdb_byte *frame_ptr;
|
||||
|
||||
/* Build a minimal decoding of the DWARF2 compilation unit. */
|
||||
unit.abfd = objfile->obfd;
|
||||
unit.objfile = objfile;
|
||||
unit.dbase = 0;
|
||||
unit.tbase = 0;
|
||||
unit = (struct comp_unit *) obstack_alloc (&objfile->objfile_obstack,
|
||||
sizeof (struct comp_unit));
|
||||
unit->abfd = objfile->obfd;
|
||||
unit->objfile = objfile;
|
||||
unit->dbase = 0;
|
||||
unit->tbase = 0;
|
||||
|
||||
/* First add the information from the .eh_frame section. That way,
|
||||
the FDEs from that section are searched last. */
|
||||
@ -1990,43 +2002,43 @@ dwarf2_build_frame_info (struct objfile *objfile)
|
||||
{
|
||||
asection *got, *txt;
|
||||
|
||||
unit.cie = NULL;
|
||||
unit.dwarf_frame_buffer = dwarf2_read_section (objfile,
|
||||
dwarf_eh_frame_section);
|
||||
unit->cie = NULL;
|
||||
unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
|
||||
dwarf_eh_frame_section);
|
||||
|
||||
unit.dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
|
||||
unit.dwarf_frame_section = dwarf_eh_frame_section;
|
||||
unit->dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
|
||||
unit->dwarf_frame_section = dwarf_eh_frame_section;
|
||||
|
||||
/* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base
|
||||
that is used for the i386/amd64 target, which currently is
|
||||
the only target in GCC that supports/uses the
|
||||
DW_EH_PE_datarel encoding. */
|
||||
got = bfd_get_section_by_name (unit.abfd, ".got");
|
||||
got = bfd_get_section_by_name (unit->abfd, ".got");
|
||||
if (got)
|
||||
unit.dbase = got->vma;
|
||||
unit->dbase = got->vma;
|
||||
|
||||
/* GCC emits the DW_EH_PE_textrel encoding type on sh and ia64
|
||||
so far. */
|
||||
txt = bfd_get_section_by_name (unit.abfd, ".text");
|
||||
txt = bfd_get_section_by_name (unit->abfd, ".text");
|
||||
if (txt)
|
||||
unit.tbase = txt->vma;
|
||||
unit->tbase = txt->vma;
|
||||
|
||||
frame_ptr = unit.dwarf_frame_buffer;
|
||||
while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size)
|
||||
frame_ptr = decode_frame_entry (&unit, frame_ptr, 1);
|
||||
frame_ptr = unit->dwarf_frame_buffer;
|
||||
while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
|
||||
frame_ptr = decode_frame_entry (unit, frame_ptr, 1);
|
||||
}
|
||||
|
||||
if (dwarf_frame_section)
|
||||
{
|
||||
unit.cie = NULL;
|
||||
unit.dwarf_frame_buffer = dwarf2_read_section (objfile,
|
||||
dwarf_frame_section);
|
||||
unit.dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
|
||||
unit.dwarf_frame_section = dwarf_frame_section;
|
||||
unit->cie = NULL;
|
||||
unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
|
||||
dwarf_frame_section);
|
||||
unit->dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
|
||||
unit->dwarf_frame_section = dwarf_frame_section;
|
||||
|
||||
frame_ptr = unit.dwarf_frame_buffer;
|
||||
while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size)
|
||||
frame_ptr = decode_frame_entry (&unit, frame_ptr, 0);
|
||||
frame_ptr = unit->dwarf_frame_buffer;
|
||||
while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
|
||||
frame_ptr = decode_frame_entry (unit, frame_ptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
static void execute_stack_op (struct dwarf_expr_context *,
|
||||
gdb_byte *, gdb_byte *);
|
||||
static struct type *unsigned_address_type (void);
|
||||
static struct type *unsigned_address_type (int);
|
||||
|
||||
/* Create a new context for the expression evaluator. */
|
||||
|
||||
@ -192,20 +192,17 @@ read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Read an address from BUF, and verify that it doesn't extend past
|
||||
BUF_END. The address is returned, and *BYTES_READ is set to the
|
||||
number of bytes read from BUF. */
|
||||
/* Read an address of size ADDR_SIZE from BUF, and verify that it
|
||||
doesn't extend past BUF_END. */
|
||||
|
||||
CORE_ADDR
|
||||
dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
|
||||
dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int addr_size)
|
||||
{
|
||||
CORE_ADDR result;
|
||||
|
||||
if (buf_end - buf < gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
|
||||
if (buf_end - buf < addr_size)
|
||||
error (_("dwarf2_read_address: Corrupted DWARF expression."));
|
||||
|
||||
*bytes_read = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
|
||||
|
||||
/* For most architectures, calling extract_unsigned_integer() alone
|
||||
is sufficient for extracting an address. However, some
|
||||
architectures (e.g. MIPS) use signed addresses and using
|
||||
@ -229,21 +226,18 @@ dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
|
||||
address being returned. */
|
||||
|
||||
result = value_as_address (value_from_longest
|
||||
(unsigned_address_type (),
|
||||
extract_unsigned_integer
|
||||
(buf,
|
||||
gdbarch_addr_bit (current_gdbarch)
|
||||
/ TARGET_CHAR_BIT)));
|
||||
|
||||
(unsigned_address_type (addr_size),
|
||||
extract_unsigned_integer (buf, addr_size)));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return the type of an address, for unsigned arithmetic. */
|
||||
/* Return the type of an address of size ADDR_SIZE,
|
||||
for unsigned arithmetic. */
|
||||
|
||||
static struct type *
|
||||
unsigned_address_type (void)
|
||||
unsigned_address_type (int addr_size)
|
||||
{
|
||||
switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
|
||||
switch (addr_size)
|
||||
{
|
||||
case 2:
|
||||
return builtin_type_uint16;
|
||||
@ -257,12 +251,13 @@ unsigned_address_type (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the type of an address, for signed arithmetic. */
|
||||
/* Return the type of an address of size ADDR_SIZE,
|
||||
for signed arithmetic. */
|
||||
|
||||
static struct type *
|
||||
signed_address_type (void)
|
||||
signed_address_type (int addr_size)
|
||||
{
|
||||
switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
|
||||
switch (addr_size)
|
||||
{
|
||||
case 2:
|
||||
return builtin_type_int16;
|
||||
@ -292,7 +287,6 @@ execute_stack_op (struct dwarf_expr_context *ctx,
|
||||
CORE_ADDR result;
|
||||
ULONGEST uoffset, reg;
|
||||
LONGEST offset;
|
||||
int bytes_read;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
@ -332,8 +326,8 @@ execute_stack_op (struct dwarf_expr_context *ctx,
|
||||
break;
|
||||
|
||||
case DW_OP_addr:
|
||||
result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
|
||||
op_ptr += bytes_read;
|
||||
result = dwarf2_read_address (op_ptr, op_end, ctx->addr_size);
|
||||
op_ptr += ctx->addr_size;
|
||||
break;
|
||||
|
||||
case DW_OP_const1u:
|
||||
@ -550,34 +544,20 @@ execute_stack_op (struct dwarf_expr_context *ctx,
|
||||
{
|
||||
case DW_OP_deref:
|
||||
{
|
||||
gdb_byte *buf = alloca (gdbarch_addr_bit (current_gdbarch)
|
||||
/ TARGET_CHAR_BIT);
|
||||
int bytes_read;
|
||||
|
||||
(ctx->read_mem) (ctx->baton, buf, result,
|
||||
gdbarch_addr_bit (current_gdbarch)
|
||||
/ TARGET_CHAR_BIT);
|
||||
result = dwarf2_read_address (buf,
|
||||
buf + (gdbarch_addr_bit
|
||||
(current_gdbarch)
|
||||
/ TARGET_CHAR_BIT),
|
||||
&bytes_read);
|
||||
gdb_byte *buf = alloca (ctx->addr_size);
|
||||
(ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size);
|
||||
result = dwarf2_read_address (buf, buf + ctx->addr_size,
|
||||
ctx->addr_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_OP_deref_size:
|
||||
{
|
||||
gdb_byte *buf
|
||||
= alloca (gdbarch_addr_bit (current_gdbarch)
|
||||
/ TARGET_CHAR_BIT);
|
||||
int bytes_read;
|
||||
|
||||
(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
|
||||
result = dwarf2_read_address (buf,
|
||||
buf + (gdbarch_addr_bit
|
||||
(current_gdbarch)
|
||||
/ TARGET_CHAR_BIT),
|
||||
&bytes_read);
|
||||
int addr_size = *op_ptr++;
|
||||
gdb_byte *buf = alloca (addr_size);
|
||||
(ctx->read_mem) (ctx->baton, buf, result, addr_size);
|
||||
result = dwarf2_read_address (buf, buf + addr_size,
|
||||
addr_size);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -628,8 +608,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
|
||||
first = dwarf_expr_fetch (ctx, 0);
|
||||
dwarf_expr_pop (ctx);
|
||||
|
||||
val1 = value_from_longest (unsigned_address_type (), first);
|
||||
val2 = value_from_longest (unsigned_address_type (), second);
|
||||
val1 = value_from_longest
|
||||
(unsigned_address_type (ctx->addr_size), first);
|
||||
val2 = value_from_longest
|
||||
(unsigned_address_type (ctx->addr_size), second);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
@ -662,7 +644,8 @@ execute_stack_op (struct dwarf_expr_context *ctx,
|
||||
break;
|
||||
case DW_OP_shra:
|
||||
binop = BINOP_RSH;
|
||||
val1 = value_from_longest (signed_address_type (), first);
|
||||
val1 = value_from_longest
|
||||
(signed_address_type (ctx->addr_size), first);
|
||||
break;
|
||||
case DW_OP_xor:
|
||||
binop = BINOP_BITWISE_XOR;
|
||||
|
@ -34,6 +34,9 @@ struct dwarf_expr_context
|
||||
number of elements allocated to the stack. */
|
||||
int stack_len, stack_allocated;
|
||||
|
||||
/* Target address size in bytes. */
|
||||
int addr_size;
|
||||
|
||||
/* An opaque argument provided by the caller, which will be passed
|
||||
to all of the callback functions. */
|
||||
void *baton;
|
||||
@ -136,6 +139,6 @@ CORE_ADDR dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
|
||||
gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r);
|
||||
gdb_byte *read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r);
|
||||
CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end,
|
||||
int *bytes_read);
|
||||
int addr_size);
|
||||
|
||||
#endif /* dwarf2expr.h */
|
||||
|
@ -54,11 +54,12 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
|
||||
CORE_ADDR low, high;
|
||||
gdb_byte *loc_ptr, *buf_end;
|
||||
int length;
|
||||
unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
|
||||
struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
|
||||
unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
|
||||
CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
|
||||
/* Adjust base_address for relocatable objects. */
|
||||
CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets,
|
||||
SECT_OFF_TEXT (baton->objfile));
|
||||
CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
|
||||
SECT_OFF_TEXT (objfile));
|
||||
CORE_ADDR base_address = baton->base_address + base_offset;
|
||||
|
||||
loc_ptr = baton->data;
|
||||
@ -66,10 +67,10 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
|
||||
|
||||
while (1)
|
||||
{
|
||||
low = dwarf2_read_address (loc_ptr, buf_end, &length);
|
||||
loc_ptr += length;
|
||||
high = dwarf2_read_address (loc_ptr, buf_end, &length);
|
||||
loc_ptr += length;
|
||||
low = dwarf2_read_address (loc_ptr, buf_end, addr_size);
|
||||
loc_ptr += addr_size;
|
||||
high = dwarf2_read_address (loc_ptr, buf_end, addr_size);
|
||||
loc_ptr += addr_size;
|
||||
|
||||
/* An end-of-list entry. */
|
||||
if (low == 0 && high == 0)
|
||||
@ -189,7 +190,7 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
|
||||
static struct value *
|
||||
dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
|
||||
gdb_byte *data, unsigned short size,
|
||||
struct objfile *objfile)
|
||||
struct dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
struct gdbarch *arch = get_frame_arch (frame);
|
||||
struct value *retval;
|
||||
@ -205,9 +206,10 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
|
||||
}
|
||||
|
||||
baton.frame = frame;
|
||||
baton.objfile = objfile;
|
||||
baton.objfile = dwarf2_per_cu_objfile (per_cu);
|
||||
|
||||
ctx = new_dwarf_expr_context ();
|
||||
ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
|
||||
ctx->baton = &baton;
|
||||
ctx->read_reg = dwarf_expr_read_reg;
|
||||
ctx->read_mem = dwarf_expr_read_mem;
|
||||
@ -318,7 +320,8 @@ needs_frame_tls_address (void *baton, CORE_ADDR offset)
|
||||
requires a frame to evaluate. */
|
||||
|
||||
static int
|
||||
dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
|
||||
dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
|
||||
struct dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
struct needs_frame_baton baton;
|
||||
struct dwarf_expr_context *ctx;
|
||||
@ -327,6 +330,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
|
||||
baton.needs_frame = 0;
|
||||
|
||||
ctx = new_dwarf_expr_context ();
|
||||
ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
|
||||
ctx->baton = &baton;
|
||||
ctx->read_reg = needs_frame_read_reg;
|
||||
ctx->read_mem = needs_frame_read_mem;
|
||||
@ -429,7 +433,7 @@ locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
|
||||
struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
|
||||
struct value *val;
|
||||
val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
|
||||
dlbaton->objfile);
|
||||
dlbaton->per_cu);
|
||||
|
||||
return val;
|
||||
}
|
||||
@ -439,7 +443,8 @@ static int
|
||||
locexpr_read_needs_frame (struct symbol *symbol)
|
||||
{
|
||||
struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
|
||||
return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
|
||||
return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size,
|
||||
dlbaton->per_cu);
|
||||
}
|
||||
|
||||
/* Print a natural-language description of SYMBOL to STREAM. */
|
||||
@ -448,6 +453,7 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
|
||||
{
|
||||
/* FIXME: be more extensive. */
|
||||
struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
|
||||
int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
|
||||
|
||||
if (dlbaton->size == 1
|
||||
&& dlbaton->data[0] >= DW_OP_reg0
|
||||
@ -477,14 +483,14 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
|
||||
&& dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
|
||||
if (dlbaton->data[0] == DW_OP_addr)
|
||||
{
|
||||
int bytes_read;
|
||||
struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
|
||||
CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
|
||||
&dlbaton->data[dlbaton->size - 1],
|
||||
&bytes_read);
|
||||
addr_size);
|
||||
fprintf_filtered (stream,
|
||||
"a thread-local variable at offset %s in the "
|
||||
"thread-local storage for `%s'",
|
||||
paddr_nz (offset), dlbaton->objfile->name);
|
||||
paddr_nz (offset), objfile->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -546,7 +552,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
|
||||
}
|
||||
else
|
||||
val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
|
||||
dlbaton->objfile);
|
||||
dlbaton->per_cu);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -21,10 +21,18 @@
|
||||
#define DWARF2LOC_H
|
||||
|
||||
struct symbol_ops;
|
||||
struct objfile;
|
||||
struct dwarf2_per_cu_data;
|
||||
|
||||
/* This header is private to the DWARF-2 reader. It is shared between
|
||||
dwarf2read.c and dwarf2loc.c. */
|
||||
|
||||
/* Return the OBJFILE associated with the compilation unit CU. */
|
||||
struct objfile *dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *cu);
|
||||
|
||||
/* Return the address size given in the compilation unit header for CU. */
|
||||
CORE_ADDR dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *cu);
|
||||
|
||||
/* The symbol location baton types used by the DWARF-2 reader (i.e.
|
||||
SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol). "struct
|
||||
dwarf2_locexpr_baton" is for a symbol with a single location
|
||||
@ -39,8 +47,9 @@ struct dwarf2_locexpr_baton
|
||||
/* Length of the location expression. */
|
||||
unsigned long size;
|
||||
|
||||
/* The objfile containing the symbol whose location we're computing. */
|
||||
struct objfile *objfile;
|
||||
/* The compilation unit containing the symbol whose location
|
||||
we're computing. */
|
||||
struct dwarf2_per_cu_data *per_cu;
|
||||
};
|
||||
|
||||
struct dwarf2_loclist_baton
|
||||
@ -55,12 +64,9 @@ struct dwarf2_loclist_baton
|
||||
/* Length of the location list. */
|
||||
unsigned long size;
|
||||
|
||||
/* The objfile containing the symbol whose location we're computing. */
|
||||
/* Used (only???) by thread local variables. The objfile in which
|
||||
this symbol is defined. To find a thread-local variable (e.g., a
|
||||
variable declared with the `__thread' storage class), we may need
|
||||
to know which object file it's in. */
|
||||
struct objfile *objfile;
|
||||
/* The compilation unit containing the symbol whose location
|
||||
we're computing. */
|
||||
struct dwarf2_per_cu_data *per_cu;
|
||||
};
|
||||
|
||||
extern const struct symbol_ops dwarf2_locexpr_funcs;
|
||||
|
@ -9818,13 +9818,6 @@ static void
|
||||
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
|
||||
struct dwarf2_cu *cu)
|
||||
{
|
||||
struct objfile *objfile = cu->objfile;
|
||||
|
||||
/* Save the master objfile, so that we can report and look up the
|
||||
correct file containing this variable. */
|
||||
if (objfile->separate_debug_objfile_backlink)
|
||||
objfile = objfile->separate_debug_objfile_backlink;
|
||||
|
||||
if (attr_form_is_section_offset (attr)
|
||||
/* ".debug_loc" may not exist at all, or the offset may be outside
|
||||
the section. If so, fall through to the complaint in the
|
||||
@ -9835,7 +9828,8 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
|
||||
|
||||
baton = obstack_alloc (&cu->objfile->objfile_obstack,
|
||||
sizeof (struct dwarf2_loclist_baton));
|
||||
baton->objfile = objfile;
|
||||
baton->per_cu = cu->per_cu;
|
||||
gdb_assert (baton->per_cu);
|
||||
|
||||
/* We don't know how long the location list is, but make sure we
|
||||
don't run off the edge of the section. */
|
||||
@ -9855,7 +9849,8 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
|
||||
|
||||
baton = obstack_alloc (&cu->objfile->objfile_obstack,
|
||||
sizeof (struct dwarf2_locexpr_baton));
|
||||
baton->objfile = objfile;
|
||||
baton->per_cu = cu->per_cu;
|
||||
gdb_assert (baton->per_cu);
|
||||
|
||||
if (attr_form_is_block (attr))
|
||||
{
|
||||
@ -9880,6 +9875,43 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the OBJFILE associated with the compilation unit CU. */
|
||||
|
||||
struct objfile *
|
||||
dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
struct objfile *objfile = per_cu->psymtab->objfile;
|
||||
|
||||
/* Return the master objfile, so that we can report and look up the
|
||||
correct file containing this variable. */
|
||||
if (objfile->separate_debug_objfile_backlink)
|
||||
objfile = objfile->separate_debug_objfile_backlink;
|
||||
|
||||
return objfile;
|
||||
}
|
||||
|
||||
/* Return the address size given in the compilation unit header for CU. */
|
||||
|
||||
CORE_ADDR
|
||||
dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
if (per_cu->cu)
|
||||
return per_cu->cu->header.addr_size;
|
||||
else
|
||||
{
|
||||
/* If the CU is not currently read in, we re-read its header. */
|
||||
struct objfile *objfile = per_cu->psymtab->objfile;
|
||||
struct dwarf2_per_objfile *per_objfile
|
||||
= objfile_data (objfile, dwarf2_objfile_data_key);
|
||||
gdb_byte *info_ptr = per_objfile->info_buffer + per_cu->offset;
|
||||
|
||||
struct comp_unit_head cu_header;
|
||||
memset (&cu_header, 0, sizeof cu_header);
|
||||
read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
|
||||
return cu_header.addr_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Locate the compilation unit from CU's objfile which contains the
|
||||
DIE at OFFSET. Raises an error on failure. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user