提交 f8264667 编写于 作者: M Matt Fleming 提交者: Paul Mundt

sh: Delete DWARF_ARCH_UNWIND_OFFSET

Trying to figure out the best value for DWARF_ARCH_UNWIND_OFFSET is
tricky at best. Various things can change the size (and offset from the
beginning of the function) of the prologue. Notably, turning on ftrace
adds calls to mcount at the beginning of functions, thereby pushing the
prologue further into the function.

So replace DWARF_ARCH_UNWIND_OFFSET with some code that continues to
execute CFA instructions until the value of return address register is
defined. This is safe to do because we know that the return address must
have been pushed onto the frame before our first function call; we just
can't figure out where at compile-time.
Signed-off-by: NMatt Fleming <matt@console-pimps.org>
Signed-off-by: NPaul Mundt <lethal@linux-sh.org>
上级 bf43a160
...@@ -193,11 +193,6 @@ ...@@ -193,11 +193,6 @@
*/ */
#define DWARF_ARCH_RA_REG 17 #define DWARF_ARCH_RA_REG 17
/*
* At what offset into dwarf_unwind_stack() is DWARF_ARCH_RA_REG setup?
*/
#define DWARF_ARCH_UNWIND_OFFSET 0x20
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/* /*
* Read either the frame pointer (r14) or the stack pointer (r15). * Read either the frame pointer (r14) or the stack pointer (r15).
......
...@@ -330,6 +330,7 @@ struct dwarf_fde *dwarf_lookup_fde(unsigned long pc) ...@@ -330,6 +330,7 @@ struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
* @fde: the FDE for this function * @fde: the FDE for this function
* @frame: the instructions calculate the CFA for this frame * @frame: the instructions calculate the CFA for this frame
* @pc: the program counter of the address we're interested in * @pc: the program counter of the address we're interested in
* @define_ra: keep executing insns until the return addr reg is defined?
* *
* Execute the Call Frame instruction sequence starting at * Execute the Call Frame instruction sequence starting at
* @insn_start and ending at @insn_end. The instructions describe * @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,17 +342,36 @@ static int dwarf_cfa_execute_insns(unsigned char *insn_start,
struct dwarf_cie *cie, struct dwarf_cie *cie,
struct dwarf_fde *fde, struct dwarf_fde *fde,
struct dwarf_frame *frame, struct dwarf_frame *frame,
unsigned long pc) unsigned long pc,
bool define_ra)
{ {
unsigned char insn; unsigned char insn;
unsigned char *current_insn; unsigned char *current_insn;
unsigned int count, delta, reg, expr_len, offset; unsigned int count, delta, reg, expr_len, offset;
bool seen_ra_reg;
current_insn = insn_start; current_insn = insn_start;
while (current_insn < insn_end && frame->pc <= pc) { /*
* If we're executing instructions for the dwarf_unwind_stack()
* FDE we need to keep executing instructions until the value of
* DWARF_ARCH_RA_REG is defined. See the comment in
* dwarf_unwind_stack() for more details.
*/
if (define_ra)
seen_ra_reg = false;
else
seen_ra_reg = true;
while (current_insn < insn_end && (frame->pc <= pc || !seen_ra_reg) ) {
insn = __raw_readb(current_insn++); insn = __raw_readb(current_insn++);
if (!seen_ra_reg) {
if (frame->num_regs >= DWARF_ARCH_RA_REG &&
frame->regs[DWARF_ARCH_RA_REG].flags)
seen_ra_reg = true;
}
/* /*
* Firstly, handle the opcodes that embed their operands * Firstly, handle the opcodes that embed their operands
* in the instructions. * in the instructions.
...@@ -490,20 +510,25 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, ...@@ -490,20 +510,25 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
struct dwarf_fde *fde; struct dwarf_fde *fde;
unsigned long addr; unsigned long addr;
int i, offset; int i, offset;
bool define_ra = false;
/* /*
* If this is the first invocation of this recursive function we * If this is the first invocation of this recursive function we
* need get the contents of a physical register to get the CFA * need get the contents of a physical register to get the CFA
* in order to begin the virtual unwinding of the stack. * in order to begin the virtual unwinding of the stack.
* *
* The constant DWARF_ARCH_UNWIND_OFFSET is added to the address of * Setting "define_ra" to true indictates that we want
* this function because the return address register * dwarf_cfa_execute_insns() to continue executing instructions
* (DWARF_ARCH_RA_REG) will probably not be initialised until a * until we know how to calculate the value of DWARF_ARCH_RA_REG
* few instructions into the prologue. * (which we need in order to kick off the whole unwinding
* process).
*
* NOTE: the return address is guaranteed to be setup by the
* time this function makes its first function call.
*/ */
if (!pc && !prev) { if (!pc && !prev) {
pc = (unsigned long)&dwarf_unwind_stack; pc = (unsigned long)&dwarf_unwind_stack;
pc += DWARF_ARCH_UNWIND_OFFSET; define_ra = true;
} }
frame = kzalloc(sizeof(*frame), GFP_KERNEL); frame = kzalloc(sizeof(*frame), GFP_KERNEL);
...@@ -539,11 +564,12 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, ...@@ -539,11 +564,12 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc,
/* CIE initial instructions */ /* CIE initial instructions */
dwarf_cfa_execute_insns(cie->initial_instructions, dwarf_cfa_execute_insns(cie->initial_instructions,
cie->instructions_end, cie, fde, frame, pc); cie->instructions_end, cie, fde,
frame, pc, false);
/* FDE instructions */ /* FDE instructions */
dwarf_cfa_execute_insns(fde->instructions, fde->end, cie, dwarf_cfa_execute_insns(fde->instructions, fde->end, cie,
fde, frame, pc); fde, frame, pc, define_ra);
/* Calculate the CFA */ /* Calculate the CFA */
switch (frame->flags) { switch (frame->flags) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册