1ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata/* 2ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * This file is part of ltrace. 344ae188c8dcd2727e383dcac0d46c3f784d0da5fPetr Machata * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc. 4ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * Copyright (C) 1998,2002,2004,2008,2009 Juan Cespedes 5ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * Copyright (C) 2006 Ian Wienand 6ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * 7ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * This program is free software; you can redistribute it and/or 8ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * modify it under the terms of the GNU General Public License as 9ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * published by the Free Software Foundation; either version 2 of the 10ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * License, or (at your option) any later version. 11ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * 12ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * This program is distributed in the hope that it will be useful, but 13ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 14ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * General Public License for more details. 16ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * 17ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * You should have received a copy of the GNU General Public License 18ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * along with this program; if not, write to the Free Software 19ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * 02110-1301 USA 21ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata */ 22ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include "config.h" 23ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 24ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include <sys/types.h> 25ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include <sys/ptrace.h> 26ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include <sys/reg.h> 27ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include <errno.h> 28ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include <stdio.h> 29ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include <string.h> 30ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 31ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include "backend.h" 32ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include "proc.h" 33ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 34ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 35ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define PTRACE_PEEKUSER PTRACE_PEEKUSR 36ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#endif 37ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 38ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 39ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define PTRACE_POKEUSER PTRACE_POKEUSR 40ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#endif 41ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 42ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#ifdef __x86_64__ 43ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define XIP (8 * RIP) 44ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define XSP (8 * RSP) 45ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#else 46ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define XIP (4 * EIP) 47ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define XSP (4 * UESP) 48ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#endif 49ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 50bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatastatic arch_addr_t 51bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machataconv_32(arch_addr_t val) 52ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata{ 53bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata /* XXX Drop the multiple double casts when arch_addr_t 54ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * becomes integral. */ 55bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata return (arch_addr_t)(uintptr_t)(uint32_t)(uintptr_t)val; 56ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata} 57ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 58ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machatavoid * 59929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataget_instruction_pointer(struct process *proc) 60ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata{ 61ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, XIP, 0); 62ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (proc->e_machine == EM_386) 63ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata ret &= 0xffffffff; 64ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return (void *)ret; 65ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata} 66ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 67ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machatavoid 68929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataset_instruction_pointer(struct process *proc, arch_addr_t addr) 69ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata{ 70ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (proc->e_machine == EM_386) 71ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata addr = conv_32(addr); 72ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata ptrace(PTRACE_POKEUSER, proc->pid, XIP, addr); 73ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata} 74ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 75ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machatavoid * 76929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataget_stack_pointer(struct process *proc) 77ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata{ 78ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata long sp = ptrace(PTRACE_PEEKUSER, proc->pid, XSP, 0); 79ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (sp == -1 && errno) { 80ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata fprintf(stderr, "Couldn't read SP register: %s\n", 81ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata strerror(errno)); 82ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return NULL; 83ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata } 84ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 85bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata /* XXX Drop the multiple double casts when arch_addr_t 86ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * becomes integral. */ 87bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t ret = (arch_addr_t)(uintptr_t)sp; 88ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (proc->e_machine == EM_386) 89ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata ret = conv_32(ret); 90ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return ret; 91ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata} 92ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 93ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machatavoid * 94929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataget_return_addr(struct process *proc, void *sp) 95ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata{ 96ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata long a = ptrace(PTRACE_PEEKTEXT, proc->pid, sp, 0); 97ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (a == -1 && errno) { 98ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata fprintf(stderr, "Couldn't read return value: %s\n", 99ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata strerror(errno)); 100ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return NULL; 101ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata } 102ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 103bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata /* XXX Drop the multiple double casts when arch_addr_t 104ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * becomes integral. */ 105bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t ret = (arch_addr_t)(uintptr_t)a; 106ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (proc->e_machine == EM_386) 107ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata ret = conv_32(ret); 108ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return ret; 109ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata} 110