From: Joel Brobecker Date: Tue, 6 May 2008 18:37:46 +0000 (+0000) Subject: * frame-unwind.c (frame_unwind_got_bytes): New function. X-Git-Tag: msnyder-reverse-20080609-branchpoint~286 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=15c1e57ffbcb27cd275429e689f509026bda698b;p=external%2Fbinutils.git * 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. --- 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 + + * 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 * 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);