131567Ssef/* 2204977Simp * Copyright 1997 Sean Eric Fagan 331899Ssef * 431899Ssef * Redistribution and use in source and binary forms, with or without 531899Ssef * modification, are permitted provided that the following conditions 631899Ssef * are met: 731899Ssef * 1. Redistributions of source code must retain the above copyright 831899Ssef * notice, this list of conditions and the following disclaimer. 931899Ssef * 2. Redistributions in binary form must reproduce the above copyright 1031899Ssef * notice, this list of conditions and the following disclaimer in the 1131899Ssef * documentation and/or other materials provided with the distribution. 1231899Ssef * 3. All advertising materials mentioning features or use of this software 1331899Ssef * must display the following acknowledgement: 1431899Ssef * This product includes software developed by Sean Eric Fagan 1531899Ssef * 4. Neither the name of the author may be used to endorse or promote 1631899Ssef * products derived from this software without specific prior written 1731899Ssef * permission. 1831899Ssef * 1931899Ssef * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2031899Ssef * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2131899Ssef * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2231899Ssef * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2331899Ssef * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2431899Ssef * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2531899Ssef * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2631899Ssef * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2731899Ssef * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2831899Ssef * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2931899Ssef * SUCH DAMAGE. 3031899Ssef */ 3131899Ssef 32288424Sjhb#include <sys/cdefs.h> 33288424Sjhb__FBSDID("$FreeBSD: releng/11.0/usr.bin/truss/amd64-linux32.c 295931 2016-02-23 20:00:55Z jhb $"); 3432275Scharnier 35288424Sjhb/* Linux/i386-specific system call handling. */ 3632275Scharnier 37168569Sdelphij#include <sys/ptrace.h> 3885301Sdes 3985301Sdes#include <machine/reg.h> 4085301Sdes#include <machine/psl.h> 4185301Sdes 4231567Ssef#include <stdio.h> 43294849Sjhb#include <sysdecode.h> 4431567Ssef 45101282Smdodd#include "truss.h" 4631567Ssef 47288424Sjhbstatic int 48288424Sjhbamd64_linux32_fetch_args(struct trussinfo *trussinfo, u_int narg) 49240562Szont{ 50240005Szont struct reg regs; 51288424Sjhb struct current_syscall *cs; 52240562Szont lwpid_t tid; 5331567Ssef 54240562Szont tid = trussinfo->curthread->tid; 55288424Sjhb cs = &trussinfo->curthread->cs; 56240562Szont if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 57240005Szont fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 58288424Sjhb return (-1); 59240005Szont } 6031567Ssef 61240005Szont /* 62240005Szont * Linux passes syscall arguments in registers, not 63240005Szont * on the stack. Fortunately, we've got access to the 64240005Szont * register set. Note that we don't bother checking the 65240005Szont * number of arguments. And what does linux do for syscalls 66240005Szont * that have more than five arguments? 67240005Szont */ 68288424Sjhb switch (narg) { 69288424Sjhb default: 70288424Sjhb cs->args[5] = regs.r_rbp; /* Unconfirmed */ 71288424Sjhb case 5: 72288424Sjhb cs->args[4] = regs.r_rdi; 73288424Sjhb case 4: 74288424Sjhb cs->args[3] = regs.r_rsi; 75288424Sjhb case 3: 76288424Sjhb cs->args[2] = regs.r_rdx; 77288424Sjhb case 2: 78288424Sjhb cs->args[1] = regs.r_rcx; 79288424Sjhb case 1: 80288424Sjhb cs->args[0] = regs.r_rbx; 81240005Szont } 8231567Ssef 83288424Sjhb return (0); 8431567Ssef} 8531567Ssef 86288424Sjhbstatic int 87288424Sjhbamd64_linux32_fetch_retval(struct trussinfo *trussinfo, long *retval, 88288424Sjhb int *errorp) 89122348Smarcel{ 90240005Szont struct reg regs; 91240562Szont lwpid_t tid; 9231567Ssef 93240562Szont tid = trussinfo->curthread->tid; 94240562Szont if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 95240005Szont fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 96240005Szont return (-1); 97240005Szont } 9831567Ssef 99288424Sjhb retval[0] = regs.r_rax & 0xffffffff; 100288424Sjhb retval[1] = regs.r_rdx & 0xffffffff; 101288424Sjhb *errorp = !!(regs.r_rflags & PSL_C); 102295636Sjhb if (*errorp) 103295636Sjhb retval[0] = (int)retval[0]; 104288424Sjhb return (0); 105288424Sjhb} 106171055Sdelphij 107288424Sjhbstatic struct procabi amd64_linux32 = { 108288424Sjhb "Linux ELF32", 109295056Sjhb SYSDECODE_ABI_LINUX32, 110288424Sjhb amd64_linux32_fetch_args, 111288424Sjhb amd64_linux32_fetch_retval 112288424Sjhb}; 113101282Smdodd 114288424SjhbPROCABI(amd64_linux32); 115