1541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata/* 2541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * This file is part of ltrace. 3ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * Copyright (C) 2010,2011,2012 Petr Machata, Red Hat Inc. 4541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * Copyright (C) 2004,2008,2009 Juan Cespedes 5541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * Copyright (C) 2006 Ian Wienand 6541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * 7541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * This program is free software; you can redistribute it and/or 8541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * modify it under the terms of the GNU General Public License as 9541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * published by the Free Software Foundation; either version 2 of the 10541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * License, or (at your option) any later version. 11541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * 12541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * This program is distributed in the hope that it will be useful, but 13541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 14541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * General Public License for more details. 16541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * 17541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * You should have received a copy of the GNU General Public License 18541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * along with this program; if not, write to the Free Software 19541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata * 02110-1301 USA 21541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata */ 22541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 23efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes#include "config.h" 24efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 25efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes#include <sys/reg.h> 26ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#include <sys/wait.h> 27211f0886c5aeceebacb44e3ae84d6b8f931cedf2Petr Machata#include <assert.h> 28f2d2ba5ce96587f4cc0975441a5da4c6e672e8faPetr Machata#include <errno.h> 29541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata#include <stdlib.h> 30efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 31ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "backend.h" 32ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "debug.h" 33ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "proc.h" 34ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "ptrace.h" 35000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#include "type.h" 36efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 37efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 38efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes# define PTRACE_PEEKUSER PTRACE_PEEKUSR 39efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes#endif 40efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 41efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 42efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes# define PTRACE_POKEUSER PTRACE_POKEUSR 43efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes#endif 44efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 45ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#ifdef __x86_64__ 46ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define ORIG_XAX (8 * ORIG_RAX) 47ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#else 48ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata# define ORIG_XAX (4 * ORIG_EAX) 49ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#endif 50ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 51ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#ifdef __x86_64__ 52ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machatastatic const int x86_64 = 1; 53ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#else 54ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machatastatic const int x86_64 = 0; 55ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata#endif 56ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 57f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 58929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataget_arch_dep(struct process *proc) 59541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata{ 60ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata /* Unfortunately there are still remnants of mask_32bit uses 61ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata * around. */ 627a919b9236b06215af87eda135b71f69478b5c15Arnaud Patard 63ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (proc->e_machine == EM_X86_64) { 64ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata proc->mask_32bit = 0; 659a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand proc->personality = 1; 66ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata } else if (x86_64) { /* x86_64/i386 */ 67ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata proc->mask_32bit = 1; 68ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata proc->personality = 0; 69541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata } else { 70541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata proc->mask_32bit = 0; 71541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata proc->personality = 0; 729a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand } 735c3fe0697b202cc7d95e90459de0fb312b297b27Juan Cespedes} 745c3fe0697b202cc7d95e90459de0fb312b297b27Juan Cespedes 75efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes/* Returns 1 if syscall, 2 if sysret, 0 otherwise. 76efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes */ 77f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesint 78929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatasyscall_p(struct process *proc, int status, int *sysnum) 79e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata{ 802d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (WIFSTOPPED(status) 812d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { 82e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata struct callstack_element *elem = NULL; 83e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata if (proc->callstack_depth > 0) 84e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata elem = proc->callstack + proc->callstack_depth - 1; 85e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata 86ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, ORIG_XAX, 0); 87e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata if (ret == -1) { 88e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata if (errno) 89e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata return -1; 90e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata /* Otherwise, ORIG_RAX == -1 means that the 91e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata * system call should not be restarted. In 92e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata * that case rely on what we have on 93e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata * stack. */ 94e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata if (elem != NULL && elem->is_syscall) 95e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata ret = elem->c_un.syscall; 96e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata } 97efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 98f2d2ba5ce96587f4cc0975441a5da4c6e672e8faPetr Machata *sysnum = ret; 99c06f23d2803c7744f3d2cd1fb3e54886d9e41ddfPetr Machata debug(DEBUG_FUNCTION, "sysnum=%ld %p %d", ret, 100e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata get_instruction_pointer(proc), errno); 101e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata if (elem != NULL && elem->is_syscall 102e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata && elem->c_un.syscall == *sysnum) 103efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes return 2; 104efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 105e577a10e73b41e2c68fff7e8d89c22dfb9378b99Petr Machata if (*sysnum >= 0) 106efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes return 1; 107efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes } 108efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes return 0; 109efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes} 110efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes 111541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machatasize_t 112929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_type_sizeof(struct process *proc, struct arg_type_info *info) 113541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata{ 114ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (proc == NULL) 115541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata return (size_t)-2; 116541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 117541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata switch (info->type) { 118541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_VOID: 119ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return 0; 120ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 121541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_CHAR: 122ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return 1; 123ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 124541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_SHORT: 125541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_USHORT: 126ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return 2; 127541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 128541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_INT: 129541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_UINT: 130ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return 4; 131ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 132541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_LONG: 133541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_ULONG: 134541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_POINTER: 135ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return proc->e_machine == EM_X86_64 ? 8 : 4; 136ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 137ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_FLOAT: 138541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata return 4; 139ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_DOUBLE: 140ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return 8; 141ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 142ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_ARRAY: 143ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_STRUCT: 144ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata /* Use default value. */ 145ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return (size_t)-2; 1465b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias 1475b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias default: 1485b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias assert(info->type != info->type); 1495b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias abort(); 150541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata } 151541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata} 152541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 153541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machatasize_t 154929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_type_alignof(struct process *proc, struct arg_type_info *info) 155541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata{ 156ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata if (proc == NULL) 157541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata return (size_t)-2; 158541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 159541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata switch (info->type) { 1605b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias default: 1615b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias assert(info->type != info->type); 1625b5c256d0e9076e745908a43acc46353265a5608Edgar E. Iglesias abort(); 163ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata break; 164541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 165541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_CHAR: 166541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata return 1; 167541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 168541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_SHORT: 169541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_USHORT: 170541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata return 2; 171541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 172541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_INT: 173541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_UINT: 174ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return 4; 175ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 176541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_LONG: 177541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_ULONG: 178541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata case ARGTYPE_POINTER: 179ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return proc->e_machine == EM_X86_64 ? 8 : 4; 180ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata 181ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_FLOAT: 182541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata return 4; 183ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_DOUBLE: 184ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return proc->e_machine == EM_X86_64 ? 8 : 4; 185541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata 186ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_ARRAY: 187ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata case ARGTYPE_STRUCT: 188ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata /* Use default value. */ 189ddd96a3fbc7c54146d1d831810fc9e29c9bc3c76Petr Machata return (size_t)-2; 190541cdc7736ffa770958208995fae71cbd1d50bcfPetr Machata } 191efe85f0668a077b1e851df4b3f87a380cf2269fdJuan Cespedes} 192