diff options
author | Jim Keniston <jkenisto@us.ibm.com> | 2009-04-20 16:39:26 -0700 |
---|---|---|
committer | Jim Keniston <jkenisto@us.ibm.com> | 2009-04-20 16:39:26 -0700 |
commit | 436e5bf634020bcb9f98967891508db21f9e6cbd (patch) | |
tree | aa0b83ff4089ab4f15be10d7ffeb94eea2255960 /runtime/uprobes2/uprobes_x86.h | |
parent | d1b6c2866b35575219fb36fa2307c9f87e876750 (diff) | |
download | systemtap-steved-436e5bf634020bcb9f98967891508db21f9e6cbd.tar.gz systemtap-steved-436e5bf634020bcb9f98967891508db21f9e6cbd.tar.xz systemtap-steved-436e5bf634020bcb9f98967891508db21f9e6cbd.zip |
PR10078: uretprobes on functions returning structs/unions
arch_predict_sp_at_ret() for x86_32 now accommodates ret $4.
Added bz10078 regression test.
Diffstat (limited to 'runtime/uprobes2/uprobes_x86.h')
-rw-r--r-- | runtime/uprobes2/uprobes_x86.h | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/runtime/uprobes2/uprobes_x86.h b/runtime/uprobes2/uprobes_x86.h index ca3f4873..a07fa0d3 100644 --- a/runtime/uprobes2/uprobes_x86.h +++ b/runtime/uprobes2/uprobes_x86.h @@ -93,11 +93,22 @@ static inline unsigned long arch_get_cur_sp(struct pt_regs *regs) return (unsigned long) regs->sp; } +/* + * On x86_32, if a function returns a struct or union, the return + * value is copied into an area created by the caller. The address + * of this area is passed on the stack as a "hidden" first argument. + * When such a function returns, it uses a "ret $4" instruction to pop + * not only the return address but also the hidden arg. To accommodate + * such functions, we add 4 bytes of slop when predicting the return + * address. See PR #10078. + */ +#define STRUCT_RETURN_SLOP 4 + static inline unsigned long arch_predict_sp_at_ret(struct pt_regs *regs, struct task_struct *tsk) { if (test_tsk_thread_flag(tsk, TIF_IA32)) - return (unsigned long) (regs->sp + 4); + return (unsigned long) (regs->sp + 4 + STRUCT_RETURN_SLOP); else return (unsigned long) (regs->sp + 8); } |