aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/frame-unwind.c11
-rw-r--r--gdb/frame-unwind.h7
-rw-r--r--gdb/ia64-tdep.c695
-rw-r--r--gdb/libunwind-frame.c176
-rw-r--r--gdb/libunwind-frame.h20
6 files changed, 420 insertions, 496 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 7120c0a..87950a4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2008-05-06 Joel Brobecker <brobecker@adacore.com>
+
+ * frame-unwind.c (frame_unwind_got_bytes): New function.
+ * frame-unwind.h (frame_unwind_got_bytes): Add declaration.
+ * libunwind-frame.h, libunwind-frame.c, ia64-tdep.c: Update
+ for unwinder changes.
+
2008-05-05 Doug Evans <dje@google.com>
* NEWS: Mention new /m modifier for disassemble command.
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 7384259..cb79f4c 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -170,6 +170,17 @@ frame_unwind_got_constant (struct frame_info *frame, int regnum,
return reg_val;
}
+struct value *
+frame_unwind_got_bytes (struct frame_info *frame, int regnum, gdb_byte *buf)
+{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct value *reg_val;
+
+ reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
+ memcpy (value_contents_raw (reg_val), buf, register_size (gdbarch, regnum));
+ return reg_val;
+}
+
/* Return a value which indicates that FRAME's saved version of REGNUM
has a known constant (computed) value of ADDR. Convert the
CORE_ADDR to a target address if necessary. */
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index 3a35aa1..bd45fa9 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -183,6 +183,13 @@ struct value *frame_unwind_got_memory (struct frame_info *frame, int regnum,
struct value *frame_unwind_got_constant (struct frame_info *frame, int regnum,
ULONGEST val);
+/* Return a value which indicates that FRAME's saved version of
+ REGNUM has a known constant (computed) value which is stored
+ inside BUF. */
+
+struct value *frame_unwind_got_bytes (struct frame_info *frame, int regnum,
+ gdb_byte *buf);
+
/* Return a value which indicates that FRAME's saved version of REGNUM
has a known constant (computed) value of ADDR. Convert the
CORE_ADDR to a target address if necessary. */
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index ebde4dc..499213a 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -343,7 +343,7 @@ const struct floatformat *floatformats_ia64_ext[2] =
bit ``from''. */
static long long
-extract_bit_field (char *bundle, int from, int len)
+extract_bit_field (const char *bundle, int from, int len)
{
long long result = 0LL;
int to = from + len;
@@ -1061,7 +1061,9 @@ ia64_alloc_frame_cache (void)
}
static CORE_ADDR
-examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame, struct ia64_frame_cache *cache)
+examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
+ struct frame_info *this_frame,
+ struct ia64_frame_cache *cache)
{
CORE_ADDR next_pc;
CORE_ADDR last_prologue_pc = pc;
@@ -1112,7 +1114,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
we do not want to interpret the prologue and calculate the
addresses of various registers such as the return address.
We will instead treat the frame as frameless. */
- if (!next_frame ||
+ if (!this_frame ||
(sof == (cache->cfm & 0x7f) &&
sol == ((cache->cfm >> 7) & 0x7f)))
frameless = 0;
@@ -1230,9 +1232,9 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
/* Hmm... whether or not this will work will depend on
where the pc is. If it's still early in the prologue
this'll be wrong. FIXME */
- if (next_frame)
+ if (this_frame)
{
- frame_unwind_register (next_frame, sp_regnum, buf);
+ get_frame_register (this_frame, sp_regnum, buf);
saved_sp = extract_unsigned_integer (buf, 8);
}
spill_addr = saved_sp
@@ -1432,10 +1434,11 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
pc = next_pc;
}
- /* If not frameless and we aren't called by skip_prologue, then we need to calculate
- registers for the previous frame which will be needed later. */
+ /* If not frameless and we aren't called by skip_prologue, then we need
+ to calculate registers for the previous frame which will be needed
+ later. */
- if (!frameless && next_frame)
+ if (!frameless && this_frame)
{
/* Extract the size of the rotating portion of the stack
frame and the register rename base from the current
@@ -1474,7 +1477,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
}
else if (cfm_reg != 0)
{
- frame_unwind_register (next_frame, cfm_reg, buf);
+ get_frame_register (this_frame, cfm_reg, buf);
cfm = extract_unsigned_integer (buf, 8);
}
cache->prev_cfm = cfm;
@@ -1486,8 +1489,9 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
sol = (cfm >> 7) & 0x7f;
rrb_gr = (cfm >> 18) & 0x7f;
- /* The previous bof only requires subtraction of the sol (size of locals)
- due to the overlap between output and input of subsequent frames. */
+ /* The previous bof only requires subtraction of the sol (size of
+ locals) due to the overlap between output and input of
+ subsequent frames. */
bof = rse_address_add (bof, -sol);
for (i = 0, addr = bof;
@@ -1537,7 +1541,7 @@ ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
/* Normal frames. */
static struct ia64_frame_cache *
-ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
+ia64_frame_cache (struct frame_info *this_frame, void **this_cache)
{
struct ia64_frame_cache *cache;
char buf[8];
@@ -1550,19 +1554,19 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
cache = ia64_alloc_frame_cache ();
*this_cache = cache;
- frame_unwind_register (next_frame, sp_regnum, buf);
+ get_frame_register (this_frame, sp_regnum, buf);
cache->saved_sp = extract_unsigned_integer (buf, 8);
/* We always want the bsp to point to the end of frame.
This way, we can always get the beginning of frame (bof)
by subtracting frame size. */
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
cache->bsp = extract_unsigned_integer (buf, 8);
- frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
+ get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
psr = extract_unsigned_integer (buf, 8);
- frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+ get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
cfm = extract_unsigned_integer (buf, 8);
cache->sof = (cfm & 0x7f);
@@ -1571,10 +1575,10 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
cache->cfm = cfm;
- cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
+ cache->pc = get_frame_func (this_frame);
if (cache->pc != 0)
- examine_prologue (cache->pc, frame_pc_unwind (next_frame), next_frame, cache);
+ examine_prologue (cache->pc, get_frame_pc (this_frame), this_frame, cache);
cache->base = cache->saved_sp + cache->mem_stack_frame_size;
@@ -1582,11 +1586,11 @@ ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
}
static void
-ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ia64_frame_this_id (struct frame_info *this_frame, void **this_cache,
struct frame_id *this_id)
{
struct ia64_frame_cache *cache =
- ia64_frame_cache (next_frame, this_cache);
+ ia64_frame_cache (this_frame, this_cache);
/* If outermost frame, mark with null frame id. */
if (cache->base == 0)
@@ -1595,22 +1599,18 @@ ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
(*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "regular frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
+ "regular frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
paddr_nz (this_id->code_addr),
paddr_nz (this_id->stack_addr),
- paddr_nz (cache->bsp), next_frame);
+ paddr_nz (cache->bsp), this_frame);
}
-static void
-ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep)
+static struct value *
+ia64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+ int regnum)
{
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
- struct ia64_frame_cache *cache =
- ia64_frame_cache (next_frame, this_cache);
- char dummy_valp[MAX_REGISTER_SIZE];
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
char buf[8];
gdb_assert (regnum >= 0);
@@ -1618,86 +1618,63 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
if (!target_has_registers)
error (_("No registers."));
- *optimizedp = 0;
- *addrp = 0;
- *lvalp = not_lval;
- *realnump = -1;
-
- /* Rather than check each time if valuep is non-null, supply a dummy buffer
- when valuep is not supplied. */
- if (!valuep)
- valuep = dummy_valp;
-
- memset (valuep, 0, register_size (gdbarch, regnum));
-
if (regnum == gdbarch_sp_regnum (gdbarch))
- {
- /* Handle SP values for all frames but the topmost. */
- store_unsigned_integer (valuep, register_size (gdbarch, regnum),
- cache->base);
- }
+ return frame_unwind_got_constant (this_frame, regnum, cache->base);
+
else if (regnum == IA64_BSP_REGNUM)
{
- char cfm_valuep[MAX_REGISTER_SIZE];
- int cfm_optim;
- int cfm_realnum;
- enum lval_type cfm_lval;
- CORE_ADDR cfm_addr;
- CORE_ADDR bsp, prev_cfm, prev_bsp;
-
- /* We want to calculate the previous bsp as the end of the previous register stack frame.
- This corresponds to what the hardware bsp register will be if we pop the frame
- back which is why we might have been called. We know the beginning of the current
- frame is cache->bsp - cache->sof. This value in the previous frame points to
- the start of the output registers. We can calculate the end of that frame by adding
- the size of output (sof (size of frame) - sol (size of locals)). */
- ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
- &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
- prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
-
+ struct value *val;
+ CORE_ADDR prev_cfm, bsp, prev_bsp;
+
+ /* We want to calculate the previous bsp as the end of the previous
+ register stack frame. This corresponds to what the hardware bsp
+ register will be if we pop the frame back which is why we might
+ have been called. We know the beginning of the current frame is
+ cache->bsp - cache->sof. This value in the previous frame points
+ to the start of the output registers. We can calculate the end of
+ that frame by adding the size of output:
+ (sof (size of frame) - sol (size of locals)). */
+ val = ia64_frame_prev_register (this_frame, this_cache, IA64_CFM_REGNUM);
+ prev_cfm = extract_unsigned_integer (value_contents_all (val), 8);
bsp = rse_address_add (cache->bsp, -(cache->sof));
- prev_bsp = rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
+ prev_bsp =
+ rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
- store_unsigned_integer (valuep, register_size (gdbarch, regnum),
- prev_bsp);
+ return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
}
+
else if (regnum == IA64_CFM_REGNUM)
{
CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
if (addr != 0)
- {
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, valuep, register_size (gdbarch, regnum));
- }
- else if (cache->prev_cfm)
- store_unsigned_integer (valuep, register_size (gdbarch, regnum), cache->prev_cfm);
- else if (cache->frameless)
- {
- CORE_ADDR cfm = 0;
- frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
- }
+ return frame_unwind_got_memory (this_frame, regnum, addr);
+
+ if (cache->prev_cfm)
+ return frame_unwind_got_constant (this_frame, regnum, cache->prev_cfm);
+
+ if (cache->frameless)
+ return frame_unwind_got_register (this_frame, IA64_PFS_REGNUM,
+ IA64_PFS_REGNUM);
+ return frame_unwind_got_register (this_frame, regnum, 0);
}
+
else if (regnum == IA64_VFP_REGNUM)
{
/* If the function in question uses an automatic register (r32-r127)
for the frame pointer, it'll be found by ia64_find_saved_register()
above. If the function lacks one of these frame pointers, we can
still provide a value since we know the size of the frame. */
- CORE_ADDR vfp = cache->base;
- store_unsigned_integer (valuep, register_size (gdbarch, IA64_VFP_REGNUM), vfp);
+ return frame_unwind_got_constant (this_frame, regnum, cache->base);
}
+
else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
{
- char pr_valuep[MAX_REGISTER_SIZE];
- int pr_optim;
- int pr_realnum;
- enum lval_type pr_lval;
- CORE_ADDR pr_addr;
- ULONGEST prN_val;
- ia64_frame_prev_register (next_frame, this_cache, IA64_PR_REGNUM,
- &pr_optim, &pr_lval, &pr_addr, &pr_realnum, pr_valuep);
+ struct value *pr_val;
+ ULONGEST prN;
+
+ pr_val = ia64_frame_prev_register (this_frame, this_cache,
+ IA64_PR_REGNUM);
if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
{
/* Fetch predicate register rename base from current frame
@@ -1705,28 +1682,24 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
int rrb_pr = (cache->cfm >> 32) & 0x3f;
/* Adjust the register number to account for register rotation. */
- regnum = VP16_REGNUM
- + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
+ regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
}
- prN_val = extract_bit_field ((unsigned char *) pr_valuep,
- regnum - VP0_REGNUM, 1);
- store_unsigned_integer (valuep, register_size (gdbarch, regnum), prN_val);
+ prN = extract_bit_field (value_contents_all (pr_val),
+ regnum - VP0_REGNUM, 1);
+ return frame_unwind_got_constant (this_frame, regnum, prN);
}
+
else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
{
- char unat_valuep[MAX_REGISTER_SIZE];
- int unat_optim;
- int unat_realnum;
- enum lval_type unat_lval;
- CORE_ADDR unat_addr;
- ULONGEST unatN_val;
- ia64_frame_prev_register (next_frame, this_cache, IA64_UNAT_REGNUM,
- &unat_optim, &unat_lval, &unat_addr, &unat_realnum, unat_valuep);
- unatN_val = extract_bit_field ((unsigned char *) unat_valuep,
- regnum - IA64_NAT0_REGNUM, 1);
- store_unsigned_integer (valuep, register_size (gdbarch, regnum),
- unatN_val);
+ struct value *unat_val;
+ ULONGEST unatN;
+ unat_val = ia64_frame_prev_register (this_frame, this_cache,
+ IA64_UNAT_REGNUM);
+ unatN = extract_bit_field (value_contents_all (unat_val),
+ regnum - IA64_NAT0_REGNUM, 1);
+ return frame_unwind_got_constant (this_frame, regnum, unatN);
}
+
else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
{
int natval = 0;
@@ -1734,8 +1707,8 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
interested in. */
CORE_ADDR gr_addr;
- gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM
- + IA64_GR0_REGNUM];
+ gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM + IA64_GR0_REGNUM];
+
if (gr_addr != 0)
{
/* Compute address of nat collection bits. */
@@ -1743,14 +1716,15 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
CORE_ADDR bsp;
CORE_ADDR nat_collection;
int nat_bit;
+
/* If our nat collection address is bigger than bsp, we have to get
the nat collection from rnat. Otherwise, we fetch the nat
collection from the computed address. */
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
bsp = extract_unsigned_integer (buf, 8);
if (nat_addr >= bsp)
{
- frame_unwind_register (next_frame, IA64_RNAT_REGNUM, buf);
+ get_frame_register (this_frame, IA64_RNAT_REGNUM, buf);
nat_collection = extract_unsigned_integer (buf, 8);
}
else
@@ -1759,114 +1733,109 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
natval = (nat_collection >> nat_bit) & 1;
}
- store_unsigned_integer (valuep, register_size (gdbarch, regnum), natval);
+ return frame_unwind_got_constant (this_frame, regnum, natval);
}
+
else if (regnum == IA64_IP_REGNUM)
{
CORE_ADDR pc = 0;
CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
if (addr != 0)
- {
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
- pc = extract_unsigned_integer (buf, 8);
- }
+ {
+ read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
+ pc = extract_unsigned_integer (buf, 8);
+ }
else if (cache->frameless)
{
- frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
pc = extract_unsigned_integer (buf, 8);
}
pc &= ~0xf;
- store_unsigned_integer (valuep, 8, pc);
+ return frame_unwind_got_constant (this_frame, regnum, pc);
}
+
else if (regnum == IA64_PSR_REGNUM)
{
- /* We don't know how to get the complete previous PSR, but we need it for
- the slot information when we unwind the pc (pc is formed of IP register
- plus slot information from PSR). To get the previous slot information,
- we mask it off the return address. */
+ /* We don't know how to get the complete previous PSR, but we need it
+ for the slot information when we unwind the pc (pc is formed of IP
+ register plus slot information from PSR). To get the previous
+ slot information, we mask it off the return address. */
ULONGEST slot_num = 0;
- CORE_ADDR pc= 0;
+ CORE_ADDR pc = 0;
CORE_ADDR psr = 0;
CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
- frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
+ get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
psr = extract_unsigned_integer (buf, 8);
if (addr != 0)
{
- *lvalp = lval_memory;
- *addrp = addr;
read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
pc = extract_unsigned_integer (buf, 8);
}
else if (cache->frameless)
{
- CORE_ADDR pc;
- frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
pc = extract_unsigned_integer (buf, 8);
}
psr &= ~(3LL << 41);
slot_num = pc & 0x3LL;
psr |= (CORE_ADDR)slot_num << 41;
- store_unsigned_integer (valuep, 8, psr);
+ return frame_unwind_got_constant (this_frame, regnum, psr);
}
+
else if (regnum == IA64_BR0_REGNUM)
{
- CORE_ADDR br0 = 0;
CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
+
if (addr != 0)
- {
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, buf, register_size (gdbarch, IA64_BR0_REGNUM));
- br0 = extract_unsigned_integer (buf, 8);
- }
- store_unsigned_integer (valuep, 8, br0);
+ return frame_unwind_got_memory (this_frame, regnum, addr);
+
+ return frame_unwind_got_constant (this_frame, regnum, 0);
}
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
- (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
+
+ else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
+ || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
{
CORE_ADDR addr = 0;
+
if (regnum >= V32_REGNUM)
regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
addr = cache->saved_regs[regnum];
if (addr != 0)
- {
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, valuep, register_size (gdbarch, regnum));
- }
- else if (cache->frameless)
+ return frame_unwind_got_memory (this_frame, regnum, addr);
+
+ if (cache->frameless)
{
- char r_valuep[MAX_REGISTER_SIZE];
- int r_optim;
- int r_realnum;
- enum lval_type r_lval;
- CORE_ADDR r_addr;
- CORE_ADDR prev_cfm, prev_bsp, prev_bof;
- CORE_ADDR addr = 0;
+ struct value *reg_val;
+ CORE_ADDR prev_cfm, prev_bsp, prev_bof;
+
+ /* FIXME: brobecker/2008-05-01: Doesn't this seem redundant
+ with the same code above? */
if (regnum >= V32_REGNUM)
regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
- ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
- &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep);
- prev_cfm = extract_unsigned_integer (r_valuep, 8);
- ia64_frame_prev_register (next_frame, this_cache, IA64_BSP_REGNUM,
- &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep);
- prev_bsp = extract_unsigned_integer (r_valuep, 8);
+ reg_val = ia64_frame_prev_register (this_frame, this_cache,
+ IA64_CFM_REGNUM);
+ prev_cfm = extract_unsigned_integer (value_contents_all (reg_val),
+ 8);
+ reg_val = ia64_frame_prev_register (this_frame, this_cache,
+ IA64_BSP_REGNUM);
+ prev_bsp = extract_unsigned_integer (value_contents_all (reg_val),
+ 8);
prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f));
addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, valuep, register_size (gdbarch, regnum));
+ return frame_unwind_got_memory (this_frame, regnum, addr);
}
+
+ return frame_unwind_got_constant (this_frame, regnum, 0);
}
- else
+
+ else /* All other registers. */
{
CORE_ADDR addr = 0;
+
if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM)
{
/* Fetch floating point register rename base from current
@@ -1882,44 +1851,29 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
/* If we have stored a memory address, access the register. */
addr = cache->saved_regs[regnum];
if (addr != 0)
- {
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, valuep, register_size (gdbarch, regnum));
- }
+ return frame_unwind_got_memory (this_frame, regnum, addr);
/* Otherwise, punt and get the current value of the register. */
else
- frame_unwind_register (next_frame, regnum, valuep);
+ return frame_unwind_got_register (this_frame, regnum, regnum);
}
-
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "regular prev register <%d> <%s> is 0x%s\n", regnum,
- (((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"),
- paddr_nz (extract_unsigned_integer (valuep, 8)));
}
static const struct frame_unwind ia64_frame_unwind =
{
NORMAL_FRAME,
&ia64_frame_this_id,
- &ia64_frame_prev_register
+ &ia64_frame_prev_register,
+ NULL,
+ default_frame_sniffer
};
-static const struct frame_unwind *
-ia64_frame_sniffer (struct frame_info *next_frame)
-{
- return &ia64_frame_unwind;
-}
-
/* Signal trampolines. */
static void
-ia64_sigtramp_frame_init_saved_regs (struct frame_info *next_frame,
+ia64_sigtramp_frame_init_saved_regs (struct frame_info *this_frame,
struct ia64_frame_cache *cache)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
if (tdep->sigcontext_register_address)
{
@@ -1958,7 +1912,7 @@ ia64_sigtramp_frame_init_saved_regs (struct frame_info *next_frame,
}
static struct ia64_frame_cache *
-ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
+ia64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
{
struct ia64_frame_cache *cache;
CORE_ADDR addr;
@@ -1970,71 +1924,57 @@ ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
cache = ia64_alloc_frame_cache ();
- frame_unwind_register (next_frame, sp_regnum, buf);
+ get_frame_register (this_frame, sp_regnum, buf);
/* Note that frame size is hard-coded below. We cannot calculate it
via prologue examination. */
cache->base = extract_unsigned_integer (buf, 8) + 16;
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
cache->bsp = extract_unsigned_integer (buf, 8);
- frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+ get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
cache->cfm = extract_unsigned_integer (buf, 8);
cache->sof = cache->cfm & 0x7f;
- ia64_sigtramp_frame_init_saved_regs (next_frame, cache);
+ ia64_sigtramp_frame_init_saved_regs (this_frame, cache);
*this_cache = cache;
return cache;
}
static void
-ia64_sigtramp_frame_this_id (struct frame_info *next_frame,
- void **this_cache, struct frame_id *this_id)
+ia64_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache, struct frame_id *this_id)
{
struct ia64_frame_cache *cache =
- ia64_sigtramp_frame_cache (next_frame, this_cache);
+ ia64_sigtramp_frame_cache (this_frame, this_cache);
- (*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp);
+ (*this_id) = frame_id_build_special (cache->base,
+ get_frame_pc (this_frame),
+ cache->bsp);
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
+ "sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
paddr_nz (this_id->code_addr),
paddr_nz (this_id->stack_addr),
- paddr_nz (cache->bsp), next_frame);
+ paddr_nz (cache->bsp), this_frame);
}
-static void
-ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
- void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep)
+static struct value *
+ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
{
- char dummy_valp[MAX_REGISTER_SIZE];
char buf[MAX_REGISTER_SIZE];
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct ia64_frame_cache *cache =
- ia64_sigtramp_frame_cache (next_frame, this_cache);
+ ia64_sigtramp_frame_cache (this_frame, this_cache);
gdb_assert (regnum >= 0);
if (!target_has_registers)
error (_("No registers."));
- *optimizedp = 0;
- *addrp = 0;
- *lvalp = not_lval;
- *realnump = -1;
-
- /* Rather than check each time if valuep is non-null, supply a dummy buffer
- when valuep is not supplied. */
- if (!valuep)
- valuep = dummy_valp;
-
- memset (valuep, 0, register_size (gdbarch, regnum));
-
if (regnum == IA64_IP_REGNUM)
{
CORE_ADDR pc = 0;
@@ -2042,81 +1982,70 @@ ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
if (addr != 0)
{
- *lvalp = lval_memory;
- *addrp = addr;
read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
pc = extract_unsigned_integer (buf, 8);
}
pc &= ~0xf;
- store_unsigned_integer (valuep, 8, pc);
+ return frame_unwind_got_constant (this_frame, regnum, pc);
}
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
- (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
+
+ else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
+ || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
{
CORE_ADDR addr = 0;
+
if (regnum >= V32_REGNUM)
regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
addr = cache->saved_regs[regnum];
if (addr != 0)
- {
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, valuep, register_size (gdbarch, regnum));
- }
+ return frame_unwind_got_memory (this_frame, regnum, addr);
+
+ return frame_unwind_got_constant (this_frame, regnum, 0);
}
- else
+
+ else /* All other registers not listed above. */
{
- /* All other registers not listed above. */
CORE_ADDR addr = cache->saved_regs[regnum];
+
if (addr != 0)
- {
- *lvalp = lval_memory;
- *addrp = addr;
- read_memory (addr, valuep, register_size (gdbarch, regnum));
- }
- }
+ return frame_unwind_got_memory (this_frame, regnum, addr);
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "sigtramp prev register <%s> is 0x%s\n",
- (regnum < IA64_GR32_REGNUM
- || (regnum > IA64_GR127_REGNUM
- && regnum < LAST_PSEUDO_REGNUM))
- ? ia64_register_names[regnum]
- : (regnum < LAST_PSEUDO_REGNUM
- ? ia64_register_names[regnum-IA64_GR32_REGNUM+V32_REGNUM]
- : "OUT_OF_RANGE"),
- paddr_nz (extract_unsigned_integer (valuep, 8)));
+ return frame_unwind_got_constant (this_frame, regnum, 0);
+ }
}
-static const struct frame_unwind ia64_sigtramp_frame_unwind =
-{
- SIGTRAMP_FRAME,
- ia64_sigtramp_frame_this_id,
- ia64_sigtramp_frame_prev_register
-};
-
-static const struct frame_unwind *
-ia64_sigtramp_frame_sniffer (struct frame_info *next_frame)
+static int
+ia64_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
if (tdep->pc_in_sigtramp)
{
- CORE_ADDR pc = frame_pc_unwind (next_frame);
+ CORE_ADDR pc = get_frame_pc (this_frame);
if (tdep->pc_in_sigtramp (pc))
- return &ia64_sigtramp_frame_unwind;
+ return 1;
}
- return NULL;
+ return 0;
}
+
+static const struct frame_unwind ia64_sigtramp_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ ia64_sigtramp_frame_this_id,
+ ia64_sigtramp_frame_prev_register,
+ NULL,
+ ia64_sigtramp_frame_sniffer
+};
+
static CORE_ADDR
-ia64_frame_base_address (struct frame_info *next_frame, void **this_cache)
+ia64_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
- struct ia64_frame_cache *cache =
- ia64_frame_cache (next_frame, this_cache);
+ struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
return cache->base;
}
@@ -2235,7 +2164,7 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
{
int regnum = ia64_uw2gdb_regnum (uw_regnum);
unw_word_t bsp, sof, sol, cfm, psr, ip;
- struct frame_info *next_frame = arg;
+ struct frame_info *this_frame = arg;
long new_sof, old_sof;
char buf[MAX_REGISTER_SIZE];
@@ -2247,9 +2176,9 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
case UNW_REG_IP:
/* Libunwind expects to see the pc value which means the slot number
from the psr must be merged with the ip word address. */
- frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_IP_REGNUM, buf);
ip = extract_unsigned_integer (buf, 8);
- frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
+ get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
psr = extract_unsigned_integer (buf, 8);
*val = ip | ((psr >> 41) & 0x3);
break;
@@ -2258,9 +2187,9 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
/* Libunwind expects to see the beginning of the current register
frame so we must account for the fact that ptrace() will return a value
for bsp that points *after* the current register frame. */
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
bsp = extract_unsigned_integer (buf, 8);
- frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+ get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
cfm = extract_unsigned_integer (buf, 8);
sof = (cfm & 0x7f);
*val = ia64_rse_skip_regs (bsp, -sof);
@@ -2269,13 +2198,13 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
case UNW_IA64_AR_BSPSTORE:
/* Libunwind wants bspstore to be after the current register frame.
This is what ptrace() and gdb treats as the regular bsp value. */
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
*val = extract_unsigned_integer (buf, 8);
break;
default:
/* For all other registers, just unwind the value directly. */
- frame_unwind_register (next_frame, regnum, buf);
+ get_frame_register (this_frame, regnum, buf);
*val = extract_unsigned_integer (buf, 8);
break;
}
@@ -2295,12 +2224,12 @@ ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_fpreg_t *val
int write, void *arg)
{
int regnum = ia64_uw2gdb_regnum (uw_regnum);
- struct frame_info *next_frame = arg;
+ struct frame_info *this_frame = arg;
/* We never call any libunwind routines that need to write registers. */
gdb_assert (!write);
- frame_unwind_register (next_frame, regnum, (char *) val);
+ get_frame_register (this_frame, regnum, (char *) val);
return 0;
}
@@ -2662,18 +2591,15 @@ ia64_get_dyn_info_list (unw_addr_space_t as,
/* Frame interface functions for libunwind. */
static void
-ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ia64_libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
struct frame_id *this_id)
{
+ struct frame_id id;
char buf[8];
CORE_ADDR bsp;
- struct frame_id id;
- CORE_ADDR prev_ip, addr;
- int realnum, optimized;
- enum lval_type lval;
- libunwind_frame_this_id (next_frame, this_cache, &id);
+ libunwind_frame_this_id (this_frame, this_cache, &id);
if (frame_id_eq (id, null_frame_id))
{
(*this_id) = null_frame_id;
@@ -2682,50 +2608,33 @@ ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
/* We must add the bsp as the special address for frame comparison
purposes. */
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
bsp = extract_unsigned_integer (buf, 8);
- /* If the previous frame pc value is 0, then we are at the end of the stack
- and don't want to unwind past this frame. We return a null frame_id to
- indicate this. */
- libunwind_frame_prev_register (next_frame, this_cache, IA64_IP_REGNUM,
- &optimized, &lval, &addr, &realnum, buf);
- prev_ip = extract_unsigned_integer (buf, 8);
-
- if (prev_ip != 0)
- (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
- else
- (*this_id) = null_frame_id;
+ (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
+ "libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
paddr_nz (id.code_addr), paddr_nz (id.stack_addr),
- paddr_nz (bsp), next_frame);
+ paddr_nz (bsp), this_frame);
}
-static void
-ia64_libunwind_frame_prev_register (struct frame_info *next_frame,
- void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep)
+static struct value *
+ia64_libunwind_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
{
int reg = regnum;
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct value *val;
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
reg = IA64_PR_REGNUM;
else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
reg = IA64_UNAT_REGNUM;
/* Let libunwind do most of the work. */
- libunwind_frame_prev_register (next_frame, this_cache, reg,
- optimizedp, lvalp, addrp, realnump, valuep);
-
- /* No more to do if the value is not supposed to be supplied. */
- if (!valuep)
- return;
+ val = libunwind_frame_prev_register (this_frame, this_cache, reg);
if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
{
@@ -2739,61 +2648,59 @@ ia64_libunwind_frame_prev_register (struct frame_info *next_frame,
/* Fetch predicate register rename base from current frame
marker for this frame. */
- frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
+ get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
cfm = extract_unsigned_integer (buf, 8);
rrb_pr = (cfm >> 32) & 0x3f;
/* Adjust the register number to account for register rotation. */
- regnum = VP16_REGNUM
- + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
+ regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
}
- prN_val = extract_bit_field ((unsigned char *) valuep,
+ prN_val = extract_bit_field (value_contents_all (val),
regnum - VP0_REGNUM, 1);
- store_unsigned_integer (valuep, register_size (gdbarch, regnum), prN_val);
+ return frame_unwind_got_constant (this_frame, regnum, prN_val);
}
+
else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
{
ULONGEST unatN_val;
- unatN_val = extract_bit_field ((unsigned char *) valuep,
- regnum - IA64_NAT0_REGNUM, 1);
- store_unsigned_integer (valuep, register_size (gdbarch, regnum),
- unatN_val);
+ unatN_val = extract_bit_field (value_contents_all (val),
+ regnum - IA64_NAT0_REGNUM, 1);
+ return frame_unwind_got_constant (this_frame, regnum, unatN_val);
}
+
else if (regnum == IA64_BSP_REGNUM)
{
- char cfm_valuep[MAX_REGISTER_SIZE];
- int cfm_optim;
- int cfm_realnum;
- enum lval_type cfm_lval;
- CORE_ADDR cfm_addr;
- CORE_ADDR bsp, prev_cfm, prev_bsp;
-
- /* We want to calculate the previous bsp as the end of the previous register stack frame.
- This corresponds to what the hardware bsp register will be if we pop the frame
- back which is why we might have been called. We know that libunwind will pass us back
- the beginning of the current frame so we should just add sof to it. */
- prev_bsp = extract_unsigned_integer (valuep, 8);
- libunwind_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
- &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
- prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
+ struct value *cfm_val;
+ CORE_ADDR prev_bsp, prev_cfm;
+
+ /* We want to calculate the previous bsp as the end of the previous
+ register stack frame. This corresponds to what the hardware bsp
+ register will be if we pop the frame back which is why we might
+ have been called. We know that libunwind will pass us back the
+ beginning of the current frame so we should just add sof to it. */
+ prev_bsp = extract_unsigned_integer (value_contents_all (val), 8);
+ cfm_val = libunwind_frame_prev_register (this_frame, this_cache,
+ IA64_CFM_REGNUM);
+ prev_cfm = extract_unsigned_integer (value_contents_all (cfm_val), 8);
prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f));
- store_unsigned_integer (valuep, register_size (gdbarch, regnum),
- prev_bsp);
+ return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
}
+ else
+ return val;
+}
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "libunwind prev register <%s> is 0x%s\n",
- (regnum < IA64_GR32_REGNUM
- || (regnum > IA64_GR127_REGNUM
- && regnum < LAST_PSEUDO_REGNUM))
- ? ia64_register_names[regnum]
- : (regnum < LAST_PSEUDO_REGNUM
- ? ia64_register_names[regnum-IA64_GR32_REGNUM+V32_REGNUM]
- : "OUT_OF_RANGE"),
- paddr_nz (extract_unsigned_integer (valuep, 8)));
+static int
+ia64_libunwind_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
+{
+ if (libunwind_is_initialized ()
+ && libunwind_frame_sniffer (self, this_frame, this_cache))
+ return 1;
+
+ return 0;
}
static const struct frame_unwind ia64_libunwind_frame_unwind =
@@ -2802,21 +2709,13 @@ static const struct frame_unwind ia64_libunwind_frame_unwind =
ia64_libunwind_frame_this_id,
ia64_libunwind_frame_prev_register,
NULL,
- NULL,
+ ia64_libunwind_frame_sniffer,
libunwind_frame_dealloc_cache
};
-static const struct frame_unwind *
-ia64_libunwind_frame_sniffer (struct frame_info *next_frame)
-{
- if (libunwind_is_initialized () && libunwind_frame_sniffer (next_frame))
- return &ia64_libunwind_frame_unwind;
-
- return NULL;
-}
-
static void
-ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **this_cache,
+ia64_libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
+ void **this_cache,
struct frame_id *this_id)
{
char buf[8];
@@ -2824,7 +2723,7 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **thi
struct frame_id id;
CORE_ADDR prev_ip;
- libunwind_frame_this_id (next_frame, this_cache, &id);
+ libunwind_frame_this_id (this_frame, this_cache, &id);
if (frame_id_eq (id, null_frame_id))
{
(*this_id) = null_frame_id;
@@ -2833,7 +2732,7 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **thi
/* We must add the bsp as the special address for frame comparison
purposes. */
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
bsp = extract_unsigned_integer (buf, 8);
/* For a sigtramp frame, we don't make the check for previous ip being 0. */
@@ -2841,62 +2740,58 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *next_frame, void **thi
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
- "libunwind sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
+ "libunwind sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, this_frame %p\n",
paddr_nz (id.code_addr), paddr_nz (id.stack_addr),
- paddr_nz (bsp), next_frame);
+ paddr_nz (bsp), this_frame);
}
-static void
-ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *next_frame,
- void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep)
-
+static struct value *
+ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
{
- gdb_byte buf[8];
- CORE_ADDR prev_ip, addr;
- int realnum, optimized;
- enum lval_type lval;
-
+ struct value *prev_ip_val;
+ CORE_ADDR prev_ip;
/* If the previous frame pc value is 0, then we want to use the SIGCONTEXT
method of getting previous registers. */
- libunwind_frame_prev_register (next_frame, this_cache, IA64_IP_REGNUM,
- &optimized, &lval, &addr, &realnum, buf);
- prev_ip = extract_unsigned_integer (buf, 8);
+ prev_ip_val = libunwind_frame_prev_register (this_frame, this_cache,
+ IA64_IP_REGNUM);
+ prev_ip = extract_unsigned_integer (value_contents_all (prev_ip_val), 8);
if (prev_ip == 0)
{
void *tmp_cache = NULL;
- ia64_sigtramp_frame_prev_register (next_frame, &tmp_cache, regnum, optimizedp, lvalp,
- addrp, realnump, valuep);
+ return ia64_sigtramp_frame_prev_register (this_frame, &tmp_cache,
+ regnum);
}
else
- ia64_libunwind_frame_prev_register (next_frame, this_cache, regnum, optimizedp, lvalp,
- addrp, realnump, valuep);
+ return ia64_libunwind_frame_prev_register (this_frame, this_cache, regnum);
}
-static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
-{
- SIGTRAMP_FRAME,
- ia64_libunwind_sigtramp_frame_this_id,
- ia64_libunwind_sigtramp_frame_prev_register
-};
-
-static const struct frame_unwind *
-ia64_libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
+static int
+ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
{
if (libunwind_is_initialized ())
{
- if (libunwind_sigtramp_frame_sniffer (next_frame))
- return &ia64_libunwind_sigtramp_frame_unwind;
- return NULL;
+ if (libunwind_sigtramp_frame_sniffer (self, this_frame, this_cache))
+ return 1;
+ return 0;
}
else
- return ia64_sigtramp_frame_sniffer (next_frame);
+ return ia64_sigtramp_frame_sniffer (self, this_frame, this_cache);
}
+static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
+{
+ SIGTRAMP_FRAME,
+ ia64_libunwind_sigtramp_frame_this_id,
+ ia64_libunwind_sigtramp_frame_prev_register,
+ NULL,
+ ia64_libunwind_sigtramp_frame_sniffer
+};
+
/* Set of libunwind callback acccessor functions. */
static unw_accessors_t ia64_unw_accessors =
{
@@ -3514,24 +3409,24 @@ ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
}
static struct frame_id
-ia64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+ia64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
char buf[8];
CORE_ADDR sp, bsp;
- frame_unwind_register (next_frame, sp_regnum, buf);
+ get_frame_register (this_frame, sp_regnum, buf);
sp = extract_unsigned_integer (buf, 8);
- frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
+ get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
bsp = extract_unsigned_integer (buf, 8);
if (gdbarch_debug >= 1)
fprintf_unfiltered (gdb_stdlog,
"dummy frame id: code 0x%s, stack 0x%s, special 0x%s\n",
- paddr_nz (frame_pc_unwind (next_frame)),
+ paddr_nz (frame_pc_unwind (this_frame)),
paddr_nz (sp), paddr_nz (bsp));
- return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp);
+ return frame_id_build_special (sp, get_frame_pc (this_frame), bsp);
}
static CORE_ADDR
@@ -3621,17 +3516,19 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Settings for calling functions in the inferior. */
set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
set_gdbarch_frame_align (gdbarch, ia64_frame_align);
- set_gdbarch_unwind_dummy_id (gdbarch, ia64_unwind_dummy_id);
+ set_gdbarch_dummy_id (gdbarch, ia64_dummy_id);
set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc);
#ifdef HAVE_LIBUNWIND_IA64_H
- frame_unwind_append_sniffer (gdbarch, ia64_libunwind_sigtramp_frame_sniffer);
- frame_unwind_append_sniffer (gdbarch, ia64_libunwind_frame_sniffer);
+ frame_unwind_append_unwinder (gdbarch,
+ &ia64_libunwind_sigtramp_frame_unwind);
+ frame_unwind_append_unwinder (gdbarch, &ia64_libunwind_frame_unwind);
+ frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
libunwind_frame_set_descr (gdbarch, &ia64_libunwind_descr);
#else
- frame_unwind_append_sniffer (gdbarch, ia64_sigtramp_frame_sniffer);
+ frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
#endif
- frame_unwind_append_sniffer (gdbarch, ia64_frame_sniffer);
+ frame_unwind_append_unwinder (gdbarch, &ia64_frame_unwind);
frame_base_set_default (gdbarch, &ia64_frame_base);
/* Settings that should be unnecessary. */
diff --git a/gdb/libunwind-frame.c b/gdb/libunwind-frame.c
index 223c3c0..d580b51 100644
--- a/gdb/libunwind-frame.c
+++ b/gdb/libunwind-frame.c
@@ -66,9 +66,9 @@ struct libunwind_frame_cache
unw_addr_space_t as;
};
-/* We need to qualify the function names with a platform-specific prefix to match
- the names used by the libunwind library. The UNW_OBJ macro is provided by the
- libunwind.h header file. */
+/* We need to qualify the function names with a platform-specific prefix
+ to match the names used by the libunwind library. The UNW_OBJ macro is
+ provided by the libunwind.h header file. */
#define STRINGIFY2(name) #name
#define STRINGIFY(name) STRINGIFY2(name)
@@ -128,7 +128,7 @@ libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *desc
}
static struct libunwind_frame_cache *
-libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
+libunwind_frame_cache (struct frame_info *this_frame, void **this_cache)
{
unw_accessors_t *acc;
unw_addr_space_t as;
@@ -136,7 +136,7 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
unw_regnum_t uw_sp_regnum;
struct libunwind_frame_cache *cache;
struct libunwind_descr *descr;
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
int i, ret;
if (*this_cache)
@@ -148,20 +148,23 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
/* We can assume we are unwinding a normal frame. Even if this is
for a signal trampoline, ia64 signal "trampolines" use a normal
subroutine call to start the signal handler. */
- cache->func_addr = frame_func_unwind (next_frame, NORMAL_FRAME);
+ cache->func_addr = get_frame_func (this_frame);
if (cache->func_addr == 0
- && frame_relative_level (next_frame) > 0
- && get_frame_type (next_frame) != SIGTRAMP_FRAME)
+ && get_next_frame (this_frame)
+ && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME)
return NULL;
- /* Get a libunwind cursor to the previous frame. We do this by initializing
- a cursor. Libunwind treats a new cursor as the top of stack and will get
- the current register set via the libunwind register accessor. Now, we
- provide the platform-specific accessors and we set up the register accessor to use
- the frame register unwinding interfaces so that we properly get the registers for
- the current frame rather than the top. We then use the unw_step function to
- move the libunwind cursor back one frame. We can later use this cursor to find previous
- registers via the unw_get_reg interface which will invoke libunwind's special logic. */
+ /* Get a libunwind cursor to the previous frame.
+
+ We do this by initializing a cursor. Libunwind treats a new cursor
+ as the top of stack and will get the current register set via the
+ libunwind register accessor. Now, we provide the platform-specific
+ accessors and we set up the register accessor to use the frame
+ register unwinding interfaces so that we properly get the registers
+ for the current frame rather than the top. We then use the unw_step
+ function to move the libunwind cursor back one frame. We can later
+ use this cursor to find previous registers via the unw_get_reg
+ interface which will invoke libunwind's special logic. */
descr = libunwind_descr (gdbarch);
acc = descr->accessors;
as = unw_create_addr_space_p (acc,
@@ -170,7 +173,7 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
? __BIG_ENDIAN
: __LITTLE_ENDIAN);
- unw_init_remote_p (&cache->cursor, as, next_frame);
+ unw_init_remote_p (&cache->cursor, as, this_frame);
if (unw_step_p (&cache->cursor) < 0)
{
unw_destroy_addr_space_p (as);
@@ -213,26 +216,28 @@ static const struct frame_unwind libunwind_frame_unwind =
libunwind_frame_this_id,
libunwind_frame_prev_register,
NULL,
- NULL,
- libunwind_frame_dealloc_cache
+ libunwind_frame_sniffer,
+ libunwind_frame_dealloc_cache,
};
/* Verify if there is sufficient libunwind information for the frame to use
libunwind frame unwinding. */
-const struct frame_unwind *
-libunwind_frame_sniffer (struct frame_info *next_frame)
+int
+libunwind_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame, void **this_cache)
{
unw_cursor_t cursor;
unw_accessors_t *acc;
unw_addr_space_t as;
struct libunwind_descr *descr;
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
int i, ret;
- /* To test for libunwind unwind support, initialize a cursor to the current frame and try to back
- up. We use this same method when setting up the frame cache (see libunwind_frame_cache()).
- If libunwind returns success for this operation, it means that it has found sufficient
- libunwind unwinding information to do so. */
+ /* To test for libunwind unwind support, initialize a cursor to
+ the current frame and try to back up. We use this same method
+ when setting up the frame cache (see libunwind_frame_cache()).
+ If libunwind returns success for this operation, it means that
+ it has found sufficient libunwind unwinding information to do so. */
descr = libunwind_descr (gdbarch);
acc = descr->accessors;
@@ -242,12 +247,12 @@ libunwind_frame_sniffer (struct frame_info *next_frame)
? __BIG_ENDIAN
: __LITTLE_ENDIAN);
- ret = unw_init_remote_p (&cursor, as, next_frame);
+ ret = unw_init_remote_p (&cursor, as, this_frame);
if (ret < 0)
{
unw_destroy_addr_space_p (as);
- return NULL;
+ return 0;
}
@@ -258,17 +263,17 @@ libunwind_frame_sniffer (struct frame_info *next_frame)
unw_destroy_addr_space_p (as);
if (ret < 0)
- return NULL;
+ return 0;
- return &libunwind_frame_unwind;
+ return 1;
}
void
-libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
- struct frame_id *this_id)
+libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
+ struct frame_id *this_id)
{
struct libunwind_frame_cache *cache =
- libunwind_frame_cache (next_frame, this_cache);
+ libunwind_frame_cache (this_frame, this_cache);
if (cache != NULL)
(*this_id) = frame_id_build (cache->base, cache->func_addr);
@@ -276,15 +281,13 @@ libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
(*this_id) = null_frame_id;
}
-void
-libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep)
+struct value *
+libunwind_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
{
struct libunwind_frame_cache *cache =
- libunwind_frame_cache (next_frame, this_cache);
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ libunwind_frame_cache (this_frame, this_cache);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
void *ptr;
unw_cursor_t *c;
@@ -294,12 +297,13 @@ libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
unw_fpreg_t fpval;
unw_regnum_t uw_regnum;
struct libunwind_descr *descr;
+ struct value *val = NULL;
if (cache == NULL)
- return;
+ return frame_unwind_got_constant (this_frame, regnum, 0);
/* Convert from gdb register number to libunwind register number. */
- descr = libunwind_descr (get_frame_arch (next_frame));
+ descr = libunwind_descr (get_frame_arch (this_frame));
uw_regnum = descr->gdb2uw (regnum);
gdb_assert (regnum >= 0);
@@ -307,63 +311,55 @@ libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
if (!target_has_registers)
error (_("No registers."));
- *optimizedp = 0;
- *addrp = 0;
- *lvalp = not_lval;
- *realnump = -1;
-
- if (valuep)
- memset (valuep, 0, register_size (gdbarch, regnum));
-
if (uw_regnum < 0)
- return;
-
- /* To get the previous register, we use the libunwind register APIs with
- the cursor we have already pushed back to the previous frame. */
-
- if (descr->is_fpreg (uw_regnum))
- {
- ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
- ptr = &fpval;
- }
- else
- {
- ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
- ptr = &intval;
- }
-
- if (ret < 0)
- return;
-
- if (valuep)
- memcpy (valuep, ptr, register_size (gdbarch, regnum));
+ return frame_unwind_got_constant (this_frame, regnum, 0);
if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
- return;
+ return frame_unwind_got_constant (this_frame, regnum, 0);
switch (sl.type)
{
- case UNW_SLT_NONE:
- *optimizedp = 1;
- break;
-
case UNW_SLT_MEMORY:
- *lvalp = lval_memory;
- *addrp = sl.u.addr;
+ val = frame_unwind_got_memory (this_frame, regnum, sl.u.addr);
break;
case UNW_SLT_REG:
- *lvalp = lval_register;
- *realnump = regnum;
+ val = frame_unwind_got_register (this_frame, regnum,
+ descr->uw2gdb (sl.u.regnum));
break;
+ case UNW_SLT_NONE:
+ {
+ /* The register is not stored at a specific memory address nor
+ inside another register. So use libunwind to fetch the register
+ value for us, and create a constant value with the result. */
+ if (descr->is_fpreg (uw_regnum))
+ {
+ ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
+ if (ret < 0)
+ return frame_unwind_got_constant (this_frame, regnum, 0);
+ val = frame_unwind_got_bytes (this_frame, regnum,
+ (gdb_byte *) &fpval);
+ }
+ else
+ {
+ ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
+ if (ret < 0)
+ return frame_unwind_got_constant (this_frame, regnum, 0);
+ val = frame_unwind_got_constant (this_frame, regnum, intval);
+ }
+ set_value_optimized_out (val, 1);
+ break;
+ }
}
+
+ return val;
}
CORE_ADDR
-libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache)
+libunwind_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
struct libunwind_frame_cache *cache =
- libunwind_frame_cache (next_frame, this_cache);
+ libunwind_frame_cache (this_frame, this_cache);
if (cache == NULL)
return (CORE_ADDR)NULL;
@@ -381,14 +377,16 @@ libunwind_search_unwind_table (void *as, long ip, void *di,
}
/* Verify if we are in a sigtramp frame and we can use libunwind to unwind. */
-const struct frame_unwind *
-libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
+int
+libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache)
{
unw_cursor_t cursor;
unw_accessors_t *acc;
unw_addr_space_t as;
struct libunwind_descr *descr;
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
int i, ret;
/* To test for libunwind unwind support, initialize a cursor to the
@@ -406,21 +404,21 @@ libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
? __BIG_ENDIAN
: __LITTLE_ENDIAN);
- ret = unw_init_remote_p (&cursor, as, next_frame);
+ ret = unw_init_remote_p (&cursor, as, this_frame);
if (ret < 0)
{
unw_destroy_addr_space_p (as);
- return NULL;
+ return 0;
}
/* Check to see if we are in a signal frame. */
ret = unw_is_signal_frame_p (&cursor);
unw_destroy_addr_space_p (as);
if (ret > 0)
- return &libunwind_frame_unwind;
+ return 1;
- return NULL;
+ return 0;
}
/* The following routine is for accessing special registers of the top frame.
diff --git a/gdb/libunwind-frame.h b/gdb/libunwind-frame.h
index b6b1159..876b92b 100644
--- a/gdb/libunwind-frame.h
+++ b/gdb/libunwind-frame.h
@@ -40,19 +40,23 @@ struct libunwind_descr
void *special_accessors;
};
-const struct frame_unwind *libunwind_frame_sniffer (struct frame_info *next_frame);
-const struct frame_unwind *libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame);
+int libunwind_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache);
+
+int libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_cache);
void libunwind_frame_set_descr (struct gdbarch *arch, struct libunwind_descr *descr);
-void libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
+void libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
struct frame_id *this_id);
-void libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep);
+struct value *libunwind_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum);
void libunwind_frame_dealloc_cache (struct frame_info *self, void *cache);
-CORE_ADDR libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache);
+CORE_ADDR libunwind_frame_base_address (struct frame_info *this_frame,
+ void **this_cache);
int libunwind_is_initialized (void);