symbian-qemu-0.9.1-12/qemu-symbian-svp/linux-user/elfload.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /* This is the Linux kernel elf-loading code, ported into user space */
       
     2 
       
     3 #include <stdio.h>
       
     4 #include <sys/types.h>
       
     5 #include <fcntl.h>
       
     6 #include <errno.h>
       
     7 #include <unistd.h>
       
     8 #include <sys/mman.h>
       
     9 #include <stdlib.h>
       
    10 #include <string.h>
       
    11 
       
    12 #include "qemu.h"
       
    13 #include "disas.h"
       
    14 
       
    15 #ifdef __powerpc64__
       
    16 #undef ARCH_DLINFO
       
    17 #undef ELF_PLATFORM
       
    18 #undef ELF_HWCAP
       
    19 #undef ELF_CLASS
       
    20 #undef ELF_DATA
       
    21 #undef ELF_ARCH
       
    22 #endif
       
    23 
       
    24 /* from personality.h */
       
    25 
       
    26 /*
       
    27  * Flags for bug emulation.
       
    28  *
       
    29  * These occupy the top three bytes.
       
    30  */
       
    31 enum {
       
    32 	ADDR_NO_RANDOMIZE = 	0x0040000,	/* disable randomization of VA space */
       
    33 	FDPIC_FUNCPTRS =	0x0080000,	/* userspace function ptrs point to descriptors
       
    34 						 * (signal handling)
       
    35 						 */
       
    36 	MMAP_PAGE_ZERO =	0x0100000,
       
    37 	ADDR_COMPAT_LAYOUT =	0x0200000,
       
    38 	READ_IMPLIES_EXEC =	0x0400000,
       
    39 	ADDR_LIMIT_32BIT =	0x0800000,
       
    40 	SHORT_INODE =		0x1000000,
       
    41 	WHOLE_SECONDS =		0x2000000,
       
    42 	STICKY_TIMEOUTS	=	0x4000000,
       
    43 	ADDR_LIMIT_3GB = 	0x8000000,
       
    44 };
       
    45 
       
    46 /*
       
    47  * Personality types.
       
    48  *
       
    49  * These go in the low byte.  Avoid using the top bit, it will
       
    50  * conflict with error returns.
       
    51  */
       
    52 enum {
       
    53 	PER_LINUX =		0x0000,
       
    54 	PER_LINUX_32BIT =	0x0000 | ADDR_LIMIT_32BIT,
       
    55 	PER_LINUX_FDPIC =	0x0000 | FDPIC_FUNCPTRS,
       
    56 	PER_SVR4 =		0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
       
    57 	PER_SVR3 =		0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
       
    58 	PER_SCOSVR3 =		0x0003 | STICKY_TIMEOUTS |
       
    59 					 WHOLE_SECONDS | SHORT_INODE,
       
    60 	PER_OSR5 =		0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
       
    61 	PER_WYSEV386 =		0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
       
    62 	PER_ISCR4 =		0x0005 | STICKY_TIMEOUTS,
       
    63 	PER_BSD =		0x0006,
       
    64 	PER_SUNOS =		0x0006 | STICKY_TIMEOUTS,
       
    65 	PER_XENIX =		0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
       
    66 	PER_LINUX32 =		0x0008,
       
    67 	PER_LINUX32_3GB =	0x0008 | ADDR_LIMIT_3GB,
       
    68 	PER_IRIX32 =		0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
       
    69 	PER_IRIXN32 =		0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
       
    70 	PER_IRIX64 =		0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
       
    71 	PER_RISCOS =		0x000c,
       
    72 	PER_SOLARIS =		0x000d | STICKY_TIMEOUTS,
       
    73 	PER_UW7 =		0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
       
    74 	PER_OSF4 =		0x000f,			 /* OSF/1 v4 */
       
    75 	PER_HPUX =		0x0010,
       
    76 	PER_MASK =		0x00ff,
       
    77 };
       
    78 
       
    79 /*
       
    80  * Return the base personality without flags.
       
    81  */
       
    82 #define personality(pers)	(pers & PER_MASK)
       
    83 
       
    84 /* this flag is uneffective under linux too, should be deleted */
       
    85 #ifndef MAP_DENYWRITE
       
    86 #define MAP_DENYWRITE 0
       
    87 #endif
       
    88 
       
    89 /* should probably go in elf.h */
       
    90 #ifndef ELIBBAD
       
    91 #define ELIBBAD 80
       
    92 #endif
       
    93 
       
    94 #ifdef TARGET_I386
       
    95 
       
    96 #define ELF_PLATFORM get_elf_platform()
       
    97 
       
    98 static const char *get_elf_platform(void)
       
    99 {
       
   100     static char elf_platform[] = "i386";
       
   101     int family = (thread_env->cpuid_version >> 8) & 0xff;
       
   102     if (family > 6)
       
   103         family = 6;
       
   104     if (family >= 3)
       
   105         elf_platform[1] = '0' + family;
       
   106     return elf_platform;
       
   107 }
       
   108 
       
   109 #define ELF_HWCAP get_elf_hwcap()
       
   110 
       
   111 static uint32_t get_elf_hwcap(void)
       
   112 {
       
   113   return thread_env->cpuid_features;
       
   114 }
       
   115 
       
   116 #ifdef TARGET_X86_64
       
   117 #define ELF_START_MMAP 0x2aaaaab000ULL
       
   118 #define elf_check_arch(x) ( ((x) == ELF_ARCH) )
       
   119 
       
   120 #define ELF_CLASS      ELFCLASS64
       
   121 #define ELF_DATA       ELFDATA2LSB
       
   122 #define ELF_ARCH       EM_X86_64
       
   123 
       
   124 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   125 {
       
   126     regs->rax = 0;
       
   127     regs->rsp = infop->start_stack;
       
   128     regs->rip = infop->entry;
       
   129 }
       
   130 
       
   131 #else
       
   132 
       
   133 #define ELF_START_MMAP 0x80000000
       
   134 
       
   135 /*
       
   136  * This is used to ensure we don't load something for the wrong architecture.
       
   137  */
       
   138 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
       
   139 
       
   140 /*
       
   141  * These are used to set parameters in the core dumps.
       
   142  */
       
   143 #define ELF_CLASS	ELFCLASS32
       
   144 #define ELF_DATA	ELFDATA2LSB
       
   145 #define ELF_ARCH	EM_386
       
   146 
       
   147 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   148 {
       
   149     regs->esp = infop->start_stack;
       
   150     regs->eip = infop->entry;
       
   151 
       
   152     /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
       
   153        starts %edx contains a pointer to a function which might be
       
   154        registered using `atexit'.  This provides a mean for the
       
   155        dynamic linker to call DT_FINI functions for shared libraries
       
   156        that have been loaded before the code runs.
       
   157 
       
   158        A value of 0 tells we have no such handler.  */
       
   159     regs->edx = 0;
       
   160 }
       
   161 #endif
       
   162 
       
   163 #define USE_ELF_CORE_DUMP
       
   164 #define ELF_EXEC_PAGESIZE	4096
       
   165 
       
   166 #endif
       
   167 
       
   168 #ifdef TARGET_ARM
       
   169 
       
   170 #define ELF_START_MMAP 0x80000000
       
   171 
       
   172 #define elf_check_arch(x) ( (x) == EM_ARM )
       
   173 
       
   174 #define ELF_CLASS	ELFCLASS32
       
   175 #ifdef TARGET_WORDS_BIGENDIAN
       
   176 #define ELF_DATA	ELFDATA2MSB
       
   177 #else
       
   178 #define ELF_DATA	ELFDATA2LSB
       
   179 #endif
       
   180 #define ELF_ARCH	EM_ARM
       
   181 
       
   182 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   183 {
       
   184     abi_long stack = infop->start_stack;
       
   185     memset(regs, 0, sizeof(*regs));
       
   186     regs->ARM_cpsr = 0x10;
       
   187     if (infop->entry & 1)
       
   188       regs->ARM_cpsr |= CPSR_T;
       
   189     regs->ARM_pc = infop->entry & 0xfffffffe;
       
   190     regs->ARM_sp = infop->start_stack;
       
   191     /* FIXME - what to for failure of get_user()? */
       
   192     get_user_ual(regs->ARM_r2, stack + 8); /* envp */
       
   193     get_user_ual(regs->ARM_r1, stack + 4); /* envp */
       
   194     /* XXX: it seems that r0 is zeroed after ! */
       
   195     regs->ARM_r0 = 0;
       
   196     /* For uClinux PIC binaries.  */
       
   197     /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
       
   198     regs->ARM_r10 = infop->start_data;
       
   199 }
       
   200 
       
   201 #define USE_ELF_CORE_DUMP
       
   202 #define ELF_EXEC_PAGESIZE	4096
       
   203 
       
   204 enum
       
   205 {
       
   206   ARM_HWCAP_ARM_SWP       = 1 << 0,
       
   207   ARM_HWCAP_ARM_HALF      = 1 << 1,
       
   208   ARM_HWCAP_ARM_THUMB     = 1 << 2,
       
   209   ARM_HWCAP_ARM_26BIT     = 1 << 3,
       
   210   ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
       
   211   ARM_HWCAP_ARM_FPA       = 1 << 5,
       
   212   ARM_HWCAP_ARM_VFP       = 1 << 6,
       
   213   ARM_HWCAP_ARM_EDSP      = 1 << 7,
       
   214 };
       
   215 
       
   216 #define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \
       
   217                     | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \
       
   218                     | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
       
   219 
       
   220 #endif
       
   221 
       
   222 #ifdef TARGET_SPARC
       
   223 #ifdef TARGET_SPARC64
       
   224 
       
   225 #define ELF_START_MMAP 0x80000000
       
   226 
       
   227 #ifndef TARGET_ABI32
       
   228 #define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
       
   229 #else
       
   230 #define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
       
   231 #endif
       
   232 
       
   233 #define ELF_CLASS   ELFCLASS64
       
   234 #define ELF_DATA    ELFDATA2MSB
       
   235 #define ELF_ARCH    EM_SPARCV9
       
   236 
       
   237 #define STACK_BIAS		2047
       
   238 
       
   239 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   240 {
       
   241 #ifndef TARGET_ABI32
       
   242     regs->tstate = 0;
       
   243 #endif
       
   244     regs->pc = infop->entry;
       
   245     regs->npc = regs->pc + 4;
       
   246     regs->y = 0;
       
   247 #ifdef TARGET_ABI32
       
   248     regs->u_regs[14] = infop->start_stack - 16 * 4;
       
   249 #else
       
   250     if (personality(infop->personality) == PER_LINUX32)
       
   251         regs->u_regs[14] = infop->start_stack - 16 * 4;
       
   252     else
       
   253         regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
       
   254 #endif
       
   255 }
       
   256 
       
   257 #else
       
   258 #define ELF_START_MMAP 0x80000000
       
   259 
       
   260 #define elf_check_arch(x) ( (x) == EM_SPARC )
       
   261 
       
   262 #define ELF_CLASS   ELFCLASS32
       
   263 #define ELF_DATA    ELFDATA2MSB
       
   264 #define ELF_ARCH    EM_SPARC
       
   265 
       
   266 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   267 {
       
   268     regs->psr = 0;
       
   269     regs->pc = infop->entry;
       
   270     regs->npc = regs->pc + 4;
       
   271     regs->y = 0;
       
   272     regs->u_regs[14] = infop->start_stack - 16 * 4;
       
   273 }
       
   274 
       
   275 #endif
       
   276 #endif
       
   277 
       
   278 #ifdef TARGET_PPC
       
   279 
       
   280 #define ELF_START_MMAP 0x80000000
       
   281 
       
   282 #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
       
   283 
       
   284 #define elf_check_arch(x) ( (x) == EM_PPC64 )
       
   285 
       
   286 #define ELF_CLASS	ELFCLASS64
       
   287 
       
   288 #else
       
   289 
       
   290 #define elf_check_arch(x) ( (x) == EM_PPC )
       
   291 
       
   292 #define ELF_CLASS	ELFCLASS32
       
   293 
       
   294 #endif
       
   295 
       
   296 #ifdef TARGET_WORDS_BIGENDIAN
       
   297 #define ELF_DATA	ELFDATA2MSB
       
   298 #else
       
   299 #define ELF_DATA	ELFDATA2LSB
       
   300 #endif
       
   301 #define ELF_ARCH	EM_PPC
       
   302 
       
   303 /*
       
   304  * We need to put in some extra aux table entries to tell glibc what
       
   305  * the cache block size is, so it can use the dcbz instruction safely.
       
   306  */
       
   307 #define AT_DCACHEBSIZE          19
       
   308 #define AT_ICACHEBSIZE          20
       
   309 #define AT_UCACHEBSIZE          21
       
   310 /* A special ignored type value for PPC, for glibc compatibility.  */
       
   311 #define AT_IGNOREPPC            22
       
   312 /*
       
   313  * The requirements here are:
       
   314  * - keep the final alignment of sp (sp & 0xf)
       
   315  * - make sure the 32-bit value at the first 16 byte aligned position of
       
   316  *   AUXV is greater than 16 for glibc compatibility.
       
   317  *   AT_IGNOREPPC is used for that.
       
   318  * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
       
   319  *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
       
   320  */
       
   321 #define DLINFO_ARCH_ITEMS       5
       
   322 #define ARCH_DLINFO                                                     \
       
   323 do {                                                                    \
       
   324         NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \
       
   325         NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \
       
   326         NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \
       
   327         /*                                                              \
       
   328          * Now handle glibc compatibility.                              \
       
   329          */                                                             \
       
   330 	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
       
   331 	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
       
   332  } while (0)
       
   333 
       
   334 static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
       
   335 {
       
   336     abi_ulong pos = infop->start_stack;
       
   337     abi_ulong tmp;
       
   338 #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
       
   339     abi_ulong entry, toc;
       
   340 #endif
       
   341 
       
   342     _regs->gpr[1] = infop->start_stack;
       
   343 #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
       
   344     entry = ldq_raw(infop->entry) + infop->load_addr;
       
   345     toc = ldq_raw(infop->entry + 8) + infop->load_addr;
       
   346     _regs->gpr[2] = toc;
       
   347     infop->entry = entry;
       
   348 #endif
       
   349     _regs->nip = infop->entry;
       
   350     /* Note that isn't exactly what regular kernel does
       
   351      * but this is what the ABI wants and is needed to allow
       
   352      * execution of PPC BSD programs.
       
   353      */
       
   354     /* FIXME - what to for failure of get_user()? */
       
   355     get_user_ual(_regs->gpr[3], pos);
       
   356     pos += sizeof(abi_ulong);
       
   357     _regs->gpr[4] = pos;
       
   358     for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
       
   359         tmp = ldl(pos);
       
   360     _regs->gpr[5] = pos;
       
   361 }
       
   362 
       
   363 #define USE_ELF_CORE_DUMP
       
   364 #define ELF_EXEC_PAGESIZE	4096
       
   365 
       
   366 #endif
       
   367 
       
   368 #ifdef TARGET_MIPS
       
   369 
       
   370 #define ELF_START_MMAP 0x80000000
       
   371 
       
   372 #define elf_check_arch(x) ( (x) == EM_MIPS )
       
   373 
       
   374 #ifdef TARGET_MIPS64
       
   375 #define ELF_CLASS   ELFCLASS64
       
   376 #else
       
   377 #define ELF_CLASS   ELFCLASS32
       
   378 #endif
       
   379 #ifdef TARGET_WORDS_BIGENDIAN
       
   380 #define ELF_DATA	ELFDATA2MSB
       
   381 #else
       
   382 #define ELF_DATA	ELFDATA2LSB
       
   383 #endif
       
   384 #define ELF_ARCH    EM_MIPS
       
   385 
       
   386 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   387 {
       
   388     regs->cp0_status = 2 << CP0St_KSU;
       
   389     regs->cp0_epc = infop->entry;
       
   390     regs->regs[29] = infop->start_stack;
       
   391 }
       
   392 
       
   393 #define USE_ELF_CORE_DUMP
       
   394 #define ELF_EXEC_PAGESIZE        4096
       
   395 
       
   396 #endif /* TARGET_MIPS */
       
   397 
       
   398 #ifdef TARGET_SH4
       
   399 
       
   400 #define ELF_START_MMAP 0x80000000
       
   401 
       
   402 #define elf_check_arch(x) ( (x) == EM_SH )
       
   403 
       
   404 #define ELF_CLASS ELFCLASS32
       
   405 #define ELF_DATA  ELFDATA2LSB
       
   406 #define ELF_ARCH  EM_SH
       
   407 
       
   408 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   409 {
       
   410   /* Check other registers XXXXX */
       
   411   regs->pc = infop->entry;
       
   412   regs->regs[15] = infop->start_stack;
       
   413 }
       
   414 
       
   415 #define USE_ELF_CORE_DUMP
       
   416 #define ELF_EXEC_PAGESIZE        4096
       
   417 
       
   418 #endif
       
   419 
       
   420 #ifdef TARGET_CRIS
       
   421 
       
   422 #define ELF_START_MMAP 0x80000000
       
   423 
       
   424 #define elf_check_arch(x) ( (x) == EM_CRIS )
       
   425 
       
   426 #define ELF_CLASS ELFCLASS32
       
   427 #define ELF_DATA  ELFDATA2LSB
       
   428 #define ELF_ARCH  EM_CRIS
       
   429 
       
   430 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   431 {
       
   432   regs->erp = infop->entry;
       
   433 }
       
   434 
       
   435 #define USE_ELF_CORE_DUMP
       
   436 #define ELF_EXEC_PAGESIZE        8192
       
   437 
       
   438 #endif
       
   439 
       
   440 #ifdef TARGET_M68K
       
   441 
       
   442 #define ELF_START_MMAP 0x80000000
       
   443 
       
   444 #define elf_check_arch(x) ( (x) == EM_68K )
       
   445 
       
   446 #define ELF_CLASS	ELFCLASS32
       
   447 #define ELF_DATA	ELFDATA2MSB
       
   448 #define ELF_ARCH	EM_68K
       
   449 
       
   450 /* ??? Does this need to do anything?
       
   451 #define ELF_PLAT_INIT(_r) */
       
   452 
       
   453 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   454 {
       
   455     regs->usp = infop->start_stack;
       
   456     regs->sr = 0;
       
   457     regs->pc = infop->entry;
       
   458 }
       
   459 
       
   460 #define USE_ELF_CORE_DUMP
       
   461 #define ELF_EXEC_PAGESIZE	8192
       
   462 
       
   463 #endif
       
   464 
       
   465 #ifdef TARGET_ALPHA
       
   466 
       
   467 #define ELF_START_MMAP (0x30000000000ULL)
       
   468 
       
   469 #define elf_check_arch(x) ( (x) == ELF_ARCH )
       
   470 
       
   471 #define ELF_CLASS      ELFCLASS64
       
   472 #define ELF_DATA       ELFDATA2MSB
       
   473 #define ELF_ARCH       EM_ALPHA
       
   474 
       
   475 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
   476 {
       
   477     regs->pc = infop->entry;
       
   478     regs->ps = 8;
       
   479     regs->usp = infop->start_stack;
       
   480     regs->unique = infop->start_data; /* ? */
       
   481     printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",
       
   482            regs->unique, infop->start_data);
       
   483 }
       
   484 
       
   485 #define USE_ELF_CORE_DUMP
       
   486 #define ELF_EXEC_PAGESIZE        8192
       
   487 
       
   488 #endif /* TARGET_ALPHA */
       
   489 
       
   490 #ifndef ELF_PLATFORM
       
   491 #define ELF_PLATFORM (NULL)
       
   492 #endif
       
   493 
       
   494 #ifndef ELF_HWCAP
       
   495 #define ELF_HWCAP 0
       
   496 #endif
       
   497 
       
   498 #ifdef TARGET_ABI32
       
   499 #undef ELF_CLASS
       
   500 #define ELF_CLASS ELFCLASS32
       
   501 #undef bswaptls
       
   502 #define bswaptls(ptr) bswap32s(ptr)
       
   503 #endif
       
   504 
       
   505 #include "elf.h"
       
   506 
       
   507 struct exec
       
   508 {
       
   509   unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
       
   510   unsigned int a_text;   /* length of text, in bytes */
       
   511   unsigned int a_data;   /* length of data, in bytes */
       
   512   unsigned int a_bss;    /* length of uninitialized data area, in bytes */
       
   513   unsigned int a_syms;   /* length of symbol table data in file, in bytes */
       
   514   unsigned int a_entry;  /* start address */
       
   515   unsigned int a_trsize; /* length of relocation info for text, in bytes */
       
   516   unsigned int a_drsize; /* length of relocation info for data, in bytes */
       
   517 };
       
   518 
       
   519 
       
   520 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
       
   521 #define OMAGIC 0407
       
   522 #define NMAGIC 0410
       
   523 #define ZMAGIC 0413
       
   524 #define QMAGIC 0314
       
   525 
       
   526 /* max code+data+bss space allocated to elf interpreter */
       
   527 #define INTERP_MAP_SIZE (32 * 1024 * 1024)
       
   528 
       
   529 /* max code+data+bss+brk space allocated to ET_DYN executables */
       
   530 #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
       
   531 
       
   532 /* Necessary parameters */
       
   533 #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
       
   534 #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
       
   535 #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
       
   536 
       
   537 #define INTERPRETER_NONE 0
       
   538 #define INTERPRETER_AOUT 1
       
   539 #define INTERPRETER_ELF 2
       
   540 
       
   541 #define DLINFO_ITEMS 12
       
   542 
       
   543 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
       
   544 {
       
   545 	memcpy(to, from, n);
       
   546 }
       
   547 
       
   548 static int load_aout_interp(void * exptr, int interp_fd);
       
   549 
       
   550 #ifdef BSWAP_NEEDED
       
   551 static void bswap_ehdr(struct elfhdr *ehdr)
       
   552 {
       
   553     bswap16s(&ehdr->e_type);			/* Object file type */
       
   554     bswap16s(&ehdr->e_machine);		/* Architecture */
       
   555     bswap32s(&ehdr->e_version);		/* Object file version */
       
   556     bswaptls(&ehdr->e_entry);		/* Entry point virtual address */
       
   557     bswaptls(&ehdr->e_phoff);		/* Program header table file offset */
       
   558     bswaptls(&ehdr->e_shoff);		/* Section header table file offset */
       
   559     bswap32s(&ehdr->e_flags);		/* Processor-specific flags */
       
   560     bswap16s(&ehdr->e_ehsize);		/* ELF header size in bytes */
       
   561     bswap16s(&ehdr->e_phentsize);		/* Program header table entry size */
       
   562     bswap16s(&ehdr->e_phnum);		/* Program header table entry count */
       
   563     bswap16s(&ehdr->e_shentsize);		/* Section header table entry size */
       
   564     bswap16s(&ehdr->e_shnum);		/* Section header table entry count */
       
   565     bswap16s(&ehdr->e_shstrndx);		/* Section header string table index */
       
   566 }
       
   567 
       
   568 static void bswap_phdr(struct elf_phdr *phdr)
       
   569 {
       
   570     bswap32s(&phdr->p_type);			/* Segment type */
       
   571     bswaptls(&phdr->p_offset);		/* Segment file offset */
       
   572     bswaptls(&phdr->p_vaddr);		/* Segment virtual address */
       
   573     bswaptls(&phdr->p_paddr);		/* Segment physical address */
       
   574     bswaptls(&phdr->p_filesz);		/* Segment size in file */
       
   575     bswaptls(&phdr->p_memsz);		/* Segment size in memory */
       
   576     bswap32s(&phdr->p_flags);		/* Segment flags */
       
   577     bswaptls(&phdr->p_align);		/* Segment alignment */
       
   578 }
       
   579 
       
   580 static void bswap_shdr(struct elf_shdr *shdr)
       
   581 {
       
   582     bswap32s(&shdr->sh_name);
       
   583     bswap32s(&shdr->sh_type);
       
   584     bswaptls(&shdr->sh_flags);
       
   585     bswaptls(&shdr->sh_addr);
       
   586     bswaptls(&shdr->sh_offset);
       
   587     bswaptls(&shdr->sh_size);
       
   588     bswap32s(&shdr->sh_link);
       
   589     bswap32s(&shdr->sh_info);
       
   590     bswaptls(&shdr->sh_addralign);
       
   591     bswaptls(&shdr->sh_entsize);
       
   592 }
       
   593 
       
   594 static void bswap_sym(struct elf_sym *sym)
       
   595 {
       
   596     bswap32s(&sym->st_name);
       
   597     bswaptls(&sym->st_value);
       
   598     bswaptls(&sym->st_size);
       
   599     bswap16s(&sym->st_shndx);
       
   600 }
       
   601 #endif
       
   602 
       
   603 /*
       
   604  * 'copy_elf_strings()' copies argument/envelope strings from user
       
   605  * memory to free pages in kernel mem. These are in a format ready
       
   606  * to be put directly into the top of new user memory.
       
   607  *
       
   608  */
       
   609 static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
       
   610                                   abi_ulong p)
       
   611 {
       
   612     char *tmp, *tmp1, *pag = NULL;
       
   613     int len, offset = 0;
       
   614 
       
   615     if (!p) {
       
   616 	return 0;       /* bullet-proofing */
       
   617     }
       
   618     while (argc-- > 0) {
       
   619         tmp = argv[argc];
       
   620         if (!tmp) {
       
   621 	    fprintf(stderr, "VFS: argc is wrong");
       
   622 	    exit(-1);
       
   623 	}
       
   624         tmp1 = tmp;
       
   625 	while (*tmp++);
       
   626 	len = tmp - tmp1;
       
   627 	if (p < len) {  /* this shouldn't happen - 128kB */
       
   628 		return 0;
       
   629 	}
       
   630 	while (len) {
       
   631 	    --p; --tmp; --len;
       
   632 	    if (--offset < 0) {
       
   633 		offset = p % TARGET_PAGE_SIZE;
       
   634                 pag = (char *)page[p/TARGET_PAGE_SIZE];
       
   635                 if (!pag) {
       
   636                     pag = (char *)malloc(TARGET_PAGE_SIZE);
       
   637                     memset(pag, 0, TARGET_PAGE_SIZE);
       
   638                     page[p/TARGET_PAGE_SIZE] = pag;
       
   639                     if (!pag)
       
   640                         return 0;
       
   641 		}
       
   642 	    }
       
   643 	    if (len == 0 || offset == 0) {
       
   644 	        *(pag + offset) = *tmp;
       
   645 	    }
       
   646 	    else {
       
   647 	      int bytes_to_copy = (len > offset) ? offset : len;
       
   648 	      tmp -= bytes_to_copy;
       
   649 	      p -= bytes_to_copy;
       
   650 	      offset -= bytes_to_copy;
       
   651 	      len -= bytes_to_copy;
       
   652 	      memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
       
   653 	    }
       
   654 	}
       
   655     }
       
   656     return p;
       
   657 }
       
   658 
       
   659 static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
       
   660                                  struct image_info *info)
       
   661 {
       
   662     abi_ulong stack_base, size, error;
       
   663     int i;
       
   664 
       
   665     /* Create enough stack to hold everything.  If we don't use
       
   666      * it for args, we'll use it for something else...
       
   667      */
       
   668     size = x86_stack_size;
       
   669     if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
       
   670         size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
       
   671     error = target_mmap(0,
       
   672                         size + qemu_host_page_size,
       
   673                         PROT_READ | PROT_WRITE,
       
   674                         MAP_PRIVATE | MAP_ANONYMOUS,
       
   675                         -1, 0);
       
   676     if (error == -1) {
       
   677         perror("stk mmap");
       
   678         exit(-1);
       
   679     }
       
   680     /* we reserve one extra page at the top of the stack as guard */
       
   681     target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
       
   682 
       
   683     stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
       
   684     p += stack_base;
       
   685 
       
   686     for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
       
   687 	if (bprm->page[i]) {
       
   688 	    info->rss++;
       
   689             /* FIXME - check return value of memcpy_to_target() for failure */
       
   690 	    memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
       
   691 	    free(bprm->page[i]);
       
   692 	}
       
   693         stack_base += TARGET_PAGE_SIZE;
       
   694     }
       
   695     info->stack_base = stack_base;
       
   696     return p;
       
   697 }
       
   698 
       
   699 static void set_brk(abi_ulong start, abi_ulong end)
       
   700 {
       
   701 	/* page-align the start and end addresses... */
       
   702         start = HOST_PAGE_ALIGN(start);
       
   703         end = HOST_PAGE_ALIGN(end);
       
   704         if (end <= start)
       
   705                 return;
       
   706         if(target_mmap(start, end - start,
       
   707                        PROT_READ | PROT_WRITE | PROT_EXEC,
       
   708                        MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
       
   709 	    perror("cannot mmap brk");
       
   710 	    exit(-1);
       
   711 	}
       
   712 }
       
   713 
       
   714 
       
   715 /* We need to explicitly zero any fractional pages after the data
       
   716    section (i.e. bss).  This would contain the junk from the file that
       
   717    should not be in memory. */
       
   718 static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
       
   719 {
       
   720         abi_ulong nbyte;
       
   721 
       
   722 	if (elf_bss >= last_bss)
       
   723 		return;
       
   724 
       
   725         /* XXX: this is really a hack : if the real host page size is
       
   726            smaller than the target page size, some pages after the end
       
   727            of the file may not be mapped. A better fix would be to
       
   728            patch target_mmap(), but it is more complicated as the file
       
   729            size must be known */
       
   730         if (qemu_real_host_page_size < qemu_host_page_size) {
       
   731             abi_ulong end_addr, end_addr1;
       
   732             end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
       
   733                 ~(qemu_real_host_page_size - 1);
       
   734             end_addr = HOST_PAGE_ALIGN(elf_bss);
       
   735             if (end_addr1 < end_addr) {
       
   736                 mmap((void *)g2h(end_addr1), end_addr - end_addr1,
       
   737                      PROT_READ|PROT_WRITE|PROT_EXEC,
       
   738                      MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
       
   739             }
       
   740         }
       
   741 
       
   742         nbyte = elf_bss & (qemu_host_page_size-1);
       
   743         if (nbyte) {
       
   744 	    nbyte = qemu_host_page_size - nbyte;
       
   745 	    do {
       
   746                 /* FIXME - what to do if put_user() fails? */
       
   747 		put_user_u8(0, elf_bss);
       
   748                 elf_bss++;
       
   749 	    } while (--nbyte);
       
   750         }
       
   751 }
       
   752 
       
   753 
       
   754 static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
       
   755                                    struct elfhdr * exec,
       
   756                                    abi_ulong load_addr,
       
   757                                    abi_ulong load_bias,
       
   758                                    abi_ulong interp_load_addr, int ibcs,
       
   759                                    struct image_info *info)
       
   760 {
       
   761         abi_ulong sp;
       
   762         int size;
       
   763         abi_ulong u_platform;
       
   764         const char *k_platform;
       
   765         const int n = sizeof(elf_addr_t);
       
   766 
       
   767         sp = p;
       
   768         u_platform = 0;
       
   769         k_platform = ELF_PLATFORM;
       
   770         if (k_platform) {
       
   771             size_t len = strlen(k_platform) + 1;
       
   772             sp -= (len + n - 1) & ~(n - 1);
       
   773             u_platform = sp;
       
   774             /* FIXME - check return value of memcpy_to_target() for failure */
       
   775             memcpy_to_target(sp, k_platform, len);
       
   776         }
       
   777 	/*
       
   778 	 * Force 16 byte _final_ alignment here for generality.
       
   779 	 */
       
   780         sp = sp &~ (abi_ulong)15;
       
   781         size = (DLINFO_ITEMS + 1) * 2;
       
   782         if (k_platform)
       
   783           size += 2;
       
   784 #ifdef DLINFO_ARCH_ITEMS
       
   785 	size += DLINFO_ARCH_ITEMS * 2;
       
   786 #endif
       
   787         size += envc + argc + 2;
       
   788 	size += (!ibcs ? 3 : 1);	/* argc itself */
       
   789         size *= n;
       
   790         if (size & 15)
       
   791             sp -= 16 - (size & 15);
       
   792 
       
   793         /* This is correct because Linux defines
       
   794          * elf_addr_t as Elf32_Off / Elf64_Off
       
   795          */
       
   796 #define NEW_AUX_ENT(id, val) do {		\
       
   797             sp -= n; put_user_ual(val, sp);	\
       
   798             sp -= n; put_user_ual(id, sp);	\
       
   799           } while(0)
       
   800 
       
   801         NEW_AUX_ENT (AT_NULL, 0);
       
   802 
       
   803         /* There must be exactly DLINFO_ITEMS entries here.  */
       
   804         NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
       
   805         NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
       
   806         NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
       
   807         NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
       
   808         NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
       
   809         NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
       
   810         NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
       
   811         NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
       
   812         NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
       
   813         NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
       
   814         NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
       
   815         NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
       
   816         NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
       
   817         if (k_platform)
       
   818             NEW_AUX_ENT(AT_PLATFORM, u_platform);
       
   819 #ifdef ARCH_DLINFO
       
   820 	/*
       
   821 	 * ARCH_DLINFO must come last so platform specific code can enforce
       
   822 	 * special alignment requirements on the AUXV if necessary (eg. PPC).
       
   823 	 */
       
   824         ARCH_DLINFO;
       
   825 #endif
       
   826 #undef NEW_AUX_ENT
       
   827 
       
   828         sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
       
   829         return sp;
       
   830 }
       
   831 
       
   832 
       
   833 static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
       
   834                                  int interpreter_fd,
       
   835                                  abi_ulong *interp_load_addr)
       
   836 {
       
   837 	struct elf_phdr *elf_phdata  =  NULL;
       
   838 	struct elf_phdr *eppnt;
       
   839 	abi_ulong load_addr = 0;
       
   840 	int load_addr_set = 0;
       
   841 	int retval;
       
   842 	abi_ulong last_bss, elf_bss;
       
   843 	abi_ulong error;
       
   844 	int i;
       
   845 
       
   846 	elf_bss = 0;
       
   847 	last_bss = 0;
       
   848 	error = 0;
       
   849 
       
   850 #ifdef BSWAP_NEEDED
       
   851         bswap_ehdr(interp_elf_ex);
       
   852 #endif
       
   853 	/* First of all, some simple consistency checks */
       
   854 	if ((interp_elf_ex->e_type != ET_EXEC &&
       
   855              interp_elf_ex->e_type != ET_DYN) ||
       
   856 	   !elf_check_arch(interp_elf_ex->e_machine)) {
       
   857 		return ~((abi_ulong)0UL);
       
   858 	}
       
   859 
       
   860 
       
   861 	/* Now read in all of the header information */
       
   862 
       
   863 	if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
       
   864 	    return ~(abi_ulong)0UL;
       
   865 
       
   866 	elf_phdata =  (struct elf_phdr *)
       
   867 		malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
       
   868 
       
   869 	if (!elf_phdata)
       
   870 	  return ~((abi_ulong)0UL);
       
   871 
       
   872 	/*
       
   873 	 * If the size of this structure has changed, then punt, since
       
   874 	 * we will be doing the wrong thing.
       
   875 	 */
       
   876 	if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
       
   877 	    free(elf_phdata);
       
   878 	    return ~((abi_ulong)0UL);
       
   879         }
       
   880 
       
   881 	retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
       
   882 	if(retval >= 0) {
       
   883 	    retval = read(interpreter_fd,
       
   884 			   (char *) elf_phdata,
       
   885 			   sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
       
   886 	}
       
   887 	if (retval < 0) {
       
   888 		perror("load_elf_interp");
       
   889 		exit(-1);
       
   890 		free (elf_phdata);
       
   891 		return retval;
       
   892  	}
       
   893 #ifdef BSWAP_NEEDED
       
   894 	eppnt = elf_phdata;
       
   895 	for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
       
   896             bswap_phdr(eppnt);
       
   897         }
       
   898 #endif
       
   899 
       
   900         if (interp_elf_ex->e_type == ET_DYN) {
       
   901             /* in order to avoid hardcoding the interpreter load
       
   902                address in qemu, we allocate a big enough memory zone */
       
   903             error = target_mmap(0, INTERP_MAP_SIZE,
       
   904                                 PROT_NONE, MAP_PRIVATE | MAP_ANON,
       
   905                                 -1, 0);
       
   906             if (error == -1) {
       
   907                 perror("mmap");
       
   908                 exit(-1);
       
   909             }
       
   910             load_addr = error;
       
   911             load_addr_set = 1;
       
   912         }
       
   913 
       
   914 	eppnt = elf_phdata;
       
   915 	for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
       
   916 	  if (eppnt->p_type == PT_LOAD) {
       
   917 	    int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
       
   918 	    int elf_prot = 0;
       
   919 	    abi_ulong vaddr = 0;
       
   920 	    abi_ulong k;
       
   921 
       
   922 	    if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
       
   923 	    if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
       
   924 	    if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
       
   925 	    if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
       
   926 	    	elf_type |= MAP_FIXED;
       
   927 	    	vaddr = eppnt->p_vaddr;
       
   928 	    }
       
   929 	    error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
       
   930 		 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
       
   931 		 elf_prot,
       
   932 		 elf_type,
       
   933 		 interpreter_fd,
       
   934 		 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
       
   935 
       
   936 	    if (error == -1) {
       
   937 	      /* Real error */
       
   938 	      close(interpreter_fd);
       
   939 	      free(elf_phdata);
       
   940 	      return ~((abi_ulong)0UL);
       
   941 	    }
       
   942 
       
   943 	    if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
       
   944 	      load_addr = error;
       
   945 	      load_addr_set = 1;
       
   946 	    }
       
   947 
       
   948 	    /*
       
   949 	     * Find the end of the file  mapping for this phdr, and keep
       
   950 	     * track of the largest address we see for this.
       
   951 	     */
       
   952 	    k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
       
   953 	    if (k > elf_bss) elf_bss = k;
       
   954 
       
   955 	    /*
       
   956 	     * Do the same thing for the memory mapping - between
       
   957 	     * elf_bss and last_bss is the bss section.
       
   958 	     */
       
   959 	    k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
       
   960 	    if (k > last_bss) last_bss = k;
       
   961 	  }
       
   962 
       
   963 	/* Now use mmap to map the library into memory. */
       
   964 
       
   965 	close(interpreter_fd);
       
   966 
       
   967 	/*
       
   968 	 * Now fill out the bss section.  First pad the last page up
       
   969 	 * to the page boundary, and then perform a mmap to make sure
       
   970 	 * that there are zeromapped pages up to and including the last
       
   971 	 * bss page.
       
   972 	 */
       
   973 	padzero(elf_bss, last_bss);
       
   974 	elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
       
   975 
       
   976 	/* Map the last of the bss segment */
       
   977 	if (last_bss > elf_bss) {
       
   978             target_mmap(elf_bss, last_bss-elf_bss,
       
   979                         PROT_READ|PROT_WRITE|PROT_EXEC,
       
   980                         MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
       
   981 	}
       
   982 	free(elf_phdata);
       
   983 
       
   984 	*interp_load_addr = load_addr;
       
   985 	return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
       
   986 }
       
   987 
       
   988 static int symfind(const void *s0, const void *s1)
       
   989 {
       
   990     struct elf_sym *key = (struct elf_sym *)s0;
       
   991     struct elf_sym *sym = (struct elf_sym *)s1;
       
   992     int result = 0;
       
   993     if (key->st_value < sym->st_value) {
       
   994         result = -1;
       
   995     } else if (key->st_value > sym->st_value + sym->st_size) {
       
   996         result = 1;
       
   997     }
       
   998     return result;
       
   999 }
       
  1000 
       
  1001 static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
       
  1002 {
       
  1003 #if ELF_CLASS == ELFCLASS32
       
  1004     struct elf_sym *syms = s->disas_symtab.elf32;
       
  1005 #else
       
  1006     struct elf_sym *syms = s->disas_symtab.elf64;
       
  1007 #endif
       
  1008 
       
  1009     // binary search
       
  1010     struct elf_sym key;
       
  1011     struct elf_sym *sym;
       
  1012 
       
  1013     key.st_value = orig_addr;
       
  1014 
       
  1015     sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), symfind);
       
  1016     if (sym != 0) {
       
  1017         return s->disas_strtab + sym->st_name;
       
  1018     }
       
  1019 
       
  1020     return "";
       
  1021 }
       
  1022 
       
  1023 /* FIXME: This should use elf_ops.h  */
       
  1024 static int symcmp(const void *s0, const void *s1)
       
  1025 {
       
  1026     struct elf_sym *sym0 = (struct elf_sym *)s0;
       
  1027     struct elf_sym *sym1 = (struct elf_sym *)s1;
       
  1028     return (sym0->st_value < sym1->st_value)
       
  1029         ? -1
       
  1030         : ((sym0->st_value > sym1->st_value) ? 1 : 0);
       
  1031 }
       
  1032 
       
  1033 /* Best attempt to load symbols from this ELF object. */
       
  1034 static void load_symbols(struct elfhdr *hdr, int fd)
       
  1035 {
       
  1036     unsigned int i, nsyms;
       
  1037     struct elf_shdr sechdr, symtab, strtab;
       
  1038     char *strings;
       
  1039     struct syminfo *s;
       
  1040     struct elf_sym *syms;
       
  1041 
       
  1042     lseek(fd, hdr->e_shoff, SEEK_SET);
       
  1043     for (i = 0; i < hdr->e_shnum; i++) {
       
  1044         if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
       
  1045             return;
       
  1046 #ifdef BSWAP_NEEDED
       
  1047         bswap_shdr(&sechdr);
       
  1048 #endif
       
  1049         if (sechdr.sh_type == SHT_SYMTAB) {
       
  1050             symtab = sechdr;
       
  1051             lseek(fd, hdr->e_shoff
       
  1052                   + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
       
  1053             if (read(fd, &strtab, sizeof(strtab))
       
  1054                 != sizeof(strtab))
       
  1055                 return;
       
  1056 #ifdef BSWAP_NEEDED
       
  1057             bswap_shdr(&strtab);
       
  1058 #endif
       
  1059             goto found;
       
  1060         }
       
  1061     }
       
  1062     return; /* Shouldn't happen... */
       
  1063 
       
  1064  found:
       
  1065     /* Now know where the strtab and symtab are.  Snarf them. */
       
  1066     s = malloc(sizeof(*s));
       
  1067     syms = malloc(symtab.sh_size);
       
  1068     if (!syms)
       
  1069         return;
       
  1070     s->disas_strtab = strings = malloc(strtab.sh_size);
       
  1071     if (!s->disas_strtab)
       
  1072         return;
       
  1073 
       
  1074     lseek(fd, symtab.sh_offset, SEEK_SET);
       
  1075     if (read(fd, syms, symtab.sh_size) != symtab.sh_size)
       
  1076         return;
       
  1077 
       
  1078     nsyms = symtab.sh_size / sizeof(struct elf_sym);
       
  1079 
       
  1080     i = 0;
       
  1081     while (i < nsyms) {
       
  1082 #ifdef BSWAP_NEEDED
       
  1083         bswap_sym(syms + i);
       
  1084 #endif
       
  1085         // Throw away entries which we do not need.
       
  1086         if (syms[i].st_shndx == SHN_UNDEF ||
       
  1087                 syms[i].st_shndx >= SHN_LORESERVE ||
       
  1088                 ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
       
  1089             nsyms--;
       
  1090             if (i < nsyms) {
       
  1091                 syms[i] = syms[nsyms];
       
  1092             }
       
  1093             continue;
       
  1094         }
       
  1095 #if defined(TARGET_ARM) || defined (TARGET_MIPS)
       
  1096         /* The bottom address bit marks a Thumb or MIPS16 symbol.  */
       
  1097         syms[i].st_value &= ~(target_ulong)1;
       
  1098 #endif
       
  1099         i++;
       
  1100     }
       
  1101     syms = realloc(syms, nsyms * sizeof(*syms));
       
  1102 
       
  1103     qsort(syms, nsyms, sizeof(*syms), symcmp);
       
  1104 
       
  1105     lseek(fd, strtab.sh_offset, SEEK_SET);
       
  1106     if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
       
  1107         return;
       
  1108     s->disas_num_syms = nsyms;
       
  1109 #if ELF_CLASS == ELFCLASS32
       
  1110     s->disas_symtab.elf32 = syms;
       
  1111     s->lookup_symbol = lookup_symbolxx;
       
  1112 #else
       
  1113     s->disas_symtab.elf64 = syms;
       
  1114     s->lookup_symbol = lookup_symbolxx;
       
  1115 #endif
       
  1116     s->next = syminfos;
       
  1117     syminfos = s;
       
  1118 }
       
  1119 
       
  1120 int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
       
  1121                     struct image_info * info)
       
  1122 {
       
  1123     struct elfhdr elf_ex;
       
  1124     struct elfhdr interp_elf_ex;
       
  1125     struct exec interp_ex;
       
  1126     int interpreter_fd = -1; /* avoid warning */
       
  1127     abi_ulong load_addr, load_bias;
       
  1128     int load_addr_set = 0;
       
  1129     unsigned int interpreter_type = INTERPRETER_NONE;
       
  1130     unsigned char ibcs2_interpreter;
       
  1131     int i;
       
  1132     abi_ulong mapped_addr;
       
  1133     struct elf_phdr * elf_ppnt;
       
  1134     struct elf_phdr *elf_phdata;
       
  1135     abi_ulong elf_bss, k, elf_brk;
       
  1136     int retval;
       
  1137     char * elf_interpreter;
       
  1138     abi_ulong elf_entry, interp_load_addr = 0;
       
  1139     int status;
       
  1140     abi_ulong start_code, end_code, start_data, end_data;
       
  1141     abi_ulong reloc_func_desc = 0;
       
  1142     abi_ulong elf_stack;
       
  1143     char passed_fileno[6];
       
  1144 
       
  1145     ibcs2_interpreter = 0;
       
  1146     status = 0;
       
  1147     load_addr = 0;
       
  1148     load_bias = 0;
       
  1149     elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
       
  1150 #ifdef BSWAP_NEEDED
       
  1151     bswap_ehdr(&elf_ex);
       
  1152 #endif
       
  1153 
       
  1154     /* First of all, some simple consistency checks */
       
  1155     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
       
  1156        				(! elf_check_arch(elf_ex.e_machine))) {
       
  1157 	    return -ENOEXEC;
       
  1158     }
       
  1159 
       
  1160     bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
       
  1161     bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
       
  1162     bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
       
  1163     if (!bprm->p) {
       
  1164         retval = -E2BIG;
       
  1165     }
       
  1166 
       
  1167     /* Now read in all of the header information */
       
  1168     elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
       
  1169     if (elf_phdata == NULL) {
       
  1170 	return -ENOMEM;
       
  1171     }
       
  1172 
       
  1173     retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
       
  1174     if(retval > 0) {
       
  1175 	retval = read(bprm->fd, (char *) elf_phdata,
       
  1176 				elf_ex.e_phentsize * elf_ex.e_phnum);
       
  1177     }
       
  1178 
       
  1179     if (retval < 0) {
       
  1180 	perror("load_elf_binary");
       
  1181 	exit(-1);
       
  1182 	free (elf_phdata);
       
  1183 	return -errno;
       
  1184     }
       
  1185 
       
  1186 #ifdef BSWAP_NEEDED
       
  1187     elf_ppnt = elf_phdata;
       
  1188     for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
       
  1189         bswap_phdr(elf_ppnt);
       
  1190     }
       
  1191 #endif
       
  1192     elf_ppnt = elf_phdata;
       
  1193 
       
  1194     elf_bss = 0;
       
  1195     elf_brk = 0;
       
  1196 
       
  1197 
       
  1198     elf_stack = ~((abi_ulong)0UL);
       
  1199     elf_interpreter = NULL;
       
  1200     start_code = ~((abi_ulong)0UL);
       
  1201     end_code = 0;
       
  1202     start_data = 0;
       
  1203     end_data = 0;
       
  1204     interp_ex.a_info = 0;
       
  1205 
       
  1206     for(i=0;i < elf_ex.e_phnum; i++) {
       
  1207 	if (elf_ppnt->p_type == PT_INTERP) {
       
  1208 	    if ( elf_interpreter != NULL )
       
  1209 	    {
       
  1210 		free (elf_phdata);
       
  1211 		free(elf_interpreter);
       
  1212 		close(bprm->fd);
       
  1213 		return -EINVAL;
       
  1214 	    }
       
  1215 
       
  1216 	    /* This is the program interpreter used for
       
  1217 	     * shared libraries - for now assume that this
       
  1218 	     * is an a.out format binary
       
  1219 	     */
       
  1220 
       
  1221 	    elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
       
  1222 
       
  1223 	    if (elf_interpreter == NULL) {
       
  1224 		free (elf_phdata);
       
  1225 		close(bprm->fd);
       
  1226 		return -ENOMEM;
       
  1227 	    }
       
  1228 
       
  1229 	    retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
       
  1230 	    if(retval >= 0) {
       
  1231 		retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
       
  1232 	    }
       
  1233 	    if(retval < 0) {
       
  1234 	 	perror("load_elf_binary2");
       
  1235 		exit(-1);
       
  1236 	    }
       
  1237 
       
  1238 	    /* If the program interpreter is one of these two,
       
  1239 	       then assume an iBCS2 image. Otherwise assume
       
  1240 	       a native linux image. */
       
  1241 
       
  1242 	    /* JRP - Need to add X86 lib dir stuff here... */
       
  1243 
       
  1244 	    if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
       
  1245 		strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
       
  1246 	      ibcs2_interpreter = 1;
       
  1247 	    }
       
  1248 
       
  1249 #if 0
       
  1250 	    printf("Using ELF interpreter %s\n", elf_interpreter);
       
  1251 #endif
       
  1252 	    if (retval >= 0) {
       
  1253 		retval = open(path(elf_interpreter), O_RDONLY);
       
  1254 		if(retval >= 0) {
       
  1255 		    interpreter_fd = retval;
       
  1256 		}
       
  1257 		else {
       
  1258 		    perror(elf_interpreter);
       
  1259 		    exit(-1);
       
  1260 		    /* retval = -errno; */
       
  1261 		}
       
  1262 	    }
       
  1263 
       
  1264 	    if (retval >= 0) {
       
  1265 		retval = lseek(interpreter_fd, 0, SEEK_SET);
       
  1266 		if(retval >= 0) {
       
  1267 		    retval = read(interpreter_fd,bprm->buf,128);
       
  1268 		}
       
  1269 	    }
       
  1270 	    if (retval >= 0) {
       
  1271 		interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
       
  1272 		interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
       
  1273 	    }
       
  1274 	    if (retval < 0) {
       
  1275 		perror("load_elf_binary3");
       
  1276 		exit(-1);
       
  1277 		free (elf_phdata);
       
  1278 		free(elf_interpreter);
       
  1279 		close(bprm->fd);
       
  1280 		return retval;
       
  1281 	    }
       
  1282 	}
       
  1283 	elf_ppnt++;
       
  1284     }
       
  1285 
       
  1286     /* Some simple consistency checks for the interpreter */
       
  1287     if (elf_interpreter){
       
  1288 	interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
       
  1289 
       
  1290 	/* Now figure out which format our binary is */
       
  1291 	if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
       
  1292 	    	(N_MAGIC(interp_ex) != QMAGIC)) {
       
  1293 	  interpreter_type = INTERPRETER_ELF;
       
  1294 	}
       
  1295 
       
  1296 	if (interp_elf_ex.e_ident[0] != 0x7f ||
       
  1297             strncmp((char *)&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
       
  1298 	    interpreter_type &= ~INTERPRETER_ELF;
       
  1299 	}
       
  1300 
       
  1301 	if (!interpreter_type) {
       
  1302 	    free(elf_interpreter);
       
  1303 	    free(elf_phdata);
       
  1304 	    close(bprm->fd);
       
  1305 	    return -ELIBBAD;
       
  1306 	}
       
  1307     }
       
  1308 
       
  1309     /* OK, we are done with that, now set up the arg stuff,
       
  1310        and then start this sucker up */
       
  1311 
       
  1312     {
       
  1313 	char * passed_p;
       
  1314 
       
  1315 	if (interpreter_type == INTERPRETER_AOUT) {
       
  1316 	    snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
       
  1317 	    passed_p = passed_fileno;
       
  1318 
       
  1319 	    if (elf_interpreter) {
       
  1320 		bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);
       
  1321 		bprm->argc++;
       
  1322 	    }
       
  1323 	}
       
  1324 	if (!bprm->p) {
       
  1325 	    if (elf_interpreter) {
       
  1326 	        free(elf_interpreter);
       
  1327 	    }
       
  1328 	    free (elf_phdata);
       
  1329 	    close(bprm->fd);
       
  1330 	    return -E2BIG;
       
  1331 	}
       
  1332     }
       
  1333 
       
  1334     /* OK, This is the point of no return */
       
  1335     info->end_data = 0;
       
  1336     info->end_code = 0;
       
  1337     info->start_mmap = (abi_ulong)ELF_START_MMAP;
       
  1338     info->mmap = 0;
       
  1339     info->elf_flags = elf_ex.e_flags;
       
  1340     elf_entry = (abi_ulong) elf_ex.e_entry;
       
  1341 
       
  1342     /* Do this so that we can load the interpreter, if need be.  We will
       
  1343        change some of these later */
       
  1344     info->rss = 0;
       
  1345     bprm->p = setup_arg_pages(bprm->p, bprm, info);
       
  1346     info->start_stack = bprm->p;
       
  1347 
       
  1348     /* Now we do a little grungy work by mmaping the ELF image into
       
  1349      * the correct location in memory.  At this point, we assume that
       
  1350      * the image should be loaded at fixed address, not at a variable
       
  1351      * address.
       
  1352      */
       
  1353 
       
  1354     for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
       
  1355         int elf_prot = 0;
       
  1356         int elf_flags = 0;
       
  1357         abi_ulong error;
       
  1358 
       
  1359 	if (elf_ppnt->p_type != PT_LOAD)
       
  1360             continue;
       
  1361 
       
  1362         if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
       
  1363         if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
       
  1364         if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
       
  1365         elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
       
  1366         if (elf_ex.e_type == ET_EXEC || load_addr_set) {
       
  1367             elf_flags |= MAP_FIXED;
       
  1368         } else if (elf_ex.e_type == ET_DYN) {
       
  1369             /* Try and get dynamic programs out of the way of the default mmap
       
  1370                base, as well as whatever program they might try to exec.  This
       
  1371                is because the brk will follow the loader, and is not movable.  */
       
  1372             /* NOTE: for qemu, we do a big mmap to get enough space
       
  1373                without hardcoding any address */
       
  1374             error = target_mmap(0, ET_DYN_MAP_SIZE,
       
  1375                                 PROT_NONE, MAP_PRIVATE | MAP_ANON,
       
  1376                                 -1, 0);
       
  1377             if (error == -1) {
       
  1378                 perror("mmap");
       
  1379                 exit(-1);
       
  1380             }
       
  1381             load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
       
  1382         }
       
  1383 
       
  1384         error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
       
  1385                             (elf_ppnt->p_filesz +
       
  1386                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
       
  1387                             elf_prot,
       
  1388                             (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
       
  1389                             bprm->fd,
       
  1390                             (elf_ppnt->p_offset -
       
  1391                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
       
  1392         if (error == -1) {
       
  1393             perror("mmap");
       
  1394             exit(-1);
       
  1395         }
       
  1396 
       
  1397 #ifdef LOW_ELF_STACK
       
  1398         if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
       
  1399             elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
       
  1400 #endif
       
  1401 
       
  1402         if (!load_addr_set) {
       
  1403             load_addr_set = 1;
       
  1404             load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
       
  1405             if (elf_ex.e_type == ET_DYN) {
       
  1406                 load_bias += error -
       
  1407                     TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
       
  1408                 load_addr += load_bias;
       
  1409                 reloc_func_desc = load_bias;
       
  1410             }
       
  1411         }
       
  1412         k = elf_ppnt->p_vaddr;
       
  1413         if (k < start_code)
       
  1414             start_code = k;
       
  1415         if (start_data < k)
       
  1416             start_data = k;
       
  1417         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
       
  1418         if (k > elf_bss)
       
  1419             elf_bss = k;
       
  1420         if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
       
  1421             end_code = k;
       
  1422         if (end_data < k)
       
  1423             end_data = k;
       
  1424         k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
       
  1425         if (k > elf_brk) elf_brk = k;
       
  1426     }
       
  1427 
       
  1428     elf_entry += load_bias;
       
  1429     elf_bss += load_bias;
       
  1430     elf_brk += load_bias;
       
  1431     start_code += load_bias;
       
  1432     end_code += load_bias;
       
  1433     start_data += load_bias;
       
  1434     end_data += load_bias;
       
  1435 
       
  1436     if (elf_interpreter) {
       
  1437 	if (interpreter_type & 1) {
       
  1438 	    elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
       
  1439 	}
       
  1440 	else if (interpreter_type & 2) {
       
  1441 	    elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
       
  1442 					    &interp_load_addr);
       
  1443 	}
       
  1444         reloc_func_desc = interp_load_addr;
       
  1445 
       
  1446 	close(interpreter_fd);
       
  1447 	free(elf_interpreter);
       
  1448 
       
  1449 	if (elf_entry == ~((abi_ulong)0UL)) {
       
  1450 	    printf("Unable to load interpreter\n");
       
  1451 	    free(elf_phdata);
       
  1452 	    exit(-1);
       
  1453 	    return 0;
       
  1454 	}
       
  1455     }
       
  1456 
       
  1457     free(elf_phdata);
       
  1458 
       
  1459     if (loglevel)
       
  1460 	load_symbols(&elf_ex, bprm->fd);
       
  1461 
       
  1462     if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
       
  1463     info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
       
  1464 
       
  1465 #ifdef LOW_ELF_STACK
       
  1466     info->start_stack = bprm->p = elf_stack - 4;
       
  1467 #endif
       
  1468     bprm->p = create_elf_tables(bprm->p,
       
  1469 		    bprm->argc,
       
  1470 		    bprm->envc,
       
  1471                     &elf_ex,
       
  1472                     load_addr, load_bias,
       
  1473 		    interp_load_addr,
       
  1474 		    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
       
  1475 		    info);
       
  1476     info->load_addr = reloc_func_desc;
       
  1477     info->start_brk = info->brk = elf_brk;
       
  1478     info->end_code = end_code;
       
  1479     info->start_code = start_code;
       
  1480     info->start_data = start_data;
       
  1481     info->end_data = end_data;
       
  1482     info->start_stack = bprm->p;
       
  1483 
       
  1484     /* Calling set_brk effectively mmaps the pages that we need for the bss and break
       
  1485        sections */
       
  1486     set_brk(elf_bss, elf_brk);
       
  1487 
       
  1488     padzero(elf_bss, elf_brk);
       
  1489 
       
  1490 #if 0
       
  1491     printf("(start_brk) %x\n" , info->start_brk);
       
  1492     printf("(end_code) %x\n" , info->end_code);
       
  1493     printf("(start_code) %x\n" , info->start_code);
       
  1494     printf("(end_data) %x\n" , info->end_data);
       
  1495     printf("(start_stack) %x\n" , info->start_stack);
       
  1496     printf("(brk) %x\n" , info->brk);
       
  1497 #endif
       
  1498 
       
  1499     if ( info->personality == PER_SVR4 )
       
  1500     {
       
  1501 	    /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
       
  1502 	       and some applications "depend" upon this behavior.
       
  1503 	       Since we do not have the power to recompile these, we
       
  1504 	       emulate the SVr4 behavior.  Sigh.  */
       
  1505 	    mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
       
  1506                                       MAP_FIXED | MAP_PRIVATE, -1, 0);
       
  1507     }
       
  1508 
       
  1509     info->entry = elf_entry;
       
  1510 
       
  1511     return 0;
       
  1512 }
       
  1513 
       
  1514 static int load_aout_interp(void * exptr, int interp_fd)
       
  1515 {
       
  1516     printf("a.out interpreter not yet supported\n");
       
  1517     return(0);
       
  1518 }
       
  1519 
       
  1520 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
       
  1521 {
       
  1522     init_thread(regs, infop);
       
  1523 }