aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Turner <digit@android.com>2010-09-10 11:50:34 +0200
committerDavid 'Digit' Turner <digit@android.com>2010-09-13 00:30:34 -0700
commitb91980562344f6a3b719bfe4be007fa9406e585f (patch)
treed27adae483fb37401a6992a60f008c6ed435919e
parent4143d8f4c302878923bde0cb2420f4ca27245bcd (diff)
downloadexternal_qemu-b91980562344f6a3b719bfe4be007fa9406e585f.zip
external_qemu-b91980562344f6a3b719bfe4be007fa9406e585f.tar.gz
external_qemu-b91980562344f6a3b719bfe4be007fa9406e585f.tar.bz2
upstream: osdep changes + fix mingw build.
-rw-r--r--Makefile.android1
-rw-r--r--hw/goldfish_trace.c82
-rw-r--r--osdep.c26
-rw-r--r--path.c165
-rw-r--r--qemu-common.h4
5 files changed, 237 insertions, 41 deletions
diff --git a/Makefile.android b/Makefile.android
index 4e796d9..0aa294a 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -646,6 +646,7 @@ CORE_MISC_SOURCES = vl-android.c \
cbuffer.c \
gdbstub.c \
ioport.c \
+ path.c \
shaper.c \
charpipe.c \
tcpdump.c \
diff --git a/hw/goldfish_trace.c b/hw/goldfish_trace.c
index 742ac63..a7e589d 100644
--- a/hw/goldfish_trace.c
+++ b/hw/goldfish_trace.c
@@ -27,8 +27,8 @@ extern int tracing;
extern const char *trace_filename;
/* for execve */
-static char path[CLIENT_PAGE_SIZE];
-static char arg[CLIENT_PAGE_SIZE];
+static char exec_path[CLIENT_PAGE_SIZE];
+static char exec_arg[CLIENT_PAGE_SIZE];
static unsigned long vstart; // VM start
static unsigned long vend; // VM end
static unsigned long eoff; // offset in EXE file
@@ -104,47 +104,47 @@ static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t va
eoff = value;
break;
case TRACE_DEV_REG_EXECVE_EXEPATH: // init exec, path of EXE
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
+ vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
if (trace_filename != NULL) {
- trace_init_exec(vstart, vend, eoff, path);
+ trace_init_exec(vstart, vend, eoff, exec_path);
#ifdef DEBUG
printf("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n",
- vstart, vend, eoff, path);
+ vstart, vend, eoff, exec_path);
#endif
}
#ifdef CONFIG_MEMCHECK
if (memcheck_enabled) {
- if (path[0] == '\0') {
+ if (exec_path[0] == '\0') {
// vstrcpy may fail to copy path. In this case lets do it
// differently.
- memcheck_get_guest_kernel_string(path, value, CLIENT_PAGE_SIZE);
+ memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE);
}
- memcheck_mmap_exepath(vstart, vend, eoff, path);
+ memcheck_mmap_exepath(vstart, vend, eoff, exec_path);
}
#endif // CONFIG_MEMCHECK
- path[0] = 0;
+ exec_path[0] = 0;
break;
case TRACE_DEV_REG_CMDLINE_LEN: // execve, process cmdline length
cmdlen = value;
break;
case TRACE_DEV_REG_CMDLINE: // execve, process cmdline
- cpu_memory_rw_debug(cpu_single_env, value, arg, cmdlen, 0);
+ cpu_memory_rw_debug(cpu_single_env, value, exec_arg, cmdlen, 0);
if (trace_filename != NULL) {
- trace_execve(arg, cmdlen);
+ trace_execve(exec_arg, cmdlen);
}
#ifdef CONFIG_MEMCHECK
if (memcheck_enabled) {
- memcheck_set_cmd_line(arg, cmdlen);
+ memcheck_set_cmd_line(exec_arg, cmdlen);
}
#endif // CONFIG_MEMCHECK
#ifdef DEBUG
if (trace_filename != NULL) {
int i;
for (i = 0; i < cmdlen; i ++)
- if (i != cmdlen - 1 && arg[i] == 0)
- arg[i] = ' ';
- printf("QEMU.trace: kernel, execve %s[%d]\n", arg, cmdlen);
- arg[0] = 0;
+ if (i != cmdlen - 1 && exec_arg[i] == 0)
+ exec_arg[i] = ' ';
+ printf("QEMU.trace: kernel, execve %s[%d]\n", exec_arg, cmdlen);
+ exec_arg[0] = 0;
}
#endif
break;
@@ -162,39 +162,39 @@ static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t va
#endif // CONFIG_MEMCHECK
break;
case TRACE_DEV_REG_NAME: // record thread name
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
+ vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
// Remove the trailing newline if it exists
- int len = strlen(path);
- if (path[len - 1] == '\n') {
- path[len - 1] = 0;
+ int len = strlen(exec_path);
+ if (exec_path[len - 1] == '\n') {
+ exec_path[len - 1] = 0;
}
if (trace_filename != NULL) {
- trace_name(path);
+ trace_name(exec_path);
#ifdef DEBUG
- printf("QEMU.trace: kernel, name %s\n", path);
+ printf("QEMU.trace: kernel, name %s\n", exec_path);
#endif
}
break;
case TRACE_DEV_REG_MMAP_EXEPATH: // mmap, path of EXE, the others are same as execve
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
+ vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
if (trace_filename != NULL) {
- trace_mmap(vstart, vend, eoff, path);
+ trace_mmap(vstart, vend, eoff, exec_path);
#ifdef DEBUG
- printf("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, path);
+ printf("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, exec_path);
#endif
}
#ifdef CONFIG_MEMCHECK
if (memcheck_enabled) {
- if (path[0] == '\0') {
+ if (exec_path[0] == '\0') {
// vstrcpy may fail to copy path. In this case lets do it
// differently.
- memcheck_get_guest_kernel_string(path, value, CLIENT_PAGE_SIZE);
+ memcheck_get_guest_kernel_string(exec_path, value, CLIENT_PAGE_SIZE);
}
- memcheck_mmap_exepath(vstart, vend, eoff, path);
+ memcheck_mmap_exepath(vstart, vend, eoff, exec_path);
}
#endif // CONFIG_MEMCHECK
- path[0] = 0;
+ exec_path[0] = 0;
break;
case TRACE_DEV_REG_INIT_PID: // init, name the pid that starts before device registered
pid = value;
@@ -205,28 +205,28 @@ static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t va
#endif // CONFIG_MEMCHECK
break;
case TRACE_DEV_REG_INIT_NAME: // init, the comm of the init pid
- vstrcpy(value, path, CLIENT_PAGE_SIZE);
+ vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
if (trace_filename != NULL) {
- trace_init_name(tgid, pid, path);
+ trace_init_name(tgid, pid, exec_path);
#ifdef DEBUG
- printf("QEMU.trace: kernel, init name %u [%s]\n", pid, path);
+ printf("QEMU.trace: kernel, init name %u [%s]\n", pid, exec_path);
#endif
}
- path[0] = 0;
+ exec_path[0] = 0;
break;
case TRACE_DEV_REG_DYN_SYM_ADDR: // dynamic symbol address
dsaddr = value;
break;
case TRACE_DEV_REG_DYN_SYM: // add dynamic symbol
- vstrcpy(value, arg, CLIENT_PAGE_SIZE);
+ vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE);
if (trace_filename != NULL) {
- trace_dynamic_symbol_add(dsaddr, arg);
+ trace_dynamic_symbol_add(dsaddr, exec_arg);
#ifdef DEBUG
- printf("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, arg);
+ printf("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, exec_arg);
#endif
}
- arg[0] = 0;
+ exec_arg[0] = 0;
break;
case TRACE_DEV_REG_REMOVE_ADDR: // remove dynamic symbol addr
if (trace_filename != NULL) {
@@ -238,9 +238,9 @@ static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t va
break;
case TRACE_DEV_REG_PRINT_STR: // print string
- vstrcpy(value, arg, CLIENT_PAGE_SIZE);
- printf("%s", arg);
- arg[0] = 0;
+ vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE);
+ printf("%s", exec_arg);
+ exec_arg[0] = 0;
break;
case TRACE_DEV_REG_PRINT_NUM_DEC: // print number in decimal
printf("%d", value);
@@ -391,5 +391,5 @@ void trace_dev_init()
goldfish_device_add(&s->dev, trace_dev_readfn, trace_dev_writefn, s);
- path[0] = arg[0] = '\0';
+ exec_path[0] = exec_arg[0] = '\0';
}
diff --git a/osdep.c b/osdep.c
index 37d3001..041ed50 100644
--- a/osdep.c
+++ b/osdep.c
@@ -43,6 +43,8 @@
#ifdef _WIN32
#include <windows.h>
+#include <winsock2.h>
+typedef int32_t socklen_t;
#elif defined(CONFIG_BSD)
#include <stdlib.h>
#else
@@ -392,3 +394,27 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
return ret;
}
+
+#ifdef WIN32
+int asprintf( char **, char *, ... );
+int vasprintf( char **, char *, va_list );
+
+int vasprintf( char **sptr, char *fmt, va_list argv )
+{
+ int wanted = vsnprintf( *sptr = NULL, 0, fmt, argv );
+ if( (wanted > 0) && ((*sptr = malloc( 1 + wanted )) != NULL) )
+ return vsprintf( *sptr, fmt, argv );
+
+ return wanted;
+}
+
+int asprintf( char **sptr, char *fmt, ... )
+{
+ int retval;
+ va_list argv;
+ va_start( argv, fmt );
+ retval = vasprintf( sptr, fmt, argv );
+ va_end( argv );
+ return retval;
+}
+#endif
diff --git a/path.c b/path.c
new file mode 100644
index 0000000..0d2bf14
--- /dev/null
+++ b/path.c
@@ -0,0 +1,165 @@
+/* Code to mangle pathnames into those matching a given prefix.
+ eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so");
+
+ The assumption is that this area does not change.
+*/
+#include <sys/types.h>
+#include <sys/param.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include "qemu-common.h"
+
+struct pathelem
+{
+ /* Name of this, eg. lib */
+ char *name;
+ /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
+ char *pathname;
+ struct pathelem *parent;
+ /* Children */
+ unsigned int num_entries;
+ struct pathelem *entries[0];
+};
+
+static struct pathelem *base;
+
+/* First N chars of S1 match S2, and S2 is N chars long. */
+static int strneq(const char *s1, unsigned int n, const char *s2)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; i++)
+ if (s1[i] != s2[i])
+ return 0;
+ return s2[i] == 0;
+}
+
+static struct pathelem *add_entry(struct pathelem *root, const char *name);
+
+static struct pathelem *new_entry(const char *root,
+ struct pathelem *parent,
+ const char *name)
+{
+ struct pathelem *new = malloc(sizeof(*new));
+ new->name = strdup(name);
+ if (asprintf(&new->pathname, "%s/%s", root, name) == -1) {
+ printf("Cannot allocate memory\n");
+ exit(1);
+ }
+ new->num_entries = 0;
+ return new;
+}
+
+#define streq(a,b) (strcmp((a), (b)) == 0)
+
+static struct pathelem *add_dir_maybe(struct pathelem *path)
+{
+ DIR *dir;
+
+ if ((dir = opendir(path->pathname)) != NULL) {
+ struct dirent *dirent;
+
+ while ((dirent = readdir(dir)) != NULL) {
+ if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
+ path = add_entry(path, dirent->d_name);
+ }
+ }
+ closedir(dir);
+ }
+ return path;
+}
+
+static struct pathelem *add_entry(struct pathelem *root, const char *name)
+{
+ root->num_entries++;
+
+ root = realloc(root, sizeof(*root)
+ + sizeof(root->entries[0])*root->num_entries);
+
+ root->entries[root->num_entries-1] = new_entry(root->pathname, root, name);
+ root->entries[root->num_entries-1]
+ = add_dir_maybe(root->entries[root->num_entries-1]);
+ return root;
+}
+
+/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
+static void set_parents(struct pathelem *child, struct pathelem *parent)
+{
+ unsigned int i;
+
+ child->parent = parent;
+ for (i = 0; i < child->num_entries; i++)
+ set_parents(child->entries[i], child);
+}
+
+/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
+static const char *
+follow_path(const struct pathelem *cursor, const char *name)
+{
+ unsigned int i, namelen;
+
+ name += strspn(name, "/");
+ namelen = strcspn(name, "/");
+
+ if (namelen == 0)
+ return cursor->pathname;
+
+ if (strneq(name, namelen, ".."))
+ return follow_path(cursor->parent, name + namelen);
+
+ if (strneq(name, namelen, "."))
+ return follow_path(cursor, name + namelen);
+
+ for (i = 0; i < cursor->num_entries; i++)
+ if (strneq(name, namelen, cursor->entries[i]->name))
+ return follow_path(cursor->entries[i], name + namelen);
+
+ /* Not found */
+ return NULL;
+}
+
+void init_paths(const char *prefix)
+{
+ char pref_buf[PATH_MAX];
+
+ if (prefix[0] == '\0' ||
+ !strcmp(prefix, "/"))
+ return;
+
+ if (prefix[0] != '/') {
+ char *cwd = getcwd(NULL, 0);
+ size_t pref_buf_len = sizeof(pref_buf);
+
+ if (!cwd)
+ abort();
+ pstrcpy(pref_buf, sizeof(pref_buf), cwd);
+ pstrcat(pref_buf, pref_buf_len, "/");
+ pstrcat(pref_buf, pref_buf_len, prefix);
+ free(cwd);
+ } else
+ pstrcpy(pref_buf, sizeof(pref_buf), prefix + 1);
+
+ base = new_entry("", NULL, pref_buf);
+ base = add_dir_maybe(base);
+ if (base->num_entries == 0) {
+ free (base);
+ base = NULL;
+ } else {
+ set_parents(base, base);
+ }
+}
+
+/* Look for path in emulation dir, otherwise return name. */
+const char *path(const char *name)
+{
+ /* Only do absolute paths: quick and dirty, but should mostly be OK.
+ Could do relative by tracking cwd. */
+ if (!base || !name || name[0] != '/')
+ return name;
+
+ return follow_path(base, name) ?: name;
+}
diff --git a/qemu-common.h b/qemu-common.h
index 73555e1..aba3887 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -138,6 +138,10 @@ int qemu_fls(int i);
int qemu_fdatasync(int fd);
int fcntl_setfl(int fd, int flag);
+/* path.c */
+void init_paths(const char *prefix);
+const char *path(const char *pathname);
+
#define qemu_isalnum(c) isalnum((unsigned char)(c))
#define qemu_isalpha(c) isalpha((unsigned char)(c))
#define qemu_iscntrl(c) iscntrl((unsigned char)(c))