Index: usr.bin/truss/setup.c =================================================================== --- usr.bin/truss/setup.c +++ usr.bin/truss/setup.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,7 @@ static struct procabi cloudabi32 = { "CloudABI32", SYSDECODE_ABI_CLOUDABI32, + sizeof(uint32_t), STAILQ_HEAD_INITIALIZER(cloudabi32.extra_syscalls), { NULL } }; @@ -83,6 +85,7 @@ static struct procabi cloudabi64 = { "CloudABI64", SYSDECODE_ABI_CLOUDABI64, + sizeof(uint64_t), STAILQ_HEAD_INITIALIZER(cloudabi64.extra_syscalls), { NULL } }; @@ -90,14 +93,20 @@ static struct procabi freebsd = { "FreeBSD", SYSDECODE_ABI_FREEBSD, + sizeof(ptrdiff_t), STAILQ_HEAD_INITIALIZER(freebsd.extra_syscalls), { NULL } }; -#ifdef __LP64__ +#if !defined(__SIZEOF_POINTER__) +#error "Use a modern compiler." +#endif + +#if __SIZEOF_POINTER__ > 4 static struct procabi freebsd32 = { "FreeBSD32", SYSDECODE_ABI_FREEBSD32, + sizeof(uint32_t), STAILQ_HEAD_INITIALIZER(freebsd32.extra_syscalls), { NULL } }; @@ -106,14 +115,16 @@ static struct procabi linux = { "Linux", SYSDECODE_ABI_LINUX, + sizeof(ptrdiff_t), STAILQ_HEAD_INITIALIZER(linux.extra_syscalls), { NULL } }; -#ifdef __LP64__ +#if __SIZEOF_POINTER__ > 4 static struct procabi linux32 = { "Linux32", SYSDECODE_ABI_LINUX32, + sizeof(uint32_t), STAILQ_HEAD_INITIALIZER(linux32.extra_syscalls), { NULL } }; @@ -122,7 +133,7 @@ static struct procabi_table abis[] = { { "CloudABI ELF32", &cloudabi32 }, { "CloudABI ELF64", &cloudabi64 }, -#ifdef __LP64__ +#if __SIZEOF_POINTER__ == 8 { "FreeBSD ELF64", &freebsd }, { "FreeBSD ELF32", &freebsd32 }, #else @@ -137,7 +148,7 @@ #if defined(__i386__) { "FreeBSD a.out", &freebsd }, #endif -#ifdef __LP64__ +#if __SIZEOF_POINTER__ >= 8 { "Linux ELF64", &linux }, { "Linux ELF32", &linux32 }, #else @@ -476,11 +487,11 @@ * passed in *and* out, however. */ #if DEBUG - fprintf(stderr, "syscall %s(", sc->name); + fprintf(stderr, "syscall %d %s(", t->cs.number, sc->name); #endif for (i = 0; i < t->cs.nargs; i++) { #if DEBUG - fprintf(stderr, "0x%lx%s", t->cs.args[sc->args[i].offset], + fprintf(stderr, "%p%s", (void*)t->cs.args[sc->args[i].offset], i < (t->cs.nargs - 1) ? "," : ""); #endif if (!(sc->args[i].type & OUT)) { Index: usr.bin/truss/syscalls.c =================================================================== --- usr.bin/truss/syscalls.c +++ usr.bin/truss/syscalls.c @@ -47,11 +47,13 @@ #include #include #include +#include #include #include #include #define _WANT_FREEBSD11_STAT #include +#include #include #include #include @@ -66,8 +68,6 @@ #define _WANT_KERNEL_ERRNO #include #include -#include -#include #include #include #include @@ -1056,6 +1056,7 @@ { struct syscall *sc; const char *name; + const char *lookup_name; char *new_name; u_int i; @@ -1069,8 +1070,29 @@ name = new_name; } else new_name = NULL; + + /* Correctly decode compat syscalls arguments by stripping the prefix */ + if (strncmp("freebsd32_", name, strlen("freebsd32_")) == 0) { + lookup_name = name + strlen("freebsd32_"); + } else if (strncmp("freebsd64_", name, strlen("freebsd64_")) == 0) { + lookup_name = name + strlen("freebsd64_"); + } else { + lookup_name = name; + } + STAILQ_FOREACH(sc, &syscalls, entries) { - if (strcmp(name, sc->name) == 0) { + if (strcmp(lookup_name, sc->name) == 0) { + if (name != lookup_name) { + /* Print the real syscall name in the logs */ + struct syscall *new_sc = + malloc(sizeof(struct syscall)); + *new_sc = *sc; + new_sc->name = name; + /* Ensure that the STAILQ is not linked */ + memset(&new_sc->entries, 0, + sizeof(new_sc->entries)); + sc = new_sc; + } add_syscall(t->proc->abi, number, sc); free(new_name); return (sc); @@ -1819,12 +1841,15 @@ case StringArray: { uintptr_t addr; union { - char *strarray[0]; + int32_t strarray32[0]; /* Sign-extend when casting */ + int64_t strarray64[0]; char buf[PAGE_SIZE]; } u; char *string; size_t len; u_int first, i; + size_t pointer_size = + trussinfo->curthread->proc->abi->pointer_size; /* * Only parse argv[] and environment arrays from exec calls @@ -1844,7 +1869,7 @@ * a partial page. */ addr = args[sc->offset]; - if (addr % sizeof(char *) != 0) { + if (addr % pointer_size != 0) { print_pointer(fp, args[sc->offset]); break; } @@ -1854,22 +1879,36 @@ print_pointer(fp, args[sc->offset]); break; } + assert(len > 0); fputc('[', fp); first = 1; i = 0; - while (u.strarray[i] != NULL) { - string = get_string(pid, (uintptr_t)u.strarray[i], 0); + while (true) { + uintptr_t straddr; + if (pointer_size == 4) { + if (u.strarray32[i] == 0) + break; + /* sign-extend 32-bit pointers */ + straddr = (intptr_t)u.strarray32[i]; + } else if (pointer_size == 8) { + if (u.strarray64[i] == 0) + break; + straddr = (intptr_t)u.strarray64[i]; + } else { + errx(1, "Unsupported pointer size: %zu", + pointer_size); + } + string = get_string(pid, straddr, 0); fprintf(fp, "%s \"%s\"", first ? "" : ",", string); free(string); first = 0; i++; - if (i == len / sizeof(char *)) { + if (i == len / pointer_size) { addr += len; len = PAGE_SIZE; - if (get_struct(pid, addr, u.buf, len) == - -1) { + if (get_struct(pid, addr, u.buf, len) == -1) { fprintf(fp, ", "); break; } Index: usr.bin/truss/truss.h =================================================================== --- usr.bin/truss/truss.h +++ usr.bin/truss/truss.h @@ -58,6 +58,7 @@ struct procabi { const char *type; enum sysdecode_abi abi; + size_t pointer_size; STAILQ_HEAD(, extra_syscall) extra_syscalls; struct syscall *syscalls[SYSCALL_NORMAL_COUNT]; };