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 | 19 | |
20 | 20 | # default parameters |
21 | 21 | prefix="/usr/local" |
22 | +interp_prefix="/usr/gnemul/qemu-i386" | |
22 | 23 | cross_prefix="" |
23 | 24 | cc="gcc" |
24 | 25 | host_cc="gcc" |
... | ... | @@ -89,6 +90,8 @@ for opt do |
89 | 90 | case "$opt" in |
90 | 91 | --prefix=*) prefix=`echo $opt | cut -d '=' -f 2` |
91 | 92 | ;; |
93 | + --interp-prefix=*) interp_prefix=`echo $opt | cut -d '=' -f 2` | |
94 | + ;; | |
92 | 95 | --source-path=*) source_path=`echo $opt | cut -d '=' -f 2` |
93 | 96 | ;; |
94 | 97 | --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` |
... | ... | @@ -172,7 +175,7 @@ EOF |
172 | 175 | echo "Standard options:" |
173 | 176 | echo " --help print this message" |
174 | 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 | 179 | echo "" |
177 | 180 | echo "Advanced options (experts only):" |
178 | 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 | 201 | echo "/* Automatically generated by configure - do not modify */" > $TMPH |
199 | 202 | |
200 | 203 | echo "prefix=$prefix" >> config.mak |
201 | -echo "#define CONFIG_QEMU_PREFIX \"$prefix\"" >> $TMPH | |
204 | +echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix\"" >> $TMPH | |
202 | 205 | echo "MAKE=$make" >> config.mak |
203 | 206 | echo "CC=$cc" >> config.mak |
204 | 207 | echo "GCC_MAJOR=$gcc_major" >> config.mak | ... | ... |
linux-user/elfload.c
... | ... | @@ -70,7 +70,6 @@ struct linux_binprm { |
70 | 70 | int fd; |
71 | 71 | int e_uid, e_gid; |
72 | 72 | int argc, envc; |
73 | - char * interp_prefix; /* prefix for interpreter */ | |
74 | 73 | char * filename; /* Name of binary */ |
75 | 74 | unsigned long loader, exec; |
76 | 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 | 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 | 760 | if (elf_interpreter == NULL) { |
763 | 761 | free (elf_phdata); |
... | ... | @@ -765,12 +763,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r |
765 | 763 | return -ENOMEM; |
766 | 764 | } |
767 | 765 | |
768 | - strcpy(elf_interpreter, bprm->interp_prefix); | |
769 | 766 | retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET); |
770 | 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 | 770 | if(retval < 0) { |
776 | 771 | perror("load_elf_binary2"); |
... | ... | @@ -792,7 +787,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r |
792 | 787 | printf("Using ELF interpreter %s\n", elf_interpreter); |
793 | 788 | #endif |
794 | 789 | if (retval >= 0) { |
795 | - retval = open(elf_interpreter, O_RDONLY); | |
790 | + retval = open(path(elf_interpreter), O_RDONLY); | |
796 | 791 | if(retval >= 0) { |
797 | 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 | 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 | 1059 | struct target_pt_regs * regs, struct image_info *infop) |
1066 | 1060 | { |
1067 | 1061 | struct linux_binprm bprm; |
... | ... | @@ -1080,7 +1074,6 @@ int elf_exec(const char *interp_prefix, |
1080 | 1074 | else { |
1081 | 1075 | bprm.fd = retval; |
1082 | 1076 | } |
1083 | - bprm.interp_prefix = (char *)interp_prefix; | |
1084 | 1077 | bprm.filename = (char *)filename; |
1085 | 1078 | bprm.sh_bang = 0; |
1086 | 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 | 60 | |
61 | 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 | 64 | struct target_pt_regs * regs, struct image_info *infop); |
66 | 65 | |
67 | 66 | void target_set_brk(char *new_brk); |
... | ... | @@ -75,5 +74,6 @@ void process_pending_signals(void *cpu_env); |
75 | 74 | void signal_init(void); |
76 | 75 | int queue_signal(int sig, target_siginfo_t *info); |
77 | 76 | void save_v86_state(CPUX86State *env); |
78 | - | |
77 | +void init_paths(const char *prefix); | |
78 | +const char *path(const char *pathname); | |
79 | 79 | #endif | ... | ... |