1912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata/* 2912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * This file is part of ltrace. 3912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * Copyright (C) 2014 Petr Machata, Red Hat, Inc. 4912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * 5912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * This program is free software; you can redistribute it and/or 6912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * modify it under the terms of the GNU General Public License as 7912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * published by the Free Software Foundation; either version 2 of the 8912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * License, or (at your option) any later version. 9912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * 10912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * This program is distributed in the hope that it will be useful, but 11912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 12912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * General Public License for more details. 14912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * 15912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * You should have received a copy of the GNU General Public License 16912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * along with this program; if not, write to the Free Software 17912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * 02110-1301 USA 19912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata */ 20912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 21912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include <sys/ptrace.h> 22912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include <sys/types.h> 23912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include <sys/wait.h> 24912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include <asm/ptrace.h> 25912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include <string.h> 266bacfc7b34be8414d01c201f1c6086e3edaa8b62dann frazier#include <stdio.h> 27912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include <errno.h> 28912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 29912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include "backend.h" 30912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#include "proc.h" 31912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 32912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machatavoid 33912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machataget_arch_dep(struct process *proc) 34912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata{ 35912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata} 36912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 37912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machataint aarch64_read_gregs(struct process *proc, struct user_pt_regs *regs); 38912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 39912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata/* The syscall instruction is: 40912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * | 31 21 | 20 5 | 4 0 | 41912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata * | 1 1 0 1 0 1 0 0 | 0 0 0 | imm16 | 0 0 0 0 1 | */ 42912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#define SVC_MASK 0xffe0001f 43912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata#define SVC_VALUE 0xd4000001 44912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 45912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machataint 46912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machatasyscall_p(struct process *proc, int status, int *sysnum) 47912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata{ 48912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata if (WIFSTOPPED(status) 49912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { 50912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 51912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata struct user_pt_regs regs; 52912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata if (aarch64_read_gregs(proc, ®s) < 0) { 53912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata fprintf(stderr, "syscall_p: " 54912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata "Couldn't read registers of %d.\n", proc->pid); 55912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata return -1; 56912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata } 57912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 58912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata errno = 0; 59912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata unsigned long insn = (unsigned long) ptrace(PTRACE_PEEKTEXT, 60912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata proc->pid, 61912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata regs.pc - 4, 0); 62912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata if (insn == -1UL && errno != 0) { 63912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata fprintf(stderr, "syscall_p: " 64912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata "Couldn't peek into %d: %s\n", proc->pid, 65912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata strerror(errno)); 66912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata return -1; 67912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata } 68912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 69912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata insn &= 0xffffffffUL; 70912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata if ((insn & SVC_MASK) == SVC_VALUE) { 71912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata *sysnum = regs.regs[8]; 72912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 73912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata size_t d1 = proc->callstack_depth - 1; 74912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata if (proc->callstack_depth > 0 75912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata && proc->callstack[d1].is_syscall 76912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata && proc->callstack[d1].c_un.syscall == *sysnum) 77912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata return 2; 78912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 79912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata return 1; 80912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata } 81912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata } 82912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata 83912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata return 0; 84912a0f75b3521803fa724a55f0e883c134c7b4e9Petr Machata} 85