Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/truss/syscalls.c
Show First 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | |||||
#include <time.h> | #include <time.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <vis.h> | #include <vis.h> | ||||
#include "truss.h" | #include "truss.h" | ||||
#include "extern.h" | #include "extern.h" | ||||
#include "syscall.h" | #include "syscall.h" | ||||
/* usr.bin/kdump/utrace.c */ | |||||
int kdump_print_utrace(FILE *, void *, size_t, int); | |||||
/* 64-bit alignment on 32-bit platforms. */ | /* 64-bit alignment on 32-bit platforms. */ | ||||
#if !defined(__LP64__) && defined(__powerpc__) | #if !defined(__LP64__) && defined(__powerpc__) | ||||
#define QUAD_ALIGN 1 | #define QUAD_ALIGN 1 | ||||
#else | #else | ||||
#define QUAD_ALIGN 0 | #define QUAD_ALIGN 0 | ||||
#endif | #endif | ||||
/* Number of slots needed for a 64-bit argument. */ | /* Number of slots needed for a 64-bit argument. */ | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | #endif | ||||
.args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } }, | .args = { { Atfd, 0 }, { Name, 1 }, { Atflags, 2 } } }, | ||||
{ .name = "unmount", .ret_type = 1, .nargs = 2, | { .name = "unmount", .ret_type = 1, .nargs = 2, | ||||
.args = { { Name, 0 }, { Int, 1 } } }, | .args = { { Name, 0 }, { Int, 1 } } }, | ||||
{ .name = "utimensat", .ret_type = 1, .nargs = 4, | { .name = "utimensat", .ret_type = 1, .nargs = 4, | ||||
.args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 }, | .args = { { Atfd, 0 }, { Name | IN, 1 }, { Timespec2 | IN, 2 }, | ||||
{ Atflags, 3 } } }, | { Atflags, 3 } } }, | ||||
{ .name = "utimes", .ret_type = 1, .nargs = 2, | { .name = "utimes", .ret_type = 1, .nargs = 2, | ||||
.args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, | .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, | ||||
{ .name = "utrace", .ret_type = 1, .nargs = 1, | |||||
.args = { { Utrace, 0 } } }, | |||||
{ .name = "wait4", .ret_type = 1, .nargs = 4, | { .name = "wait4", .ret_type = 1, .nargs = 4, | ||||
.args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 }, | .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 }, | ||||
{ Rusage | OUT, 3 } } }, | { Rusage | OUT, 3 } } }, | ||||
{ .name = "wait6", .ret_type = 1, .nargs = 6, | { .name = "wait6", .ret_type = 1, .nargs = 6, | ||||
.args = { { Idtype, 0 }, { Quad, 1 + QUAD_ALIGN }, | .args = { { Idtype, 0 }, { Quad, 1 + QUAD_ALIGN }, | ||||
{ ExitStatus | OUT, 1 + QUAD_ALIGN + QUAD_SLOTS }, | { ExitStatus | OUT, 1 + QUAD_ALIGN + QUAD_SLOTS }, | ||||
{ Waitoptions, 2 + QUAD_ALIGN + QUAD_SLOTS }, | { Waitoptions, 2 + QUAD_ALIGN + QUAD_SLOTS }, | ||||
{ Rusage | OUT, 3 + QUAD_ALIGN + QUAD_SLOTS }, | { Rusage | OUT, 3 + QUAD_ALIGN + QUAD_SLOTS }, | ||||
▲ Show 20 Lines • Show All 502 Lines • ▼ Show 20 Lines | case EVFILT_USER: { | ||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
fprintf(fp, "%#x", ke->fflags); | fprintf(fp, "%#x", ke->fflags); | ||||
} | } | ||||
fprintf(fp, ",%p,%p", (void *)ke->data, (void *)ke->udata); | fprintf(fp, ",%p,%p", (void *)ke->data, (void *)ke->udata); | ||||
} | } | ||||
static void | |||||
print_utrace(FILE *fp, void *utrace_addr, size_t len) | |||||
{ | |||||
unsigned char *utrace_buffer; | |||||
fprintf(fp, "{ "); | |||||
if (kdump_print_utrace(fp, utrace_addr, len, 0)) { | |||||
fprintf(fp, " }"); | |||||
return; | |||||
} | |||||
utrace_buffer = utrace_addr; | |||||
fprintf(fp, "%zu:", len); | |||||
while (len--) | |||||
fprintf(fp, " %02x", *utrace_buffer++); | |||||
fprintf(fp, " }"); | |||||
} | |||||
/* | /* | ||||
* Converts a syscall argument into a string. Said string is | * Converts a syscall argument into a string. Said string is | ||||
* allocated via malloc(), so needs to be free()'d. sc is | * allocated via malloc(), so needs to be free()'d. sc is | ||||
* a pointer to the syscall description (see above); args is | * a pointer to the syscall description (see above); args is | ||||
* an array of all of the system call arguments. | * an array of all of the system call arguments. | ||||
*/ | */ | ||||
char * | char * | ||||
print_arg(struct syscall_args *sc, unsigned long *args, long *retval, | print_arg(struct syscall_args *sc, unsigned long *args, long *retval, | ||||
▲ Show 20 Lines • Show All 725 Lines • ▼ Show 20 Lines | case PipeFds: | ||||
* the returned file descriptors as a fake argument. | * the returned file descriptors as a fake argument. | ||||
* | * | ||||
* Overwrite the first retval to signal a successful | * Overwrite the first retval to signal a successful | ||||
* return as well. | * return as well. | ||||
*/ | */ | ||||
fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]); | fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]); | ||||
retval[0] = 0; | retval[0] = 0; | ||||
break; | break; | ||||
case Utrace: { | |||||
size_t len; | |||||
void *utrace_addr; | |||||
len = args[sc->offset + 1]; | |||||
utrace_addr = calloc(1, len); | |||||
if (get_struct(pid, (void *)args[sc->offset], | |||||
(void *)utrace_addr, len) != -1) | |||||
print_utrace(fp, utrace_addr, len); | |||||
else | |||||
fprintf(fp, "0x%lx", args[sc->offset]); | |||||
free(utrace_addr); | |||||
break; | |||||
} | |||||
default: | default: | ||||
errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); | errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); | ||||
} | } | ||||
fclose(fp); | fclose(fp); | ||||
return (tmp); | return (tmp); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 115 Lines • Show Last 20 Lines |