Page MenuHomeFreeBSD

D27625.diff
No OneTemporary

D27625.diff

diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c
--- a/usr.bin/truss/setup.c
+++ b/usr.bin/truss/setup.c
@@ -74,59 +74,72 @@
static struct procabi cloudabi32 = {
- "CloudABI32",
- SYSDECODE_ABI_CLOUDABI32,
- STAILQ_HEAD_INITIALIZER(cloudabi32.extra_syscalls),
- { NULL }
+ .type = "CloudABI32",
+ .abi = SYSDECODE_ABI_CLOUDABI32,
+ .pointer_size = sizeof(uint32_t),
+ .extra_syscalls = STAILQ_HEAD_INITIALIZER(cloudabi32.extra_syscalls),
+ .syscalls = { NULL }
};
static struct procabi cloudabi64 = {
- "CloudABI64",
- SYSDECODE_ABI_CLOUDABI64,
- STAILQ_HEAD_INITIALIZER(cloudabi64.extra_syscalls),
- { NULL }
+ .type = "CloudABI64",
+ .abi = SYSDECODE_ABI_CLOUDABI64,
+ .pointer_size = sizeof(uint64_t),
+ .extra_syscalls = STAILQ_HEAD_INITIALIZER(cloudabi64.extra_syscalls),
+ .syscalls = { NULL }
};
static struct procabi freebsd = {
- "FreeBSD",
- SYSDECODE_ABI_FREEBSD,
- STAILQ_HEAD_INITIALIZER(freebsd.extra_syscalls),
- { NULL }
+ .type = "FreeBSD",
+ .abi = SYSDECODE_ABI_FREEBSD,
+ .pointer_size = sizeof(void *),
+ .extra_syscalls = STAILQ_HEAD_INITIALIZER(freebsd.extra_syscalls),
+ .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,
- STAILQ_HEAD_INITIALIZER(freebsd32.extra_syscalls),
- { NULL }
+ .type = "FreeBSD32",
+ .abi = SYSDECODE_ABI_FREEBSD32,
+ .pointer_size = sizeof(uint32_t),
+ .compat_prefix = "freebsd32",
+ .extra_syscalls = STAILQ_HEAD_INITIALIZER(freebsd32.extra_syscalls),
+ .syscalls = { NULL }
};
#endif
static struct procabi linux = {
- "Linux",
- SYSDECODE_ABI_LINUX,
- STAILQ_HEAD_INITIALIZER(linux.extra_syscalls),
- { NULL }
+ .type = "Linux",
+ .abi = SYSDECODE_ABI_LINUX,
+ .pointer_size = sizeof(void *),
+ .extra_syscalls = STAILQ_HEAD_INITIALIZER(linux.extra_syscalls),
+ .syscalls = { NULL }
};
-#ifdef __LP64__
+#if __SIZEOF_POINTER__ > 4
static struct procabi linux32 = {
- "Linux32",
- SYSDECODE_ABI_LINUX32,
- STAILQ_HEAD_INITIALIZER(linux32.extra_syscalls),
- { NULL }
+ .type = "Linux32",
+ .abi = SYSDECODE_ABI_LINUX32,
+ .pointer_size = sizeof(uint32_t),
+ .extra_syscalls = STAILQ_HEAD_INITIALIZER(linux32.extra_syscalls),
+ .syscalls = { NULL }
};
#endif
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 +150,7 @@
#if defined(__i386__)
{ "FreeBSD a.out", &freebsd },
#endif
-#ifdef __LP64__
+#if __SIZEOF_POINTER__ >= 8
{ "Linux ELF64", &linux },
{ "Linux ELF32", &linux32 },
#else
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -963,7 +963,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
@@ -1008,7 +1007,6 @@
}
}
}
-#endif
static struct syscall *
find_syscall(struct procabi *abi, u_int number)
@@ -1029,10 +1027,13 @@
{
struct extra_syscall *es;
-#ifndef __LP64__
- /* FIXME: should be based on syscall ABI not truss ABI */
- quad_fixup(&sc->decode);
-#endif
+ /*
+ * quad_fixup() is currently needed for all 32-bit ABIs.
+ * TODO: This should probably be a function pointer inside struct
+ * procabi instead.
+ */
+ if (abi->pointer_size == 4)
+ quad_fixup(&sc->decode);
if (number < nitems(abi->syscalls)) {
assert(abi->syscalls[number] == NULL);
@@ -1055,16 +1056,19 @@
get_syscall(struct threadinfo *t, u_int number, u_int nargs)
{
struct syscall *sc;
+ struct procabi *procabi;
const char *sysdecode_name;
+ const char *lookup_name;
const char *name;
u_int i;
- sc = find_syscall(t->proc->abi, number);
+ procabi = t->proc->abi;
+ sc = find_syscall(procabi, number);
if (sc != NULL)
return (sc);
/* Memory is not explicitly deallocated, it's released on exit(). */
- sysdecode_name = sysdecode_syscallname(t->proc->abi->abi, number);
+ sysdecode_name = sysdecode_syscallname(procabi->abi, number);
if (sysdecode_name == NULL)
asprintf(__DECONST(char **, &name), "#%d", number);
else
@@ -1073,8 +1077,14 @@
sc = calloc(1, sizeof(*sc));
sc->name = name;
+ /* Also decode compat syscalls arguments by stripping the prefix. */
+ lookup_name = name;
+ if (procabi->compat_prefix != NULL && strncmp(procabi->compat_prefix,
+ name, strlen(procabi->compat_prefix)) == 0)
+ lookup_name += strlen(procabi->compat_prefix);
+
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->decode = decoded_syscalls[i];
add_syscall(t->proc->abi, number, sc);
return (sc);
@@ -1817,12 +1827,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 +1855,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 +1865,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);
+ for (;;) {
+ 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, ", <inval>");
break;
}
diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h
--- a/usr.bin/truss/truss.h
+++ b/usr.bin/truss/truss.h
@@ -58,6 +58,8 @@
struct procabi {
const char *type;
enum sysdecode_abi abi;
+ size_t pointer_size;
+ const char *compat_prefix;
STAILQ_HEAD(, extra_syscall) extra_syscalls;
struct syscall *syscalls[SYSCALL_NORMAL_COUNT];
};

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 24, 3:26 AM (21 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12624040
Default Alt Text
D27625.diff (7 KB)

Event Timeline