Teach kdump to decode linux syscalls names too.
Fix bug introduced in my previous commit: the kernel always dump native signal numbers, so no need to check the ABI in ktrpsig(). Suggested by: jhb MFC after: 1 Month.
This commit is contained in:
parent
141aca1ff0
commit
dde5f9b938
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=219138
@ -1,15 +1,23 @@
|
|||||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.if (${MACHINE_ARCH} == "amd64")
|
||||||
|
SFX= 32
|
||||||
|
.endif
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/../ktrace
|
.PATH: ${.CURDIR}/../ktrace
|
||||||
|
|
||||||
PROG= kdump
|
PROG= kdump
|
||||||
SRCS= kdump.c ioctl.c kdump_subr.c subr.c
|
SRCS= kdump.c ioctl.c kdump_subr.c subr.c
|
||||||
CFLAGS+= -I${.CURDIR}/../ktrace -I${.CURDIR} -I${.CURDIR}/../..
|
CFLAGS+= -I${.CURDIR}/../ktrace -I${.CURDIR} -I${.CURDIR}/../..
|
||||||
|
|
||||||
|
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
|
||||||
|
SRCS+= linux_syscalls.c
|
||||||
|
.endif
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
|
|
||||||
CLEANFILES= ioctl.c kdump_subr.c
|
CLEANFILES= ioctl.c kdump_subr.c linux_syscalls.c
|
||||||
|
|
||||||
ioctl.c: mkioctls
|
ioctl.c: mkioctls
|
||||||
sh ${.CURDIR}/mkioctls ${DESTDIR}/usr/include > ${.TARGET}
|
sh ${.CURDIR}/mkioctls ${DESTDIR}/usr/include > ${.TARGET}
|
||||||
@ -17,4 +25,10 @@ ioctl.c: mkioctls
|
|||||||
kdump_subr.c: mksubr
|
kdump_subr.c: mksubr
|
||||||
sh ${.CURDIR}/mksubr ${DESTDIR}/usr/include > ${.TARGET}
|
sh ${.CURDIR}/mksubr ${DESTDIR}/usr/include > ${.TARGET}
|
||||||
|
|
||||||
|
linux_syscalls.c:
|
||||||
|
/bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh \
|
||||||
|
${.CURDIR}/../../sys/${MACHINE_ARCH}/linux${SFX}/syscalls.master ${.CURDIR}/linux_syscalls.conf
|
||||||
|
echo "int nlinux_syscalls = sizeof(linux_syscallnames) / sizeof(linux_syscallnames[0]);" \
|
||||||
|
>> linux_syscalls.c
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
@ -93,7 +93,7 @@ void ktrnamei(char *, int);
|
|||||||
void hexdump(char *, int, int);
|
void hexdump(char *, int, int);
|
||||||
void visdump(char *, int, int);
|
void visdump(char *, int, int);
|
||||||
void ktrgenio(struct ktr_genio *, int);
|
void ktrgenio(struct ktr_genio *, int);
|
||||||
void ktrpsig(struct ktr_psig *, u_int);
|
void ktrpsig(struct ktr_psig *);
|
||||||
void ktrcsw(struct ktr_csw *);
|
void ktrcsw(struct ktr_csw *);
|
||||||
void ktruser(int, unsigned char *);
|
void ktruser(int, unsigned char *);
|
||||||
void ktrsockaddr(struct sockaddr *);
|
void ktrsockaddr(struct sockaddr *);
|
||||||
@ -111,6 +111,41 @@ struct ktr_header ktr_header;
|
|||||||
#define TIME_FORMAT "%b %e %T %Y"
|
#define TIME_FORMAT "%b %e %T %Y"
|
||||||
#define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
|
#define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
|
||||||
|
|
||||||
|
#define print_number(i,n,c) do { \
|
||||||
|
if (decimal) \
|
||||||
|
printf("%c%ld", c, (long)*i); \
|
||||||
|
else \
|
||||||
|
printf("%c%#lx", c, (long)*i); \
|
||||||
|
i++; \
|
||||||
|
n--; \
|
||||||
|
c = ','; \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
|
||||||
|
void linux_ktrsyscall(struct ktr_syscall *);
|
||||||
|
void linux_ktrsysret(struct ktr_sysret *);
|
||||||
|
extern char *linux_syscallnames[];
|
||||||
|
extern int nlinux_syscalls;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* from linux.h
|
||||||
|
* Linux syscalls return negative errno's, we do positive and map them
|
||||||
|
*/
|
||||||
|
static int bsd_to_linux_errno[ELAST + 1] = {
|
||||||
|
-0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
|
||||||
|
-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
|
||||||
|
-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
|
||||||
|
-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
|
||||||
|
-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
|
||||||
|
-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
|
||||||
|
-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
|
||||||
|
-116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
|
||||||
|
-6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
|
||||||
|
-72, -67, -71
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct proc_info
|
struct proc_info
|
||||||
{
|
{
|
||||||
TAILQ_ENTRY(proc_info) info;
|
TAILQ_ENTRY(proc_info) info;
|
||||||
@ -233,10 +268,20 @@ main(int argc, char *argv[])
|
|||||||
drop_logged = 0;
|
drop_logged = 0;
|
||||||
switch (ktr_header.ktr_type) {
|
switch (ktr_header.ktr_type) {
|
||||||
case KTR_SYSCALL:
|
case KTR_SYSCALL:
|
||||||
ktrsyscall((struct ktr_syscall *)m, sv_flags);
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
|
||||||
|
linux_ktrsyscall((struct ktr_syscall *)m);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
ktrsyscall((struct ktr_syscall *)m, sv_flags);
|
||||||
break;
|
break;
|
||||||
case KTR_SYSRET:
|
case KTR_SYSRET:
|
||||||
ktrsysret((struct ktr_sysret *)m, sv_flags);
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
|
||||||
|
linux_ktrsysret((struct ktr_sysret *)m);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
ktrsysret((struct ktr_sysret *)m, sv_flags);
|
||||||
break;
|
break;
|
||||||
case KTR_NAMEI:
|
case KTR_NAMEI:
|
||||||
case KTR_SYSCTL:
|
case KTR_SYSCTL:
|
||||||
@ -246,7 +291,7 @@ main(int argc, char *argv[])
|
|||||||
ktrgenio((struct ktr_genio *)m, ktrlen);
|
ktrgenio((struct ktr_genio *)m, ktrlen);
|
||||||
break;
|
break;
|
||||||
case KTR_PSIG:
|
case KTR_PSIG:
|
||||||
ktrpsig((struct ktr_psig *)m, sv_flags);
|
ktrpsig((struct ktr_psig *)m);
|
||||||
break;
|
break;
|
||||||
case KTR_CSW:
|
case KTR_CSW:
|
||||||
ktrcsw((struct ktr_csw *)m);
|
ktrcsw((struct ktr_csw *)m);
|
||||||
@ -455,17 +500,6 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags)
|
|||||||
char c = '(';
|
char c = '(';
|
||||||
if (fancy &&
|
if (fancy &&
|
||||||
(flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
|
(flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
|
||||||
|
|
||||||
#define print_number(i,n,c) do { \
|
|
||||||
if (decimal) \
|
|
||||||
(void)printf("%c%ld", c, (long)*i); \
|
|
||||||
else \
|
|
||||||
(void)printf("%c%#lx", c, (long)*i); \
|
|
||||||
i++; \
|
|
||||||
n--; \
|
|
||||||
c = ','; \
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
if (ktr->ktr_code == SYS_ioctl) {
|
if (ktr->ktr_code == SYS_ioctl) {
|
||||||
const char *cp;
|
const char *cp;
|
||||||
print_number(ip,narg,c);
|
print_number(ip,narg,c);
|
||||||
@ -1093,10 +1127,9 @@ const char *signames[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
ktrpsig(struct ktr_psig *psig, u_int flags)
|
ktrpsig(struct ktr_psig *psig)
|
||||||
{
|
{
|
||||||
if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD &&
|
if (psig->signo > 0 && psig->signo < NSIG)
|
||||||
psig->signo > 0 && psig->signo < NSIG)
|
|
||||||
(void)printf("SIG%s ", signames[psig->signo]);
|
(void)printf("SIG%s ", signames[psig->signo]);
|
||||||
else
|
else
|
||||||
(void)printf("SIG %d ", psig->signo);
|
(void)printf("SIG %d ", psig->signo);
|
||||||
@ -1471,6 +1504,67 @@ ktrstruct(char *buf, size_t buflen)
|
|||||||
printf("invalid record\n");
|
printf("invalid record\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
void
|
||||||
|
linux_ktrsyscall(struct ktr_syscall *ktr)
|
||||||
|
{
|
||||||
|
int narg = ktr->ktr_narg;
|
||||||
|
register_t *ip;
|
||||||
|
|
||||||
|
if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
|
||||||
|
printf("[%d]", ktr->ktr_code);
|
||||||
|
else
|
||||||
|
printf("%s", linux_syscallnames[ktr->ktr_code]);
|
||||||
|
ip = &ktr->ktr_args[0];
|
||||||
|
if (narg) {
|
||||||
|
char c = '(';
|
||||||
|
while (narg > 0)
|
||||||
|
print_number(ip, narg, c);
|
||||||
|
putchar(')');
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
linux_ktrsysret(struct ktr_sysret *ktr)
|
||||||
|
{
|
||||||
|
register_t ret = ktr->ktr_retval;
|
||||||
|
int error = ktr->ktr_error;
|
||||||
|
int code = ktr->ktr_code;
|
||||||
|
|
||||||
|
if (code >= nlinux_syscalls || code < 0)
|
||||||
|
printf("[%d] ", code);
|
||||||
|
else
|
||||||
|
printf("%s ", linux_syscallnames[code]);
|
||||||
|
|
||||||
|
if (error == 0) {
|
||||||
|
if (fancy) {
|
||||||
|
printf("%ld", (long)ret);
|
||||||
|
if (ret < 0 || ret > 9)
|
||||||
|
printf("/%#lx", (long)ret);
|
||||||
|
} else {
|
||||||
|
if (decimal)
|
||||||
|
printf("%ld", (long)ret);
|
||||||
|
else
|
||||||
|
printf("%#lx", (long)ret);
|
||||||
|
}
|
||||||
|
} else if (error == ERESTART)
|
||||||
|
printf("RESTART");
|
||||||
|
else if (error == EJUSTRETURN)
|
||||||
|
printf("JUSTRETURN");
|
||||||
|
else {
|
||||||
|
if (ktr->ktr_error <= ELAST + 1)
|
||||||
|
error = abs(bsd_to_linux_errno[ktr->ktr_error]);
|
||||||
|
else
|
||||||
|
error = 999;
|
||||||
|
printf("-1 errno %d", error);
|
||||||
|
if (fancy)
|
||||||
|
printf(" %s", strerror(ktr->ktr_error));
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
|
11
usr.bin/kdump/linux_syscalls.conf
Normal file
11
usr.bin/kdump/linux_syscalls.conf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
sysnames="linux_syscalls.c"
|
||||||
|
sysproto="/dev/null"
|
||||||
|
sysproto_h=_LINUX_SYSPROTO_H_
|
||||||
|
syshdr="/dev/null"
|
||||||
|
syssw="/dev/null"
|
||||||
|
sysmk="/dev/null"
|
||||||
|
syscallprefix="LINUX_SYS_"
|
||||||
|
switchname="/dev/null"
|
||||||
|
namesname="linux_syscallnames"
|
||||||
|
systrace="/dev/null"
|
Loading…
Reference in New Issue
Block a user