1e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata/* 2e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This file is part of ltrace. 3693dfad9c1b121cf079a3082866daa2225df1797Petr Machata * Copyright (C) 2013 Petr Machata, Red Hat Inc. 4e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2012 Edgar E. Iglesias, Axis Communications 5e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2010 Arnaud Patard, Mandriva SA 6e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2008,2009 Juan Cespedes 7e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc. 8e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 9e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is free software; you can redistribute it and/or 10e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * modify it under the terms of the GNU General Public License as 11e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * published by the Free Software Foundation; either version 2 of the 12e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * License, or (at your option) any later version. 13e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 14e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is distributed in the hope that it will be useful, but 15e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 16e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * General Public License for more details. 18e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 19e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * You should have received a copy of the GNU General Public License 20e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * along with this program; if not, write to the Free Software 21e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 22e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 02110-1301 USA 23e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata */ 24e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata 251228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#include "config.h" 261228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 271228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#include <sys/types.h> 281228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#include <sys/wait.h> 291228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#include <signal.h> 301228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#include <sys/ptrace.h> 311228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#include <asm/ptrace.h> 32addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#include <assert.h> 333b3b0d3a24c1b6c374cc2338d9791518fffa29bePetr Machata 343b3b0d3a24c1b6c374cc2338d9791518fffa29bePetr Machata#include "backend.h" 35f728123bd75a65a6a1536e198c3c30719e494e71Juan Cespedes#include "common.h" 363b3b0d3a24c1b6c374cc2338d9791518fffa29bePetr Machata#include "debug.h" 3732ea1b1eaad1a07a120811bca9dd9f3524cc9256Oliver Spornitz#include "mips.h" 383b3b0d3a24c1b6c374cc2338d9791518fffa29bePetr Machata#include "proc.h" 39000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata#include "type.h" 403b3b0d3a24c1b6c374cc2338d9791518fffa29bePetr Machata 411228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 421228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl# define PTRACE_PEEKUSER PTRACE_PEEKUSR 431228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#endif 441228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 451228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 461228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl# define PTRACE_POKEUSER PTRACE_POKEUSR 471228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#endif 481228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 491228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 501228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl/** 5132ea1b1eaad1a07a120811bca9dd9f3524cc9256Oliver Spornitz \addtogroup mips Mips specific functions. 521228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 531228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl These are the functions that it looks like I need to implement in 54fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes order to get ltrace to work on our target. 551228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 561228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl @{ 571228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl */ 581228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 591228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl/** 60fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes \param proc The process that had an event. 611228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 62e2023f721b66db48cc8a0f4ab6519460093c2cf1Juan Cespedes Called by \c next_event() right after the return from wait. 631228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 641228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl Most targets just return here. A couple use proc->arch_ptr for a 651228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl private data area. 661228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl */ 67f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 68929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataget_arch_dep(struct process *proc) 69929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata{ 701228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl} 711228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 721228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl/** 73fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes \param proc Process that had event. 741228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl \param status From \c wait() 75fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes \param sysnum 0-based syscall number. 761228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl \return 1 if syscall, 2 if sysret, 0 otherwise. 771228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 78e2023f721b66db48cc8a0f4ab6519460093c2cf1Juan Cespedes Called by \c next_event() after the call to get_arch_dep() 791228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 801228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl It seems that the ptrace call trips twice on a system call, once 811228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl just before the system call and once when it returns. Both times, 8232ea1b1eaad1a07a120811bca9dd9f3524cc9256Oliver Spornitz the pc points at the instruction just after the mips "syscall" 831228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl instruction. 841228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 851228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl There are several possiblities for system call sets, each is offset 861228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl by a base from the others. On our system, it looks like the base 871228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl for the system calls is 4000. 881228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl */ 89f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesint 90929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatasyscall_p(struct process *proc, int status, int *sysnum) 91929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata{ 921228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl if (WIFSTOPPED(status) 933e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { 943e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes /* get the user's pc (plus 8) */ 953e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes long pc = (long)get_instruction_pointer(proc); 963e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes /* fetch the SWI instruction */ 973e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0); 983e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes int num = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 8, 0); 993e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes 1003e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes /* 10132ea1b1eaad1a07a120811bca9dd9f3524cc9256Oliver Spornitz On a mips, syscall looks like: 1023e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes 24040fa1 li v0, 0x0fa1 # 4001 --> _exit syscall 1033e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes 0000000c syscall 1043e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes */ 1053e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes if(insn!=0x0000000c){ 1063e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes return 0; 1073e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } 1083e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes 1093e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes *sysnum = (num & 0xFFFF) - 4000; 1103e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes /* if it is a syscall, return 1 or 2 */ 1113e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes if (proc->callstack_depth > 0 && 1123e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes proc->callstack[proc->callstack_depth - 1].is_syscall && 1133e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes proc->callstack[proc->callstack_depth - 1].c_un.syscall == *sysnum) { 1143e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes return 2; 1153e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } 1163e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes 1173e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes if (*sysnum >= 0) { 1183e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes return 1; 1193e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } 1203e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } 1211228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl return 0; 1221228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl} 123addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 124addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias/* Based on GDB code. */ 125addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define mips32_op(x) (x >> 26) 126addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define itype_op(x) (x >> 26) 127addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define itype_rs(x) ((x >> 21) & 0x1f) 128addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define itype_rt(x) ((x >> 16) & 0x1f) 129addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define itype_immediate(x) (x & 0xffff) 130addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 131addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define jtype_op(x) (x >> 26) 132addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define jtype_target(x) (x & 0x03ffffff) 133addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 134addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define rtype_op(x) (x >> 26) 135addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define rtype_rs(x) ((x >> 21) & 0x1f) 136addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define rtype_rt(x) ((x >> 16) & 0x1f) 137addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define rtype_rd(x) ((x >> 11) & 0x1f) 138addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define rtype_shamt(x) ((x >> 6) & 0x1f) 139addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias#define rtype_funct(x) (x & 0x3f) 140addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 141addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesiasstatic int32_t 142addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesiasmips32_relative_offset (uint32_t inst) 143addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias{ 1440b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias return ((itype_immediate(inst) ^ 0x8000) - 0x8000) << 2; 145addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias} 146addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 147929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataint mips_next_pcs(struct process *proc, uint32_t pc, uint32_t *newpc) 148addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias{ 149addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias uint32_t inst, rx; 150addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias int op; 151addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias int rn; 152addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias int nr = 0; 153addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 154addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias inst = ptrace(PTRACE_PEEKTEXT, proc->pid, pc, 0); 155addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 156addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias if ((inst & 0xe0000000) != 0) { 157addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias /* Check for branches. */ 1580b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias if (itype_op(inst) >> 2 == 5) { 159addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */ 1600b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias op = (itype_op(inst) & 0x03); 161addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias switch (op) 162addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias { 163addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 0: /* BEQL */ 164addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 1: /* BNEL */ 165addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 2: /* BLEZL */ 166addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 3: /* BGTZL */ 167addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 8; 168addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 4 + 1690b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias mips32_relative_offset(inst); 170addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 171addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias default: 172addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 4; 173addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 174addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 1750b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias } else if (itype_op(inst) == 17 && itype_rs(inst) == 8) { 176addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias /* Step over the branch. */ 177addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 8; 1780b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias newpc[nr++] = pc + mips32_relative_offset(inst) + 4; 179addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } else { 180addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 4; 181addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 182addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } else { 183addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias /* Further subdivide into SPECIAL, REGIMM and other. */ 1840b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias switch (op = itype_op(inst) & 0x07) 185addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias { 186addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 0: 1870b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias op = rtype_funct(inst); 188addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias switch (op) 189addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias { 190addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 8: /* JR */ 191addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 9: /* JALR */ 1920b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias rn = rtype_rs(inst); 193addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 194addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias rx = ptrace(PTRACE_PEEKUSER,proc->pid, rn, 0); 195addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = rx; 196addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 197addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias default: 198addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 12: /* SYSCALL */ 199addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 4; 200addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 201addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 202addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 203addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 1: 2040b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias op = itype_rt(inst); 205addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias switch (op) 206addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias { 207addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 0: 208addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 1: 209addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 2: 210addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 3: 211addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 16: 212addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 17: 213addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 18: 214addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 19: 215addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 8; 216addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 4 + 217addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias mips32_relative_offset(inst); 218addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 219addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias default: 220addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 4; 221addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 222addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 223addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 224addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 2: /* J */ 225addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 3: /* JAL */ 2260b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias rx = jtype_target(inst) << 2; 227addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias /* Upper four bits get never changed... */ 228addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = rx + ((pc + 4) & ~0x0fffffff); 229addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 230c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias case 4: /* BEQ */ 231c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias if (itype_rs(inst) == itype_rt(inst)) { 232c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias /* Compare the same reg for equality, always 233c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias * follow the branch. */ 234c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias newpc[nr++] = pc + 4 + 235c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias mips32_relative_offset(inst); 236c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias break; 237c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias } 238c44ef1ea84927851ddd74abff9a6374a62978caeEdgar E. Iglesias /* Fall through. */ 239addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias default: 240addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 5: 241addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 6: 242addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias case 7: 243addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias /* Step over the branch. */ 244addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias newpc[nr++] = pc + 8; 2450b02a93aff5808b7640299faedfeb697485fd170Edgar E. Iglesias newpc[nr++] = pc + mips32_relative_offset(inst) + 4; 246addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias break; 247addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 248addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 249addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias if (nr <= 0 || nr > 2) 250addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias goto fail; 251addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias if (nr == 2) { 252addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias if (newpc[1] == 0) 253addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias goto fail; 254addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 255addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias if (newpc[0] == 0) 256addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias goto fail; 257addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 258addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias assert(nr == 1 || nr == 2); 259addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias return nr; 260addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 261addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesiasfail: 262addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias printf("nr=%d pc=%x\n", nr, pc); 263addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias printf("pc=%x %x\n", newpc[0], newpc[1]); 264addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias return 0; 265addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias} 266addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 267693dfad9c1b121cf079a3082866daa2225df1797Petr Machataenum sw_singlestep_status 268693dfad9c1b121cf079a3082866daa2225df1797Petr Machataarch_sw_singlestep(struct process *proc, struct breakpoint *bp, 269693dfad9c1b121cf079a3082866daa2225df1797Petr Machata int (*add_cb)(arch_addr_t, struct sw_singlestep_data *), 270693dfad9c1b121cf079a3082866daa2225df1797Petr Machata struct sw_singlestep_data *add_cb_data) 271addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias{ 272addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias uint32_t pc = (uint32_t) get_instruction_pointer(proc); 273addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias uint32_t newpcs[2]; 274addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias int nr; 275addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 276addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias nr = mips_next_pcs(proc, pc, newpcs); 277addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 278addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias while (nr-- > 0) { 279addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias arch_addr_t baddr = (arch_addr_t) newpcs[nr]; 280addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias /* Not sure what to do here. We've already got a bp? */ 281273890e09616b8fe0b9b015ea8edda12c52d4ba2Petr Machata if (DICT_HAS_KEY(proc->leader->breakpoints, &baddr)) { 282addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias fprintf(stderr, "skip %p %p\n", baddr, add_cb_data); 283addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias continue; 284addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 285addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 286addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias if (add_cb(baddr, add_cb_data) < 0) 287693dfad9c1b121cf079a3082866daa2225df1797Petr Machata return SWS_FAIL; 288addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias } 289addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 290addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias ptrace(PTRACE_SYSCALL, proc->pid, 0, 0); 291693dfad9c1b121cf079a3082866daa2225df1797Petr Machata return SWS_OK; 292addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias} 293addae05da54ac16c55133e1c384d74e03346f634Edgar E. Iglesias 2941228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl/** 2951228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl \param type Function/syscall call or return. 2961228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl \param proc The process that had an event. 297fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes \param arg_num -1 for return value, 298fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes \return The argument to fetch. 2991228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 300fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes A couple of assumptions. 3011228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 3021228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl- Type is LT_TOF_FUNCTIONR or LT_TOF_SYSCALLR if arg_num==-1. These 3031228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl types are only used in calls for output_right(), which only uses -1 3041228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl for arg_num. 305fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes- Type is LT_TOF_FUNCTION or LT_TOF_SYSCALL for args 0...4. 3061228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl- I'm only displaying the first 4 args (Registers a0..a3). Good 3071228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl enough for now. 3081228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 30932ea1b1eaad1a07a120811bca9dd9f3524cc9256Oliver Spornitz Mips conventions seem to be: 3101228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl- syscall parameters: r4...r9 3111228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl- syscall return: if(!a3){ return v0;} else{ errno=v0;return -1;} 312fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes- function call: r4..r7. Not sure how to get arg number 5. 3131228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl- function return: v0 3141228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 3151228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric VaitlThe argument registers are wiped by a call, so it is a mistake to ask 3161228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitlfor arguments on a return. If ltrace does this, we will need to cache 3171228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitlarguments somewhere on the call. 3181228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 319fea4a1285dc7bea02b0203845ad43117f091fc3eJuan CespedesI'm not doing any floating point support here. 3201228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 3211228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl*/ 322f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedeslong 323929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatagimme_arg(enum tof type, struct process *proc, int arg_num, 324929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct arg_type_info *info) 325000e31195ad4ad30a0c80c93ab57a424e7d8d918Petr Machata{ 3263e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes long ret; 3278a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard long addr; 3283e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes debug(2,"type %d arg %d",type,arg_num); 3298a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if (arg_num == -1) { 3308a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if(type == LT_TOF_FUNCTIONR) { 3318a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return ptrace(PTRACE_PEEKUSER,proc->pid,off_v0,0); 3328a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard } 3338a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if (type == LT_TOF_SYSCALLR) { 3348a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard unsigned a3=ptrace(PTRACE_PEEKUSER, proc->pid,off_a3,0); 3358a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard unsigned v0=ptrace(PTRACE_PEEKUSER, proc->pid,off_v0,0); 3368a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if(!a3){ 3378a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return v0; 3388a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard } 3398a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return -1; 3408a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard } 3418a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard } 3428a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL) { 3438a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard /* o32: float args are in f12 and f14 */ 3448a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if ((info->type == ARGTYPE_FLOAT) && (arg_num < 2)) { 3458a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_fpr0+12+arg_num*2,0); 3468a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard debug(2,"ret = %#lx",ret); 3478a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return ret; 3488a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard } 3493e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes if(arg_num <4){ 3503e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_a0+arg_num,0); 3513e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes debug(2,"ret = %#lx",ret); 3523e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes return ret; 3533e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } else { 3548a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard /* not sure it's going to work for something else than syscall */ 3558a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard addr=ptrace(PTRACE_PEEKUSER,proc->pid,off_sp,0); 3568a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if (addr == -1) { 3578a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard debug(2,"ret = %#lx",addr); 3588a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return addr; 3598a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard } 3608a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard ret = addr + 4*arg_num; 3618a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard ret=ptrace(PTRACE_PEEKTEXT,proc->pid,addr,0); 3628a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard debug(2,"ret = %#lx",ret); 3638a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return ret; 3643e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } 365fea4a1285dc7bea02b0203845ad43117f091fc3eJuan Cespedes } 3668a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if (type == LT_TOF_FUNCTIONR || type == LT_TOF_SYSCALLR){ 3678a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard addr=ptrace(PTRACE_PEEKUSER,proc->pid,off_sp,0); 3688a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard if (addr == -1) { 3698a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard debug(2,"ret = %#lx",addr); 3708a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return addr; 3713e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } 3728a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard ret = addr + 4*arg_num; 3738a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard ret=ptrace(PTRACE_PEEKTEXT,proc->pid,addr,0); 3748a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard debug(2,"ret = %#lx",ret); 3758a115b6cedaf530e4589e6dc190bfb70b2c2619aArnaud Patard return ret; 3763e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes } 3773e94cbf0d388a5b5b49f8dbc60f4b24900de89aeJuan Cespedes fprintf(stderr, "gimme_arg called with wrong arguments\n"); 3781228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl return 0; 3791228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl} 3801228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl 3811228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl/**@}*/ 382