1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2010,2011,2012 Petr Machata, Red Hat Inc. 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 23#include "config.h" 24 25#include <sys/reg.h> 26#include <sys/wait.h> 27#include <assert.h> 28#include <errno.h> 29#include <stdlib.h> 30 31#include "backend.h" 32#include "debug.h" 33#include "proc.h" 34#include "ptrace.h" 35#include "type.h" 36 37#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 38# define PTRACE_PEEKUSER PTRACE_PEEKUSR 39#endif 40 41#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 42# define PTRACE_POKEUSER PTRACE_POKEUSR 43#endif 44 45#ifdef __x86_64__ 46# define ORIG_XAX (8 * ORIG_RAX) 47#else 48# define ORIG_XAX (4 * ORIG_EAX) 49#endif 50 51#ifdef __x86_64__ 52static const int x86_64 = 1; 53#else 54static const int x86_64 = 0; 55#endif 56 57void 58get_arch_dep(struct process *proc) 59{ 60 /* Unfortunately there are still remnants of mask_32bit uses 61 * around. */ 62 63 if (proc->e_machine == EM_X86_64) { 64 proc->mask_32bit = 0; 65 proc->personality = 1; 66 } else if (x86_64) { /* x86_64/i386 */ 67 proc->mask_32bit = 1; 68 proc->personality = 0; 69 } else { 70 proc->mask_32bit = 0; 71 proc->personality = 0; 72 } 73} 74 75/* Returns 1 if syscall, 2 if sysret, 0 otherwise. 76 */ 77int 78syscall_p(struct process *proc, int status, int *sysnum) 79{ 80 if (WIFSTOPPED(status) 81 && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { 82 struct callstack_element *elem = NULL; 83 if (proc->callstack_depth > 0) 84 elem = proc->callstack + proc->callstack_depth - 1; 85 86 long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, ORIG_XAX, 0); 87 if (ret == -1) { 88 if (errno) 89 return -1; 90 /* Otherwise, ORIG_RAX == -1 means that the 91 * system call should not be restarted. In 92 * that case rely on what we have on 93 * stack. */ 94 if (elem != NULL && elem->is_syscall) 95 ret = elem->c_un.syscall; 96 } 97 98 *sysnum = ret; 99 debug(DEBUG_FUNCTION, "sysnum=%ld %p %d", ret, 100 get_instruction_pointer(proc), errno); 101 if (elem != NULL && elem->is_syscall 102 && elem->c_un.syscall == *sysnum) 103 return 2; 104 105 if (*sysnum >= 0) 106 return 1; 107 } 108 return 0; 109} 110 111size_t 112arch_type_sizeof(struct process *proc, struct arg_type_info *info) 113{ 114 if (proc == NULL) 115 return (size_t)-2; 116 117 switch (info->type) { 118 case ARGTYPE_VOID: 119 return 0; 120 121 case ARGTYPE_CHAR: 122 return 1; 123 124 case ARGTYPE_SHORT: 125 case ARGTYPE_USHORT: 126 return 2; 127 128 case ARGTYPE_INT: 129 case ARGTYPE_UINT: 130 return 4; 131 132 case ARGTYPE_LONG: 133 case ARGTYPE_ULONG: 134 case ARGTYPE_POINTER: 135 return proc->e_machine == EM_X86_64 ? 8 : 4; 136 137 case ARGTYPE_FLOAT: 138 return 4; 139 case ARGTYPE_DOUBLE: 140 return 8; 141 142 case ARGTYPE_ARRAY: 143 case ARGTYPE_STRUCT: 144 /* Use default value. */ 145 return (size_t)-2; 146 147 default: 148 assert(info->type != info->type); 149 abort(); 150 } 151} 152 153size_t 154arch_type_alignof(struct process *proc, struct arg_type_info *info) 155{ 156 if (proc == NULL) 157 return (size_t)-2; 158 159 switch (info->type) { 160 default: 161 assert(info->type != info->type); 162 abort(); 163 break; 164 165 case ARGTYPE_CHAR: 166 return 1; 167 168 case ARGTYPE_SHORT: 169 case ARGTYPE_USHORT: 170 return 2; 171 172 case ARGTYPE_INT: 173 case ARGTYPE_UINT: 174 return 4; 175 176 case ARGTYPE_LONG: 177 case ARGTYPE_ULONG: 178 case ARGTYPE_POINTER: 179 return proc->e_machine == EM_X86_64 ? 8 : 4; 180 181 case ARGTYPE_FLOAT: 182 return 4; 183 case ARGTYPE_DOUBLE: 184 return proc->e_machine == EM_X86_64 ? 8 : 4; 185 186 case ARGTYPE_ARRAY: 187 case ARGTYPE_STRUCT: 188 /* Use default value. */ 189 return (size_t)-2; 190 } 191} 192