Commit 32ce63371a6b4d7ad8786ac5d2f95a1e6cdd1af4
1 parent
ec86b0fb
path patch
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@96 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
154 additions
and
16 deletions
configure
@@ -19,6 +19,7 @@ TMPH="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.h" | @@ -19,6 +19,7 @@ TMPH="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.h" | ||
19 | 19 | ||
20 | # default parameters | 20 | # default parameters |
21 | prefix="/usr/local" | 21 | prefix="/usr/local" |
22 | +interp_prefix="/usr/gnemul/qemu-i386" | ||
22 | cross_prefix="" | 23 | cross_prefix="" |
23 | cc="gcc" | 24 | cc="gcc" |
24 | host_cc="gcc" | 25 | host_cc="gcc" |
@@ -89,6 +90,8 @@ for opt do | @@ -89,6 +90,8 @@ for opt do | ||
89 | case "$opt" in | 90 | case "$opt" in |
90 | --prefix=*) prefix=`echo $opt | cut -d '=' -f 2` | 91 | --prefix=*) prefix=`echo $opt | cut -d '=' -f 2` |
91 | ;; | 92 | ;; |
93 | + --interp-prefix=*) interp_prefix=`echo $opt | cut -d '=' -f 2` | ||
94 | + ;; | ||
92 | --source-path=*) source_path=`echo $opt | cut -d '=' -f 2` | 95 | --source-path=*) source_path=`echo $opt | cut -d '=' -f 2` |
93 | ;; | 96 | ;; |
94 | --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` | 97 | --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` |
@@ -172,7 +175,7 @@ EOF | @@ -172,7 +175,7 @@ EOF | ||
172 | echo "Standard options:" | 175 | echo "Standard options:" |
173 | echo " --help print this message" | 176 | echo " --help print this message" |
174 | echo " --prefix=PREFIX install in PREFIX [$prefix]" | 177 | echo " --prefix=PREFIX install in PREFIX [$prefix]" |
175 | -echo " for audio/video/image support" | 178 | +echo " --interp-prefix=PREFIX where to find shared libraries, etc. [$interp_prefix]" |
176 | echo "" | 179 | echo "" |
177 | echo "Advanced options (experts only):" | 180 | echo "Advanced options (experts only):" |
178 | echo " --source-path=PATH path of source code [$source_path]" | 181 | echo " --source-path=PATH path of source code [$source_path]" |
@@ -198,7 +201,7 @@ echo "# Automatically generated by configure - do not modify" > config.mak | @@ -198,7 +201,7 @@ echo "# Automatically generated by configure - do not modify" > config.mak | ||
198 | echo "/* Automatically generated by configure - do not modify */" > $TMPH | 201 | echo "/* Automatically generated by configure - do not modify */" > $TMPH |
199 | 202 | ||
200 | echo "prefix=$prefix" >> config.mak | 203 | echo "prefix=$prefix" >> config.mak |
201 | -echo "#define CONFIG_QEMU_PREFIX \"$prefix\"" >> $TMPH | 204 | +echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix\"" >> $TMPH |
202 | echo "MAKE=$make" >> config.mak | 205 | echo "MAKE=$make" >> config.mak |
203 | echo "CC=$cc" >> config.mak | 206 | echo "CC=$cc" >> config.mak |
204 | echo "GCC_MAJOR=$gcc_major" >> config.mak | 207 | echo "GCC_MAJOR=$gcc_major" >> config.mak |
linux-user/elfload.c
@@ -70,7 +70,6 @@ struct linux_binprm { | @@ -70,7 +70,6 @@ struct linux_binprm { | ||
70 | int fd; | 70 | int fd; |
71 | int e_uid, e_gid; | 71 | int e_uid, e_gid; |
72 | int argc, envc; | 72 | int argc, envc; |
73 | - char * interp_prefix; /* prefix for interpreter */ | ||
74 | char * filename; /* Name of binary */ | 73 | char * filename; /* Name of binary */ |
75 | unsigned long loader, exec; | 74 | unsigned long loader, exec; |
76 | int dont_iput; /* binfmt handler has put inode */ | 75 | int dont_iput; /* binfmt handler has put inode */ |
@@ -756,8 +755,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | @@ -756,8 +755,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | ||
756 | * is an a.out format binary | 755 | * is an a.out format binary |
757 | */ | 756 | */ |
758 | 757 | ||
759 | - elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+ | ||
760 | - strlen(bprm->interp_prefix)); | 758 | + elf_interpreter = (char *)malloc(elf_ppnt->p_filesz); |
761 | 759 | ||
762 | if (elf_interpreter == NULL) { | 760 | if (elf_interpreter == NULL) { |
763 | free (elf_phdata); | 761 | free (elf_phdata); |
@@ -765,12 +763,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | @@ -765,12 +763,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | ||
765 | return -ENOMEM; | 763 | return -ENOMEM; |
766 | } | 764 | } |
767 | 765 | ||
768 | - strcpy(elf_interpreter, bprm->interp_prefix); | ||
769 | retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET); | 766 | retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET); |
770 | if(retval >= 0) { | 767 | if(retval >= 0) { |
771 | - retval = read(bprm->fd, | ||
772 | - elf_interpreter+strlen(bprm->interp_prefix), | ||
773 | - elf_ppnt->p_filesz); | 768 | + retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz); |
774 | } | 769 | } |
775 | if(retval < 0) { | 770 | if(retval < 0) { |
776 | perror("load_elf_binary2"); | 771 | perror("load_elf_binary2"); |
@@ -792,7 +787,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | @@ -792,7 +787,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | ||
792 | printf("Using ELF interpreter %s\n", elf_interpreter); | 787 | printf("Using ELF interpreter %s\n", elf_interpreter); |
793 | #endif | 788 | #endif |
794 | if (retval >= 0) { | 789 | if (retval >= 0) { |
795 | - retval = open(elf_interpreter, O_RDONLY); | 790 | + retval = open(path(elf_interpreter), O_RDONLY); |
796 | if(retval >= 0) { | 791 | if(retval >= 0) { |
797 | interpreter_fd = retval; | 792 | interpreter_fd = retval; |
798 | } | 793 | } |
@@ -1060,8 +1055,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | @@ -1060,8 +1055,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r | ||
1060 | 1055 | ||
1061 | 1056 | ||
1062 | 1057 | ||
1063 | -int elf_exec(const char *interp_prefix, | ||
1064 | - const char * filename, char ** argv, char ** envp, | 1058 | +int elf_exec(const char * filename, char ** argv, char ** envp, |
1065 | struct target_pt_regs * regs, struct image_info *infop) | 1059 | struct target_pt_regs * regs, struct image_info *infop) |
1066 | { | 1060 | { |
1067 | struct linux_binprm bprm; | 1061 | struct linux_binprm bprm; |
@@ -1080,7 +1074,6 @@ int elf_exec(const char *interp_prefix, | @@ -1080,7 +1074,6 @@ int elf_exec(const char *interp_prefix, | ||
1080 | else { | 1074 | else { |
1081 | bprm.fd = retval; | 1075 | bprm.fd = retval; |
1082 | } | 1076 | } |
1083 | - bprm.interp_prefix = (char *)interp_prefix; | ||
1084 | bprm.filename = (char *)filename; | 1077 | bprm.filename = (char *)filename; |
1085 | bprm.sh_bang = 0; | 1078 | bprm.sh_bang = 0; |
1086 | bprm.loader = 0; | 1079 | bprm.loader = 0; |
linux-user/path.c
0 โ 100644
1 | +/* Code to mangle pathnames into those matching a given prefix. | ||
2 | + eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so"); | ||
3 | + | ||
4 | + The assumption is that this area does not change. | ||
5 | +*/ | ||
6 | +#include <sys/types.h> | ||
7 | +#include <dirent.h> | ||
8 | +#include <unistd.h> | ||
9 | +#include <stdlib.h> | ||
10 | +#include <string.h> | ||
11 | +#include <errno.h> | ||
12 | +#include <stdio.h> | ||
13 | +#include "qemu.h" | ||
14 | + | ||
15 | +struct pathelem | ||
16 | +{ | ||
17 | + /* Name of this, eg. lib */ | ||
18 | + char *name; | ||
19 | + /* Full path name, eg. /usr/gnemul/x86-linux/lib. */ | ||
20 | + char *pathname; | ||
21 | + struct pathelem *parent; | ||
22 | + /* Children */ | ||
23 | + unsigned int num_entries; | ||
24 | + struct pathelem *entries[0]; | ||
25 | +}; | ||
26 | + | ||
27 | +static struct pathelem *base; | ||
28 | + | ||
29 | +/* First N chars of S1 match S2, and S2 is N chars long. */ | ||
30 | +static int strneq(const char *s1, unsigned int n, const char *s2) | ||
31 | +{ | ||
32 | + unsigned int i; | ||
33 | + | ||
34 | + for (i = 0; i < n; i++) | ||
35 | + if (s1[i] != s2[i]) | ||
36 | + return 0; | ||
37 | + return s2[i] == 0; | ||
38 | +} | ||
39 | + | ||
40 | +static struct pathelem *add_entry(struct pathelem *root, const char *name); | ||
41 | + | ||
42 | +static struct pathelem *new_entry(const char *root, | ||
43 | + struct pathelem *parent, | ||
44 | + const char *name) | ||
45 | +{ | ||
46 | + struct pathelem *new = malloc(sizeof(*new)); | ||
47 | + new->name = strdup(name); | ||
48 | + asprintf(&new->pathname, "%s/%s", root, name); | ||
49 | + new->num_entries = 0; | ||
50 | + return new; | ||
51 | +} | ||
52 | + | ||
53 | +#define streq(a,b) (strcmp((a), (b)) == 0) | ||
54 | + | ||
55 | +static struct pathelem *add_dir_maybe(struct pathelem *path) | ||
56 | +{ | ||
57 | + DIR *dir; | ||
58 | + | ||
59 | + if ((dir = opendir(path->pathname)) != NULL) { | ||
60 | + struct dirent *dirent; | ||
61 | + | ||
62 | + while ((dirent = readdir(dir)) != NULL) { | ||
63 | + if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){ | ||
64 | + path = add_entry(path, dirent->d_name); | ||
65 | + } | ||
66 | + } | ||
67 | + closedir(dir); | ||
68 | + } | ||
69 | + return path; | ||
70 | +} | ||
71 | + | ||
72 | +static struct pathelem *add_entry(struct pathelem *root, const char *name) | ||
73 | +{ | ||
74 | + root->num_entries++; | ||
75 | + | ||
76 | + root = realloc(root, sizeof(*root) | ||
77 | + + sizeof(root->entries[0])*root->num_entries); | ||
78 | + | ||
79 | + root->entries[root->num_entries-1] = new_entry(root->pathname, root, name); | ||
80 | + root->entries[root->num_entries-1] | ||
81 | + = add_dir_maybe(root->entries[root->num_entries-1]); | ||
82 | + return root; | ||
83 | +} | ||
84 | + | ||
85 | +/* This needs to be done after tree is stabalized (ie. no more reallocs!). */ | ||
86 | +static void set_parents(struct pathelem *child, struct pathelem *parent) | ||
87 | +{ | ||
88 | + unsigned int i; | ||
89 | + | ||
90 | + child->parent = parent; | ||
91 | + for (i = 0; i < child->num_entries; i++) | ||
92 | + set_parents(child->entries[i], child); | ||
93 | +} | ||
94 | + | ||
95 | +void init_paths(const char *prefix) | ||
96 | +{ | ||
97 | + if (prefix[0] != '/' || | ||
98 | + prefix[0] == '\0' || | ||
99 | + !strcmp(prefix, "/")) | ||
100 | + return; | ||
101 | + | ||
102 | + base = new_entry("", NULL, prefix+1); | ||
103 | + base = add_dir_maybe(base); | ||
104 | + set_parents(base, base); | ||
105 | +} | ||
106 | + | ||
107 | +/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */ | ||
108 | +static const char * | ||
109 | +follow_path(const struct pathelem *cursor, const char *name) | ||
110 | +{ | ||
111 | + unsigned int i, namelen; | ||
112 | + | ||
113 | + name += strspn(name, "/"); | ||
114 | + namelen = strcspn(name, "/"); | ||
115 | + | ||
116 | + if (namelen == 0) | ||
117 | + return cursor->pathname; | ||
118 | + | ||
119 | + if (strneq(name, namelen, "..")) | ||
120 | + return follow_path(cursor->parent, name + namelen); | ||
121 | + | ||
122 | + if (strneq(name, namelen, ".")) | ||
123 | + return follow_path(cursor, name + namelen); | ||
124 | + | ||
125 | + for (i = 0; i < cursor->num_entries; i++) | ||
126 | + if (strneq(name, namelen, cursor->entries[i]->name)) | ||
127 | + return follow_path(cursor->entries[i], name + namelen); | ||
128 | + | ||
129 | + /* Not found */ | ||
130 | + return NULL; | ||
131 | +} | ||
132 | + | ||
133 | +/* Look for path in emulation dir, otherwise return name. */ | ||
134 | +const char *path(const char *name) | ||
135 | +{ | ||
136 | + /* Only do absolute paths: quick and dirty, but should mostly be OK. | ||
137 | + Could do relative by tracking cwd. */ | ||
138 | + if (!base || name[0] != '/') | ||
139 | + return name; | ||
140 | + | ||
141 | + return follow_path(base, name) ?: name; | ||
142 | +} |
linux-user/qemu.h
@@ -60,8 +60,7 @@ typedef struct TaskState { | @@ -60,8 +60,7 @@ typedef struct TaskState { | ||
60 | 60 | ||
61 | extern TaskState *first_task_state; | 61 | extern TaskState *first_task_state; |
62 | 62 | ||
63 | -int elf_exec(const char *interp_prefix, | ||
64 | - const char * filename, char ** argv, char ** envp, | 63 | +int elf_exec(const char * filename, char ** argv, char ** envp, |
65 | struct target_pt_regs * regs, struct image_info *infop); | 64 | struct target_pt_regs * regs, struct image_info *infop); |
66 | 65 | ||
67 | void target_set_brk(char *new_brk); | 66 | void target_set_brk(char *new_brk); |
@@ -75,5 +74,6 @@ void process_pending_signals(void *cpu_env); | @@ -75,5 +74,6 @@ void process_pending_signals(void *cpu_env); | ||
75 | void signal_init(void); | 74 | void signal_init(void); |
76 | int queue_signal(int sig, target_siginfo_t *info); | 75 | int queue_signal(int sig, target_siginfo_t *info); |
77 | void save_v86_state(CPUX86State *env); | 76 | void save_v86_state(CPUX86State *env); |
78 | - | 77 | +void init_paths(const char *prefix); |
78 | +const char *path(const char *pathname); | ||
79 | #endif | 79 | #endif |