summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.bin/truss/syscalls.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index 0df8d9a..91769fb 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -913,36 +913,54 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval,
break;
}
case StringArray: {
- int num, size, i;
- char *tmp2;
+ uintptr_t addr;
+ union {
+ char *strarray[0];
+ char buf[PAGE_SIZE];
+ } u;
char *string;
- char *strarray[100]; /* XXX This is ugly. */
-
- if (get_struct(pid, (void *)args[sc->offset],
- (void *)&strarray, sizeof(strarray)) == -1)
- err(1, "get_struct %p", (void *)args[sc->offset]);
- num = 0;
- size = 0;
-
- /* Find out how large of a buffer we'll need. */
- while (strarray[num] != NULL) {
- string = get_string(pid, (void*)strarray[num], 0);
- size += strlen(string);
- free(string);
- num++;
+ size_t len;
+ int first, i;
+
+ /*
+ * Read a page of pointers at a time. Punt if the top-level
+ * pointer is not aligned. Note that the first read is of
+ * a partial page.
+ */
+ addr = args[sc->offset];
+ if (addr % sizeof(char *) != 0) {
+ fprintf(fp, "0x%lx", args[sc->offset]);
+ break;
+ }
+
+ len = PAGE_SIZE - (addr & PAGE_MASK);
+ if (get_struct(pid, (void *)addr, u.buf, len) == -1) {
+ fprintf(fp, "0x%lx", args[sc->offset]);
+ break;
}
- size += 4 + (num * 4);
- tmp = (char *)malloc(size);
- tmp2 = tmp;
-
- tmp2 += sprintf(tmp2, " [");
- for (i = 0; i < num; i++) {
- string = get_string(pid, (void*)strarray[i], 0);
- tmp2 += sprintf(tmp2, " \"%s\"%c", string,
- (i + 1 == num) ? ' ' : ',');
+
+ fputc('[', fp);
+ first = 1;
+ i = 0;
+ while (u.strarray[i] != NULL) {
+ string = get_string(pid, u.strarray[i], 0);
+ fprintf(fp, "%s \"%s\"", first ? "" : ",", string);
free(string);
+ first = 0;
+
+ i++;
+ if (i == len / sizeof(char *)) {
+ addr += len;
+ len = PAGE_SIZE;
+ if (get_struct(pid, (void *)addr, u.buf, len) ==
+ -1) {
+ fprintf(fp, ", <inval>");
+ break;
+ }
+ i = 0;
+ }
}
- tmp2 += sprintf(tmp2, "]");
+ fputs(" ]", fp);
break;
}
#ifdef __LP64__
OpenPOWER on IntegriCloud