1/1
gdb stack backtrace works
by Unknown on Feb 6, 2004 |
Not available! | ||
Just committed the changes. To use it, gcc needs a little change too.
These lines should go into config/or32/or32.c:or32_output_function_prologue() and or32_output_function_epilogue(). fp_save_area = frame_pointer_needed ? 4 : 0; lr_save_area = (fp_save_area || regs_ever_live[OR1K_LINK_REG]) ? 4 : 0; Before, the link register wasn't saved in leaf functions. I found no suitable variable to make lr saving dependant on, instead I chose to save lr whenever fp is saved. I'll put that into CVS as soon as we have our new gcc version online. Heiko |
gdb stack backtrace works
by Unknown on Feb 6, 2004 |
Not available! | ||
* Heiko Panther (heiko.panther@web.de) wrote:
Just committed the changes. To use it, gcc needs a little change too.
These lines should go into config/or32/or32.c:or32_output_function_prologue() and or32_output_function_epilogue(). fp_save_area = frame_pointer_needed ? 4 : 0; lr_save_area = (fp_save_area || regs_ever_live[OR1K_LINK_REG]) ? 4 : 0; Before, the link register wasn't saved in leaf functions. I found no suitable variable to make lr saving dependant on, instead I chose to save lr whenever fp is saved. I'll put that into CVS as soon as we have our new gcc version online. here we'll have one more small problem. in linux r2 is currently used for 'current' pointer (pointer to current task). this means that linux can not be compiled with frame pointer. i'm going to move it to one of other CALL_USED registers. since there is an option to have or1k processor with only 16 registers i really only have 2 options: r13 and r15. any preferences ? regards, p. |
gdb stack backtrace works
by Unknown on Feb 6, 2004 |
Not available! | ||
What exactly do you mean when you say that, "gdb stack backtrace works".
From my experience, gdb backtraces have worked for almost a year, but maybe my toolchain is different from what everyone else is using. I'm using gdb 5.3 w/ gcc 3.1. Or is there a specific backtrace bug that you're referring to ? Heiko Panther wrote:
Just committed the changes. To use it, gcc needs a little change too.
These lines should go into config/or32/or32.c:or32_output_function_prologue() and or32_output_function_epilogue(). fp_save_area = frame_pointer_needed ? 4 : 0; lr_save_area = (fp_save_area || regs_ever_live[OR1K_LINK_REG]) ? 4 : 0; Before, the link register wasn't saved in leaf functions. I found no suitable variable to make lr saving dependant on, instead I chose to save lr whenever fp is saved. In the case of a leaf function, gdb should recover the value of the link register from the gdb stub, without requiring it to be saved on the stack, in gdb's or1k_init_saved_regs(). -Scott |
gdb stack backtrace works
by Unknown on Feb 9, 2004 |
Not available! | ||
What exactly do you mean when you say that, "gdb stack backtrace works".
The regular "bt". From my experience, gdb backtraces have worked for almost a year, but maybe my toolchain is different from what everyone else is using. I'm using gdb 5.3 w/ gcc 3.1.
In the case of a leaf function, gdb should recover the value of the link
register from the gdb stub, without requiring it to be saved on the stack, in gdb's or1k_init_saved_regs(). I use the "current" gcc-3.2.3 with UC target config. But I checked, the 3.2.3 with OC target config didn't save the link register either. Stack backtraces never worked for me before. As I interpret the source, or1k_init_saved_regs does just that, init the regs which were saved to the stack (by analyzing where in the stack frame they are, which happens in or1k_skip_prologue). So if LR is not on the stack, it won't get initialized there. I agree with you that it should be possible for gdb to just read r9 from the register file for the topmost frame, in case it wasn't used in the frame and is thus only available from the stack. It still looks to me as if gdb always gets the link register from the stack. I have no doubt that stack backtrace worked for you, yet I really don't know why it didn't work for me then. Heiko |
gdb stack backtrace works
by Unknown on Feb 9, 2004 |
Not available! | ||
Heiko Panther wrote:
As I interpret the source, or1k_init_saved_regs does just that, init
If you look at line 979 of or1k-tdep.c, you can see that the PC for a
stack frame is initialized from the LR when the LR has not been saved on
the stack in the function prologue:
http://www.opencores.org/cvsweb.shtml/or1k/gdb-5.3/gdb/or1k-tdep.c?annotate=1.3
Since it's the PC that's required to accomplish a stack backtrace, I
think this should work OK without forcing the compiler to always save LR
on the stack.
-Scott
the regs which were saved to the stack (by analyzing where in the stack frame they are, which happens in or1k_skip_prologue). So if LR is not on the stack, it won't get initialized there. |
gdb stack backtrace works
by Unknown on Feb 9, 2004 |
Not available! | ||
If you look at line 979 of or1k-tdep.c, you can see that the PC for a
stack frame is initialized from the LR when the LR has not been saved on
the stack in the function prologue:
http://www.opencores.org/cvsweb.shtml/or1k/gdb-5.3/gdb/or1k-tdep.c?annotate=1.3
Since it's the PC that's required to accomplish a stack backtrace, I
think this should work OK without forcing the compiler to always save LR
on the stack.
Well, you're right. The real bug were some missing casts in statements like this (fictional one): CORE_ADDR r = read_register (regno); Since read_register returns an ULONGEST a cast would be in place. Without cast, it will still work OK on little endian, but not on big endian. Now I get a backtrace to the first non-leaf function, which is either on frame #0 or frame #1. And this is because or1k_frame_chain looks for the stored r2 at (function_start + 4): unsigned long insn = read_memory_integer(func_pc+4,4); And if there is a link register stored, it is stored first, then the frame pointer, like this: f000c7f8: 9c 21 ff f0 l.addi r1,r1,0xfffffff0 f000c7fc: d4 01 48 00 l.sw 0x0(r1),r9 f000c800: d4 01 10 04 l.sw 0x4(r1),r2 f000c804: 9c 41 00 10 l.addi r2,r1,0x10 So or1k_frame_chain fails to get the previous frame, because the second insn does not match what it is looking for. Why does it work for you? Heiko |
1/1