Index: usr.bin/truss/setup.c =================================================================== --- usr.bin/truss/setup.c +++ usr.bin/truss/setup.c @@ -76,6 +76,7 @@ static struct procabi cloudabi32 = { "CloudABI32", SYSDECODE_ABI_CLOUDABI32, + sizeof(uint32_t), STAILQ_HEAD_INITIALIZER(cloudabi32.extra_syscalls), { NULL } }; @@ -83,6 +84,7 @@ static struct procabi cloudabi64 = { "CloudABI64", SYSDECODE_ABI_CLOUDABI64, + sizeof(uint64_t), STAILQ_HEAD_INITIALIZER(cloudabi64.extra_syscalls), { NULL } }; @@ -90,14 +92,20 @@ static struct procabi freebsd = { "FreeBSD", SYSDECODE_ABI_FREEBSD, + sizeof(void *), 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 +114,16 @@ static struct procabi linux = { "Linux", SYSDECODE_ABI_LINUX, + sizeof(void *), 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,11 +132,13 @@ static struct procabi_table abis[] = { { "CloudABI ELF32", &cloudabi32 }, { "CloudABI ELF64", &cloudabi64 }, -#ifdef __LP64__ +#if __SIZEOF_POINTER__ == 4 + { "FreeBSD ELF32", &freebsd }, +#elif __SIZEOF_POINTER__ == 8 { "FreeBSD ELF64", &freebsd }, { "FreeBSD ELF32", &freebsd32 }, #else - { "FreeBSD ELF32", &freebsd }, +#error "Unsupported pointer size" #endif #if defined(__powerpc64__) { "FreeBSD ELF64 V2", &freebsd }, @@ -137,7 +149,7 @@ #if defined(__i386__) { "FreeBSD a.out", &freebsd }, #endif -#ifdef __LP64__ +#if __SIZEOF_POINTER__ >= 8 { "Linux ELF64", &linux }, { "Linux ELF32", &linux32 }, #else Index: usr.bin/truss/syscalls.c =================================================================== --- usr.bin/truss/syscalls.c +++ usr.bin/truss/syscalls.c @@ -959,7 +959,6 @@ fprintf(fp, "|0x%x", rem); } -#ifndef __LP64__ /* * Add argument padding to subsequent system calls after Quad * syscall arguments as needed. This used to be done by hand in the @@ -1004,7 +1003,6 @@ } } } -#endif static struct syscall * find_syscall(struct procabi *abi, u_int number) @@ -1025,10 +1023,9 @@ { struct extra_syscall *es; -#ifndef __LP64__ - /* FIXME: should be based on sycall ABI not truss ABI */ - quad_fixup(&sc->info); -#endif + /* TODO: Is quad fixup needed for all 32-bit ABIs or only FreeBSD32? */ + if (abi->pointer_size == 4) + quad_fixup(&sc->info); if (number < nitems(abi->syscalls)) { assert(abi->syscalls[number] == NULL); @@ -1052,6 +1049,7 @@ { struct syscall *sc; const char *sysdecode_name; + const char *lookup_name; char *name; u_int i; @@ -1068,8 +1066,15 @@ sc = calloc(1, sizeof(*sc)); sc->display_name = name; + /* Correctly decode compat syscalls arguments by stripping the prefix */ + if (strncmp("freebsd32_", name, strlen("freebsd32_")) == 0) { + lookup_name = name + strlen("freebsd32_"); + } else { + lookup_name = name; + } + for (i = 0; i < nitems(decoded_syscalls); i++) { - if (strcmp(name, decoded_syscalls[i].name) == 0) { + if (strcmp(lookup_name, decoded_syscalls[i].name) == 0) { sc->info = decoded_syscalls[i]; add_syscall(t->proc->abi, number, sc); return (sc); @@ -1086,7 +1091,7 @@ * Note: info.name is either a constant or points to sc->display_name * which be free'd toger with sc on exit. */ - sc->info.name = name; + sc->info.name = lookup_name; sc->info.ret_type = 1; /* Assume 1 return value. */ sc->info.nargs = nargs; for (i = 0; i < nargs; i++) { @@ -1817,12 +1822,15 @@ case StringArray: { uintptr_t addr; union { - char *strarray[0]; + int32_t strarray32[PAGE_SIZE / sizeof(int32_t)]; + int64_t strarray64[PAGE_SIZE / sizeof(int64_t)]; 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 @@ -1842,7 +1850,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; } @@ -1852,22 +1860,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]; };