path patch
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@96 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
ec86b0fb3a
commit
32ce63371a
|
@ -19,6 +19,7 @@ TMPH="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.h"
|
||||||
|
|
||||||
# default parameters
|
# default parameters
|
||||||
prefix="/usr/local"
|
prefix="/usr/local"
|
||||||
|
interp_prefix="/usr/gnemul/qemu-i386"
|
||||||
cross_prefix=""
|
cross_prefix=""
|
||||||
cc="gcc"
|
cc="gcc"
|
||||||
host_cc="gcc"
|
host_cc="gcc"
|
||||||
|
@ -89,6 +90,8 @@ for opt do
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
--prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
|
--prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
|
||||||
;;
|
;;
|
||||||
|
--interp-prefix=*) interp_prefix=`echo $opt | cut -d '=' -f 2`
|
||||||
|
;;
|
||||||
--source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
|
--source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
|
||||||
;;
|
;;
|
||||||
--cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
|
--cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
|
||||||
|
@ -172,7 +175,7 @@ EOF
|
||||||
echo "Standard options:"
|
echo "Standard options:"
|
||||||
echo " --help print this message"
|
echo " --help print this message"
|
||||||
echo " --prefix=PREFIX install in PREFIX [$prefix]"
|
echo " --prefix=PREFIX install in PREFIX [$prefix]"
|
||||||
echo " for audio/video/image support"
|
echo " --interp-prefix=PREFIX where to find shared libraries, etc. [$interp_prefix]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Advanced options (experts only):"
|
echo "Advanced options (experts only):"
|
||||||
echo " --source-path=PATH path of source code [$source_path]"
|
echo " --source-path=PATH path of source code [$source_path]"
|
||||||
|
@ -198,7 +201,7 @@ echo "# Automatically generated by configure - do not modify" > config.mak
|
||||||
echo "/* Automatically generated by configure - do not modify */" > $TMPH
|
echo "/* Automatically generated by configure - do not modify */" > $TMPH
|
||||||
|
|
||||||
echo "prefix=$prefix" >> config.mak
|
echo "prefix=$prefix" >> config.mak
|
||||||
echo "#define CONFIG_QEMU_PREFIX \"$prefix\"" >> $TMPH
|
echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix\"" >> $TMPH
|
||||||
echo "MAKE=$make" >> config.mak
|
echo "MAKE=$make" >> config.mak
|
||||||
echo "CC=$cc" >> config.mak
|
echo "CC=$cc" >> config.mak
|
||||||
echo "GCC_MAJOR=$gcc_major" >> config.mak
|
echo "GCC_MAJOR=$gcc_major" >> config.mak
|
||||||
|
|
|
@ -70,7 +70,6 @@ struct linux_binprm {
|
||||||
int fd;
|
int fd;
|
||||||
int e_uid, e_gid;
|
int e_uid, e_gid;
|
||||||
int argc, envc;
|
int argc, envc;
|
||||||
char * interp_prefix; /* prefix for interpreter */
|
|
||||||
char * filename; /* Name of binary */
|
char * filename; /* Name of binary */
|
||||||
unsigned long loader, exec;
|
unsigned long loader, exec;
|
||||||
int dont_iput; /* binfmt handler has put inode */
|
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
|
||||||
* is an a.out format binary
|
* is an a.out format binary
|
||||||
*/
|
*/
|
||||||
|
|
||||||
elf_interpreter = (char *)malloc(elf_ppnt->p_filesz+
|
elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
|
||||||
strlen(bprm->interp_prefix));
|
|
||||||
|
|
||||||
if (elf_interpreter == NULL) {
|
if (elf_interpreter == NULL) {
|
||||||
free (elf_phdata);
|
free (elf_phdata);
|
||||||
|
@ -765,12 +763,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(elf_interpreter, bprm->interp_prefix);
|
|
||||||
retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
|
retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
|
||||||
if(retval >= 0) {
|
if(retval >= 0) {
|
||||||
retval = read(bprm->fd,
|
retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
|
||||||
elf_interpreter+strlen(bprm->interp_prefix),
|
|
||||||
elf_ppnt->p_filesz);
|
|
||||||
}
|
}
|
||||||
if(retval < 0) {
|
if(retval < 0) {
|
||||||
perror("load_elf_binary2");
|
perror("load_elf_binary2");
|
||||||
|
@ -792,7 +787,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
|
||||||
printf("Using ELF interpreter %s\n", elf_interpreter);
|
printf("Using ELF interpreter %s\n", elf_interpreter);
|
||||||
#endif
|
#endif
|
||||||
if (retval >= 0) {
|
if (retval >= 0) {
|
||||||
retval = open(elf_interpreter, O_RDONLY);
|
retval = open(path(elf_interpreter), O_RDONLY);
|
||||||
if(retval >= 0) {
|
if(retval >= 0) {
|
||||||
interpreter_fd = retval;
|
interpreter_fd = retval;
|
||||||
}
|
}
|
||||||
|
@ -1060,8 +1055,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int elf_exec(const char *interp_prefix,
|
int elf_exec(const char * filename, char ** argv, char ** envp,
|
||||||
const char * filename, char ** argv, char ** envp,
|
|
||||||
struct target_pt_regs * regs, struct image_info *infop)
|
struct target_pt_regs * regs, struct image_info *infop)
|
||||||
{
|
{
|
||||||
struct linux_binprm bprm;
|
struct linux_binprm bprm;
|
||||||
|
@ -1080,7 +1074,6 @@ int elf_exec(const char *interp_prefix,
|
||||||
else {
|
else {
|
||||||
bprm.fd = retval;
|
bprm.fd = retval;
|
||||||
}
|
}
|
||||||
bprm.interp_prefix = (char *)interp_prefix;
|
|
||||||
bprm.filename = (char *)filename;
|
bprm.filename = (char *)filename;
|
||||||
bprm.sh_bang = 0;
|
bprm.sh_bang = 0;
|
||||||
bprm.loader = 0;
|
bprm.loader = 0;
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
/* 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 <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "qemu.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);
|
||||||
|
asprintf(&new->pathname, "%s/%s", root, name);
|
||||||
|
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 stabalized (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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_paths(const char *prefix)
|
||||||
|
{
|
||||||
|
if (prefix[0] != '/' ||
|
||||||
|
prefix[0] == '\0' ||
|
||||||
|
!strcmp(prefix, "/"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
base = new_entry("", NULL, prefix+1);
|
||||||
|
base = add_dir_maybe(base);
|
||||||
|
set_parents(base, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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[0] != '/')
|
||||||
|
return name;
|
||||||
|
|
||||||
|
return follow_path(base, name) ?: name;
|
||||||
|
}
|
|
@ -60,8 +60,7 @@ typedef struct TaskState {
|
||||||
|
|
||||||
extern TaskState *first_task_state;
|
extern TaskState *first_task_state;
|
||||||
|
|
||||||
int elf_exec(const char *interp_prefix,
|
int elf_exec(const char * filename, char ** argv, char ** envp,
|
||||||
const char * filename, char ** argv, char ** envp,
|
|
||||||
struct target_pt_regs * regs, struct image_info *infop);
|
struct target_pt_regs * regs, struct image_info *infop);
|
||||||
|
|
||||||
void target_set_brk(char *new_brk);
|
void target_set_brk(char *new_brk);
|
||||||
|
@ -75,5 +74,6 @@ void process_pending_signals(void *cpu_env);
|
||||||
void signal_init(void);
|
void signal_init(void);
|
||||||
int queue_signal(int sig, target_siginfo_t *info);
|
int queue_signal(int sig, target_siginfo_t *info);
|
||||||
void save_v86_state(CPUX86State *env);
|
void save_v86_state(CPUX86State *env);
|
||||||
|
void init_paths(const char *prefix);
|
||||||
|
const char *path(const char *pathname);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue