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)&regs, 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)&regs, 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