aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/dwarf.c
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-08-15 18:10:57 -0400
committerMatt Fleming <matt@console-pimps.org>2009-08-16 07:48:53 -0400
commitb955873bf530ee4b80e6c8b734521ad07cbaed7e (patch)
tree44367dd882fc8851f32285ddcdcb3f62892df99d /arch/sh/kernel/dwarf.c
parent38f9ddf44150c1a213b41726384d055f7c35ec4f (diff)
sh: Try again at getting the initial return address for an unwind
The previous hack for calculating the return address for the first frame we unwind (dwarf_unwinder_dump) didn't always work. The problem was that it assumed once it read the rule for calculating the return address, there would be no new rules for calculating it. This isn't true because the way in which the CFA is calculated can change as you progress through a function and the return address is figured out using the CFA. Therefore, the way to calculate the return address can change. So, instead of using some offset from the beginning of dwarf_unwind_stack which is just a flakey approach, and instead of executing instructions from the FDE until the return address is setup, we now figure out the pc in dwarf_unwind_stack() just before we call dwarf_cfa_execute_insns(). Signed-off-by: Matt Fleming <matt@console-pimps.org>
Diffstat (limited to 'arch/sh/kernel/dwarf.c')
-rw-r--r--arch/sh/kernel/dwarf.c41
1 files changed, 6 insertions, 35 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index c6c5764a8ab1..44e674ed2871 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -330,7 +330,6 @@ struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
330 * @fde: the FDE for this function 330 * @fde: the FDE for this function
331 * @frame: the instructions calculate the CFA for this frame 331 * @frame: the instructions calculate the CFA for this frame
332 * @pc: the program counter of the address we're interested in 332 * @pc: the program counter of the address we're interested in
333 * @define_ra: keep executing insns until the return addr reg is defined?
334 * 333 *
335 * Execute the Call Frame instruction sequence starting at 334 * Execute the Call Frame instruction sequence starting at
336 * @insn_start and ending at @insn_end. The instructions describe 335 * @insn_start and ending at @insn_end. The instructions describe
@@ -342,36 +341,17 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
342 struct dwarf_cie *cie, 341 struct dwarf_cie *cie,
343 struct dwarf_fde *fde, 342 struct dwarf_fde *fde,
344 struct dwarf_frame *frame, 343 struct dwarf_frame *frame,
345 unsigned long pc, 344 unsigned long pc)
346 bool define_ra)
347{ 345{
348 unsigned char insn; 346 unsigned char insn;
349 unsigned char *current_insn; 347 unsigned char *current_insn;
350 unsigned int count, delta, reg, expr_len, offset; 348 unsigned int count, delta, reg, expr_len, offset;
351 bool seen_ra_reg;
352 349
353 current_insn = insn_start; 350 current_insn = insn_start;
354 351
355 /* 352 while (current_insn < insn_end && frame->pc <= pc) {
356 * If we're executing instructions for the dwarf_unwind_stack()
357 * FDE we need to keep executing instructions until the value of
358 * DWARF_ARCH_RA_REG is defined. See the comment in
359 * dwarf_unwind_stack() for more details.
360 */
361 if (define_ra)
362 seen_ra_reg = false;
363 else
364 seen_ra_reg = true;
365
366 while (current_insn < insn_end && (frame->pc <= pc || !seen_ra_reg) ) {
367 insn = __raw_readb(current_insn++); 353 insn = __raw_readb(current_insn++);
368 354
369 if (!seen_ra_reg) {
370 if (frame->num_regs >= DWARF_ARCH_RA_REG &&
371 frame->regs[DWARF_ARCH_RA_REG].flags)
372 seen_ra_reg = true;
373 }
374
375 /* 355 /*
376 * Firstly, handle the opcodes that embed their operands 356 * Firstly, handle the opcodes that embed their operands
377 * in the instructions. 357 * in the instructions.
@@ -511,26 +491,17 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
511 struct dwarf_fde *fde; 491 struct dwarf_fde *fde;
512 unsigned long addr; 492 unsigned long addr;
513 int i, offset; 493 int i, offset;
514 bool define_ra = false;
515 494
516 /* 495 /*
517 * If this is the first invocation of this recursive function we 496 * If this is the first invocation of this recursive function we
518 * need get the contents of a physical register to get the CFA 497 * need get the contents of a physical register to get the CFA
519 * in order to begin the virtual unwinding of the stack. 498 * in order to begin the virtual unwinding of the stack.
520 * 499 *
521 * Setting "define_ra" to true indictates that we want
522 * dwarf_cfa_execute_insns() to continue executing instructions
523 * until we know how to calculate the value of DWARF_ARCH_RA_REG
524 * (which we need in order to kick off the whole unwinding
525 * process).
526 *
527 * NOTE: the return address is guaranteed to be setup by the 500 * NOTE: the return address is guaranteed to be setup by the
528 * time this function makes its first function call. 501 * time this function makes its first function call.
529 */ 502 */
530 if (!pc && !prev) { 503 if (!pc && !prev)
531 pc = (unsigned long)&dwarf_unwind_stack; 504 pc = (unsigned long)current_text_addr();
532 define_ra = true;
533 }
534 505
535 frame = kzalloc(sizeof(*frame), GFP_ATOMIC); 506 frame = kzalloc(sizeof(*frame), GFP_ATOMIC);
536 if (!frame) 507 if (!frame)
@@ -566,11 +537,11 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
566 /* CIE initial instructions */ 537 /* CIE initial instructions */
567 dwarf_cfa_execute_insns(cie->initial_instructions, 538 dwarf_cfa_execute_insns(cie->initial_instructions,
568 cie->instructions_end, cie, fde, 539 cie->instructions_end, cie, fde,
569 frame, pc, false); 540 frame, pc);
570 541
571 /* FDE instructions */ 542 /* FDE instructions */
572 dwarf_cfa_execute_insns(fde->instructions, fde->end, cie, 543 dwarf_cfa_execute_insns(fde->instructions, fde->end, cie,
573 fde, frame, pc, define_ra); 544 fde, frame, pc);
574 545
575 /* Calculate the CFA */ 546 /* Calculate the CFA */
576 switch (frame->flags) { 547 switch (frame->flags) {