| Petr Machata | e99af27 | 2012-10-26 00:29:52 +0200 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of ltrace. |
| Petr Machata | 44ae188 | 2013-01-30 17:38:37 +0100 | [diff] [blame] | 3 | * Copyright (C) 2013 Petr Machata, Red Hat Inc. |
| Petr Machata | e99af27 | 2012-10-26 00:29:52 +0200 | [diff] [blame] | 4 | * Copyright (C) 2004,2008,2009 Juan Cespedes |
| 5 | * Copyright (C) 2006 Ian Wienand |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License as |
| 9 | * published by the Free Software Foundation; either version 2 of the |
| 10 | * License, or (at your option) any later version. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, but |
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License |
| 18 | * along with this program; if not, write to the Free Software |
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
| 20 | * 02110-1301 USA |
| 21 | */ |
| 22 | |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 23 | #include "config.h" |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 24 | |
| 25 | #include <sys/types.h> |
| 26 | #include "ptrace.h" |
| Petr Machata | 366c2f4 | 2012-02-09 19:34:36 +0100 | [diff] [blame] | 27 | #include "proc.h" |
| Juan Cespedes | f728123 | 2009-06-25 16:11:21 +0200 | [diff] [blame] | 28 | #include "common.h" |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 29 | |
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 30 | void * |
| Petr Machata | 929bd57 | 2012-12-17 03:20:34 +0100 | [diff] [blame] | 31 | get_instruction_pointer(struct process *proc) |
| 32 | { |
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 33 | proc_archdep *a = (proc_archdep *) (proc->arch_ptr); |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 34 | if (a->valid) |
| Juan Cespedes | 3458456 | 2009-07-25 16:10:39 +0200 | [diff] [blame] | 35 | return (void *)a->regs.pc; |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 36 | return (void *)-1; |
| 37 | } |
| 38 | |
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 39 | void |
| Petr Machata | 929bd57 | 2012-12-17 03:20:34 +0100 | [diff] [blame] | 40 | set_instruction_pointer(struct process *proc, void *addr) |
| 41 | { |
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 42 | proc_archdep *a = (proc_archdep *) (proc->arch_ptr); |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 43 | if (a->valid) |
| Juan Cespedes | 3458456 | 2009-07-25 16:10:39 +0200 | [diff] [blame] | 44 | a->regs.pc = (long)addr; |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 45 | } |
| 46 | |
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 47 | void * |
| Petr Machata | 929bd57 | 2012-12-17 03:20:34 +0100 | [diff] [blame] | 48 | get_stack_pointer(struct process *proc) |
| 49 | { |
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 50 | proc_archdep *a = (proc_archdep *) (proc->arch_ptr); |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 51 | if (a->valid) |
| Juan Cespedes | 3458456 | 2009-07-25 16:10:39 +0200 | [diff] [blame] | 52 | return (void *)a->regs.u_regs[UREG_I5]; |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 53 | return (void *)-1; |
| 54 | } |
| 55 | |
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 56 | void * |
| Petr Machata | 929bd57 | 2012-12-17 03:20:34 +0100 | [diff] [blame] | 57 | get_return_addr(struct process *proc, void *stack_pointer) |
| 58 | { |
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 59 | proc_archdep *a = (proc_archdep *) (proc->arch_ptr); |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 60 | unsigned int t; |
| 61 | if (!a->valid) |
| 62 | return (void *)-1; |
| 63 | /* Work around structure returns */ |
| Juan Cespedes | 3458456 | 2009-07-25 16:10:39 +0200 | [diff] [blame] | 64 | t = ptrace(PTRACE_PEEKTEXT, proc->pid, a->regs.u_regs[UREG_I6] + 8, 0); |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 65 | if (t < 0x400000) |
| Juan Cespedes | 3458456 | 2009-07-25 16:10:39 +0200 | [diff] [blame] | 66 | return (void *)a->regs.u_regs[UREG_I6] + 12; |
| 67 | return (void *)a->regs.u_regs[UREG_I6] + 8; |
| Juan Cespedes | 5c3fe06 | 2004-06-14 18:08:37 +0200 | [diff] [blame] | 68 | } |