diff options
Diffstat (limited to 'arch/sh/kernel/dwarf.c')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 49d039f19426..83f3cc92549f 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c | |||
@@ -330,6 +330,7 @@ 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? | ||
333 | * | 334 | * |
334 | * Execute the Call Frame instruction sequence starting at | 335 | * Execute the Call Frame instruction sequence starting at |
335 | * @insn_start and ending at @insn_end. The instructions describe | 336 | * @insn_start and ending at @insn_end. The instructions describe |
@@ -341,17 +342,36 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start, | |||
341 | struct dwarf_cie *cie, | 342 | struct dwarf_cie *cie, |
342 | struct dwarf_fde *fde, | 343 | struct dwarf_fde *fde, |
343 | struct dwarf_frame *frame, | 344 | struct dwarf_frame *frame, |
344 | unsigned long pc) | 345 | unsigned long pc, |
346 | bool define_ra) | ||
345 | { | 347 | { |
346 | unsigned char insn; | 348 | unsigned char insn; |
347 | unsigned char *current_insn; | 349 | unsigned char *current_insn; |
348 | unsigned int count, delta, reg, expr_len, offset; | 350 | unsigned int count, delta, reg, expr_len, offset; |
351 | bool seen_ra_reg; | ||
349 | 352 | ||
350 | current_insn = insn_start; | 353 | current_insn = insn_start; |
351 | 354 | ||
352 | while (current_insn < insn_end && frame->pc <= pc) { | 355 | /* |
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) ) { | ||
353 | insn = __raw_readb(current_insn++); | 367 | insn = __raw_readb(current_insn++); |
354 | 368 | ||
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 | |||
355 | /* | 375 | /* |
356 | * Firstly, handle the opcodes that embed their operands | 376 | * Firstly, handle the opcodes that embed their operands |
357 | * in the instructions. | 377 | * in the instructions. |
@@ -490,20 +510,25 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, | |||
490 | struct dwarf_fde *fde; | 510 | struct dwarf_fde *fde; |
491 | unsigned long addr; | 511 | unsigned long addr; |
492 | int i, offset; | 512 | int i, offset; |
513 | bool define_ra = false; | ||
493 | 514 | ||
494 | /* | 515 | /* |
495 | * If this is the first invocation of this recursive function we | 516 | * If this is the first invocation of this recursive function we |
496 | * need get the contents of a physical register to get the CFA | 517 | * need get the contents of a physical register to get the CFA |
497 | * in order to begin the virtual unwinding of the stack. | 518 | * in order to begin the virtual unwinding of the stack. |
498 | * | 519 | * |
499 | * The constant DWARF_ARCH_UNWIND_OFFSET is added to the address of | 520 | * Setting "define_ra" to true indictates that we want |
500 | * this function because the return address register | 521 | * dwarf_cfa_execute_insns() to continue executing instructions |
501 | * (DWARF_ARCH_RA_REG) will probably not be initialised until a | 522 | * until we know how to calculate the value of DWARF_ARCH_RA_REG |
502 | * few instructions into the prologue. | 523 | * (which we need in order to kick off the whole unwinding |
524 | * process). | ||
525 | * | ||
526 | * NOTE: the return address is guaranteed to be setup by the | ||
527 | * time this function makes its first function call. | ||
503 | */ | 528 | */ |
504 | if (!pc && !prev) { | 529 | if (!pc && !prev) { |
505 | pc = (unsigned long)&dwarf_unwind_stack; | 530 | pc = (unsigned long)&dwarf_unwind_stack; |
506 | pc += DWARF_ARCH_UNWIND_OFFSET; | 531 | define_ra = true; |
507 | } | 532 | } |
508 | 533 | ||
509 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); | 534 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); |
@@ -539,11 +564,12 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, | |||
539 | 564 | ||
540 | /* CIE initial instructions */ | 565 | /* CIE initial instructions */ |
541 | dwarf_cfa_execute_insns(cie->initial_instructions, | 566 | dwarf_cfa_execute_insns(cie->initial_instructions, |
542 | cie->instructions_end, cie, fde, frame, pc); | 567 | cie->instructions_end, cie, fde, |
568 | frame, pc, false); | ||
543 | 569 | ||
544 | /* FDE instructions */ | 570 | /* FDE instructions */ |
545 | dwarf_cfa_execute_insns(fde->instructions, fde->end, cie, | 571 | dwarf_cfa_execute_insns(fde->instructions, fde->end, cie, |
546 | fde, frame, pc); | 572 | fde, frame, pc, define_ra); |
547 | 573 | ||
548 | /* Calculate the CFA */ | 574 | /* Calculate the CFA */ |
549 | switch (frame->flags) { | 575 | switch (frame->flags) { |