Revision 74cd30b8 linux-user/main.c
b/linux-user/main.c | ||
---|---|---|
23 | 23 |
#include <string.h> |
24 | 24 |
#include <errno.h> |
25 | 25 |
#include <unistd.h> |
26 |
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) |
|
27 |
#include <sys/personality.h> |
|
28 |
#endif |
|
29 | 26 |
|
30 | 27 |
#include "qemu.h" |
31 | 28 |
|
... | ... | |
35 | 32 |
|
36 | 33 |
FILE *logfile = NULL; |
37 | 34 |
int loglevel; |
38 |
const char *interp_prefix = CONFIG_QEMU_PREFIX "/qemu-i386";
|
|
35 |
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
|
|
39 | 36 |
|
40 | 37 |
#ifdef __i386__ |
41 | 38 |
/* Force usage of an ELF interpreter even if it is an ELF shared |
42 | 39 |
object ! */ |
43 | 40 |
const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2"; |
41 |
|
|
42 |
/* for recent libc, we add these dummies symbol which are not declared |
|
43 |
when generating a linked object (bug in ld ?) */ |
|
44 |
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) |
|
45 |
long __init_array_start[0]; |
|
46 |
long __init_array_end[0]; |
|
47 |
long __fini_array_start[0]; |
|
48 |
long __fini_array_end[0]; |
|
49 |
#endif |
|
50 |
|
|
44 | 51 |
#endif |
45 | 52 |
|
46 | 53 |
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so |
... | ... | |
358 | 365 |
DEBUG_LOGFILE, |
359 | 366 |
interp_prefix, |
360 | 367 |
x86_stack_size); |
361 |
exit(1); |
|
368 |
_exit(1);
|
|
362 | 369 |
} |
363 | 370 |
|
364 | 371 |
/* XXX: currently only used for async signals (see signal.c) */ |
... | ... | |
379 | 386 |
if (argc <= 1) |
380 | 387 |
usage(); |
381 | 388 |
|
382 |
/* Set personality to X86_LINUX. May fail on unpatched kernels: |
|
383 |
if so, they need to have munged paths themselves (eg. chroot, |
|
384 |
hacked ld.so, whatever). */ |
|
385 |
if (personality(0x11) >= 0) |
|
386 |
interp_prefix = ""; |
|
387 |
|
|
388 | 389 |
loglevel = 0; |
389 | 390 |
optind = 1; |
390 | 391 |
for(;;) { |
... | ... | |
423 | 424 |
logfile = fopen(DEBUG_LOGFILE, "w"); |
424 | 425 |
if (!logfile) { |
425 | 426 |
perror(DEBUG_LOGFILE); |
426 |
exit(1); |
|
427 |
_exit(1);
|
|
427 | 428 |
} |
428 | 429 |
setvbuf(logfile, NULL, _IOLBF, 0); |
429 | 430 |
} |
... | ... | |
434 | 435 |
/* Zero out image_info */ |
435 | 436 |
memset(info, 0, sizeof(struct image_info)); |
436 | 437 |
|
437 |
if(elf_exec(interp_prefix, filename, argv+optind, environ, regs, info) != 0) { |
|
438 |
/* Scan interp_prefix dir for replacement files. */ |
|
439 |
init_paths(interp_prefix); |
|
440 |
|
|
441 |
if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { |
|
438 | 442 |
printf("Error loading %s\n", filename); |
439 |
exit(1); |
|
443 |
_exit(1);
|
|
440 | 444 |
} |
441 | 445 |
|
442 | 446 |
if (loglevel) { |
Also available in: Unified diff