symbian-qemu-0.9.1-12/qemu-symbian-svp/bsd-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 extern unsigned long x86_stack_size;
       
   549 
       
   550 static int load_aout_interp(void * exptr, int interp_fd);
       
   551 
       
   552 #ifdef BSWAP_NEEDED
       
   553 static void bswap_ehdr(struct elfhdr *ehdr)
       
   554 {
       
   555     bswap16s(&ehdr->e_type);                    /* Object file type */
       
   556     bswap16s(&ehdr->e_machine);         /* Architecture */
       
   557     bswap32s(&ehdr->e_version);         /* Object file version */
       
   558     bswaptls(&ehdr->e_entry);           /* Entry point virtual address */
       
   559     bswaptls(&ehdr->e_phoff);           /* Program header table file offset */
       
   560     bswaptls(&ehdr->e_shoff);           /* Section header table file offset */
       
   561     bswap32s(&ehdr->e_flags);           /* Processor-specific flags */
       
   562     bswap16s(&ehdr->e_ehsize);          /* ELF header size in bytes */
       
   563     bswap16s(&ehdr->e_phentsize);               /* Program header table entry size */
       
   564     bswap16s(&ehdr->e_phnum);           /* Program header table entry count */
       
   565     bswap16s(&ehdr->e_shentsize);               /* Section header table entry size */
       
   566     bswap16s(&ehdr->e_shnum);           /* Section header table entry count */
       
   567     bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */
       
   568 }
       
   569 
       
   570 static void bswap_phdr(struct elf_phdr *phdr)
       
   571 {
       
   572     bswap32s(&phdr->p_type);                    /* Segment type */
       
   573     bswaptls(&phdr->p_offset);          /* Segment file offset */
       
   574     bswaptls(&phdr->p_vaddr);           /* Segment virtual address */
       
   575     bswaptls(&phdr->p_paddr);           /* Segment physical address */
       
   576     bswaptls(&phdr->p_filesz);          /* Segment size in file */
       
   577     bswaptls(&phdr->p_memsz);           /* Segment size in memory */
       
   578     bswap32s(&phdr->p_flags);           /* Segment flags */
       
   579     bswaptls(&phdr->p_align);           /* Segment alignment */
       
   580 }
       
   581 
       
   582 static void bswap_shdr(struct elf_shdr *shdr)
       
   583 {
       
   584     bswap32s(&shdr->sh_name);
       
   585     bswap32s(&shdr->sh_type);
       
   586     bswaptls(&shdr->sh_flags);
       
   587     bswaptls(&shdr->sh_addr);
       
   588     bswaptls(&shdr->sh_offset);
       
   589     bswaptls(&shdr->sh_size);
       
   590     bswap32s(&shdr->sh_link);
       
   591     bswap32s(&shdr->sh_info);
       
   592     bswaptls(&shdr->sh_addralign);
       
   593     bswaptls(&shdr->sh_entsize);
       
   594 }
       
   595 
       
   596 static void bswap_sym(struct elf_sym *sym)
       
   597 {
       
   598     bswap32s(&sym->st_name);
       
   599     bswaptls(&sym->st_value);
       
   600     bswaptls(&sym->st_size);
       
   601     bswap16s(&sym->st_shndx);
       
   602 }
       
   603 #endif
       
   604 
       
   605 /*
       
   606  * 'copy_elf_strings()' copies argument/envelope strings from user
       
   607  * memory to free pages in kernel mem. These are in a format ready
       
   608  * to be put directly into the top of new user memory.
       
   609  *
       
   610  */
       
   611 static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
       
   612                                   abi_ulong p)
       
   613 {
       
   614     char *tmp, *tmp1, *pag = NULL;
       
   615     int len, offset = 0;
       
   616 
       
   617     if (!p) {
       
   618         return 0;       /* bullet-proofing */
       
   619     }
       
   620     while (argc-- > 0) {
       
   621         tmp = argv[argc];
       
   622         if (!tmp) {
       
   623             fprintf(stderr, "VFS: argc is wrong");
       
   624             exit(-1);
       
   625         }
       
   626         tmp1 = tmp;
       
   627         while (*tmp++);
       
   628         len = tmp - tmp1;
       
   629         if (p < len) {  /* this shouldn't happen - 128kB */
       
   630                 return 0;
       
   631         }
       
   632         while (len) {
       
   633             --p; --tmp; --len;
       
   634             if (--offset < 0) {
       
   635                 offset = p % TARGET_PAGE_SIZE;
       
   636                 pag = (char *)page[p/TARGET_PAGE_SIZE];
       
   637                 if (!pag) {
       
   638                     pag = (char *)malloc(TARGET_PAGE_SIZE);
       
   639                     memset(pag, 0, TARGET_PAGE_SIZE);
       
   640                     page[p/TARGET_PAGE_SIZE] = pag;
       
   641                     if (!pag)
       
   642                         return 0;
       
   643                 }
       
   644             }
       
   645             if (len == 0 || offset == 0) {
       
   646                 *(pag + offset) = *tmp;
       
   647             }
       
   648             else {
       
   649               int bytes_to_copy = (len > offset) ? offset : len;
       
   650               tmp -= bytes_to_copy;
       
   651               p -= bytes_to_copy;
       
   652               offset -= bytes_to_copy;
       
   653               len -= bytes_to_copy;
       
   654               memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
       
   655             }
       
   656         }
       
   657     }
       
   658     return p;
       
   659 }
       
   660 
       
   661 static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
       
   662                                  struct image_info *info)
       
   663 {
       
   664     abi_ulong stack_base, size, error;
       
   665     int i;
       
   666 
       
   667     /* Create enough stack to hold everything.  If we don't use
       
   668      * it for args, we'll use it for something else...
       
   669      */
       
   670     size = x86_stack_size;
       
   671     if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
       
   672         size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
       
   673     error = target_mmap(0,
       
   674                         size + qemu_host_page_size,
       
   675                         PROT_READ | PROT_WRITE,
       
   676                         MAP_PRIVATE | MAP_ANON,
       
   677                         -1, 0);
       
   678     if (error == -1) {
       
   679         perror("stk mmap");
       
   680         exit(-1);
       
   681     }
       
   682     /* we reserve one extra page at the top of the stack as guard */
       
   683     target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
       
   684 
       
   685     stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
       
   686     p += stack_base;
       
   687 
       
   688     for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
       
   689         if (bprm->page[i]) {
       
   690             info->rss++;
       
   691             /* FIXME - check return value of memcpy_to_target() for failure */
       
   692             memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
       
   693             free(bprm->page[i]);
       
   694         }
       
   695         stack_base += TARGET_PAGE_SIZE;
       
   696     }
       
   697     return p;
       
   698 }
       
   699 
       
   700 static void set_brk(abi_ulong start, abi_ulong end)
       
   701 {
       
   702         /* page-align the start and end addresses... */
       
   703         start = HOST_PAGE_ALIGN(start);
       
   704         end = HOST_PAGE_ALIGN(end);
       
   705         if (end <= start)
       
   706                 return;
       
   707         if(target_mmap(start, end - start,
       
   708                        PROT_READ | PROT_WRITE | PROT_EXEC,
       
   709                        MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
       
   710             perror("cannot mmap brk");
       
   711             exit(-1);
       
   712         }
       
   713 }
       
   714 
       
   715 
       
   716 /* We need to explicitly zero any fractional pages after the data
       
   717    section (i.e. bss).  This would contain the junk from the file that
       
   718    should not be in memory. */
       
   719 static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
       
   720 {
       
   721         abi_ulong nbyte;
       
   722 
       
   723         if (elf_bss >= last_bss)
       
   724                 return;
       
   725 
       
   726         /* XXX: this is really a hack : if the real host page size is
       
   727            smaller than the target page size, some pages after the end
       
   728            of the file may not be mapped. A better fix would be to
       
   729            patch target_mmap(), but it is more complicated as the file
       
   730            size must be known */
       
   731         if (qemu_real_host_page_size < qemu_host_page_size) {
       
   732             abi_ulong end_addr, end_addr1;
       
   733             end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
       
   734                 ~(qemu_real_host_page_size - 1);
       
   735             end_addr = HOST_PAGE_ALIGN(elf_bss);
       
   736             if (end_addr1 < end_addr) {
       
   737                 mmap((void *)g2h(end_addr1), end_addr - end_addr1,
       
   738                      PROT_READ|PROT_WRITE|PROT_EXEC,
       
   739                      MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
       
   740             }
       
   741         }
       
   742 
       
   743         nbyte = elf_bss & (qemu_host_page_size-1);
       
   744         if (nbyte) {
       
   745             nbyte = qemu_host_page_size - nbyte;
       
   746             do {
       
   747                 /* FIXME - what to do if put_user() fails? */
       
   748                 put_user_u8(0, elf_bss);
       
   749                 elf_bss++;
       
   750             } while (--nbyte);
       
   751         }
       
   752 }
       
   753 
       
   754 
       
   755 static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
       
   756                                    struct elfhdr * exec,
       
   757                                    abi_ulong load_addr,
       
   758                                    abi_ulong load_bias,
       
   759                                    abi_ulong interp_load_addr, int ibcs,
       
   760                                    struct image_info *info)
       
   761 {
       
   762         abi_ulong sp;
       
   763         int size;
       
   764         abi_ulong u_platform;
       
   765         const char *k_platform;
       
   766         const int n = sizeof(elf_addr_t);
       
   767 
       
   768         sp = p;
       
   769         u_platform = 0;
       
   770         k_platform = ELF_PLATFORM;
       
   771         if (k_platform) {
       
   772             size_t len = strlen(k_platform) + 1;
       
   773             sp -= (len + n - 1) & ~(n - 1);
       
   774             u_platform = sp;
       
   775             /* FIXME - check return value of memcpy_to_target() for failure */
       
   776             memcpy_to_target(sp, k_platform, len);
       
   777         }
       
   778         /*
       
   779          * Force 16 byte _final_ alignment here for generality.
       
   780          */
       
   781         sp = sp &~ (abi_ulong)15;
       
   782         size = (DLINFO_ITEMS + 1) * 2;
       
   783         if (k_platform)
       
   784           size += 2;
       
   785 #ifdef DLINFO_ARCH_ITEMS
       
   786         size += DLINFO_ARCH_ITEMS * 2;
       
   787 #endif
       
   788         size += envc + argc + 2;
       
   789         size += (!ibcs ? 3 : 1);        /* argc itself */
       
   790         size *= n;
       
   791         if (size & 15)
       
   792             sp -= 16 - (size & 15);
       
   793 
       
   794         /* This is correct because Linux defines
       
   795          * elf_addr_t as Elf32_Off / Elf64_Off
       
   796          */
       
   797 #define NEW_AUX_ENT(id, val) do {               \
       
   798             sp -= n; put_user_ual(val, sp);     \
       
   799             sp -= n; put_user_ual(id, sp);      \
       
   800           } while(0)
       
   801 
       
   802         NEW_AUX_ENT (AT_NULL, 0);
       
   803 
       
   804         /* There must be exactly DLINFO_ITEMS entries here.  */
       
   805         NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
       
   806         NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
       
   807         NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
       
   808         NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
       
   809         NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
       
   810         NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
       
   811         NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
       
   812         NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
       
   813         NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
       
   814         NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
       
   815         NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
       
   816         NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
       
   817         NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
       
   818         if (k_platform)
       
   819             NEW_AUX_ENT(AT_PLATFORM, u_platform);
       
   820 #ifdef ARCH_DLINFO
       
   821         /*
       
   822          * ARCH_DLINFO must come last so platform specific code can enforce
       
   823          * special alignment requirements on the AUXV if necessary (eg. PPC).
       
   824          */
       
   825         ARCH_DLINFO;
       
   826 #endif
       
   827 #undef NEW_AUX_ENT
       
   828 
       
   829         sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
       
   830         return sp;
       
   831 }
       
   832 
       
   833 
       
   834 static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
       
   835                                  int interpreter_fd,
       
   836                                  abi_ulong *interp_load_addr)
       
   837 {
       
   838         struct elf_phdr *elf_phdata  =  NULL;
       
   839         struct elf_phdr *eppnt;
       
   840         abi_ulong load_addr = 0;
       
   841         int load_addr_set = 0;
       
   842         int retval;
       
   843         abi_ulong last_bss, elf_bss;
       
   844         abi_ulong error;
       
   845         int i;
       
   846 
       
   847         elf_bss = 0;
       
   848         last_bss = 0;
       
   849         error = 0;
       
   850 
       
   851 #ifdef BSWAP_NEEDED
       
   852         bswap_ehdr(interp_elf_ex);
       
   853 #endif
       
   854         /* First of all, some simple consistency checks */
       
   855         if ((interp_elf_ex->e_type != ET_EXEC &&
       
   856              interp_elf_ex->e_type != ET_DYN) ||
       
   857            !elf_check_arch(interp_elf_ex->e_machine)) {
       
   858                 return ~((abi_ulong)0UL);
       
   859         }
       
   860 
       
   861 
       
   862         /* Now read in all of the header information */
       
   863 
       
   864         if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
       
   865             return ~(abi_ulong)0UL;
       
   866 
       
   867         elf_phdata =  (struct elf_phdr *)
       
   868                 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
       
   869 
       
   870         if (!elf_phdata)
       
   871           return ~((abi_ulong)0UL);
       
   872 
       
   873         /*
       
   874          * If the size of this structure has changed, then punt, since
       
   875          * we will be doing the wrong thing.
       
   876          */
       
   877         if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
       
   878             free(elf_phdata);
       
   879             return ~((abi_ulong)0UL);
       
   880         }
       
   881 
       
   882         retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
       
   883         if(retval >= 0) {
       
   884             retval = read(interpreter_fd,
       
   885                            (char *) elf_phdata,
       
   886                            sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
       
   887         }
       
   888         if (retval < 0) {
       
   889                 perror("load_elf_interp");
       
   890                 exit(-1);
       
   891                 free (elf_phdata);
       
   892                 return retval;
       
   893         }
       
   894 #ifdef BSWAP_NEEDED
       
   895         eppnt = elf_phdata;
       
   896         for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
       
   897             bswap_phdr(eppnt);
       
   898         }
       
   899 #endif
       
   900 
       
   901         if (interp_elf_ex->e_type == ET_DYN) {
       
   902             /* in order to avoid hardcoding the interpreter load
       
   903                address in qemu, we allocate a big enough memory zone */
       
   904             error = target_mmap(0, INTERP_MAP_SIZE,
       
   905                                 PROT_NONE, MAP_PRIVATE | MAP_ANON,
       
   906                                 -1, 0);
       
   907             if (error == -1) {
       
   908                 perror("mmap");
       
   909                 exit(-1);
       
   910             }
       
   911             load_addr = error;
       
   912             load_addr_set = 1;
       
   913         }
       
   914 
       
   915         eppnt = elf_phdata;
       
   916         for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
       
   917           if (eppnt->p_type == PT_LOAD) {
       
   918             int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
       
   919             int elf_prot = 0;
       
   920             abi_ulong vaddr = 0;
       
   921             abi_ulong k;
       
   922 
       
   923             if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
       
   924             if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
       
   925             if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
       
   926             if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
       
   927                 elf_type |= MAP_FIXED;
       
   928                 vaddr = eppnt->p_vaddr;
       
   929             }
       
   930             error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
       
   931                  eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
       
   932                  elf_prot,
       
   933                  elf_type,
       
   934                  interpreter_fd,
       
   935                  eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
       
   936 
       
   937             if (error == -1) {
       
   938               /* Real error */
       
   939               close(interpreter_fd);
       
   940               free(elf_phdata);
       
   941               return ~((abi_ulong)0UL);
       
   942             }
       
   943 
       
   944             if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
       
   945               load_addr = error;
       
   946               load_addr_set = 1;
       
   947             }
       
   948 
       
   949             /*
       
   950              * Find the end of the file  mapping for this phdr, and keep
       
   951              * track of the largest address we see for this.
       
   952              */
       
   953             k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
       
   954             if (k > elf_bss) elf_bss = k;
       
   955 
       
   956             /*
       
   957              * Do the same thing for the memory mapping - between
       
   958              * elf_bss and last_bss is the bss section.
       
   959              */
       
   960             k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
       
   961             if (k > last_bss) last_bss = k;
       
   962           }
       
   963 
       
   964         /* Now use mmap to map the library into memory. */
       
   965 
       
   966         close(interpreter_fd);
       
   967 
       
   968         /*
       
   969          * Now fill out the bss section.  First pad the last page up
       
   970          * to the page boundary, and then perform a mmap to make sure
       
   971          * that there are zeromapped pages up to and including the last
       
   972          * bss page.
       
   973          */
       
   974         padzero(elf_bss, last_bss);
       
   975         elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
       
   976 
       
   977         /* Map the last of the bss segment */
       
   978         if (last_bss > elf_bss) {
       
   979             target_mmap(elf_bss, last_bss-elf_bss,
       
   980                         PROT_READ|PROT_WRITE|PROT_EXEC,
       
   981                         MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
       
   982         }
       
   983         free(elf_phdata);
       
   984 
       
   985         *interp_load_addr = load_addr;
       
   986         return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
       
   987 }
       
   988 
       
   989 static int symfind(const void *s0, const void *s1)
       
   990 {
       
   991     struct elf_sym *key = (struct elf_sym *)s0;
       
   992     struct elf_sym *sym = (struct elf_sym *)s1;
       
   993     int result = 0;
       
   994     if (key->st_value < sym->st_value) {
       
   995         result = -1;
       
   996     } else if (key->st_value > sym->st_value + sym->st_size) {
       
   997         result = 1;
       
   998     }
       
   999     return result;
       
  1000 }
       
  1001 
       
  1002 static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
       
  1003 {
       
  1004 #if ELF_CLASS == ELFCLASS32
       
  1005     struct elf_sym *syms = s->disas_symtab.elf32;
       
  1006 #else
       
  1007     struct elf_sym *syms = s->disas_symtab.elf64;
       
  1008 #endif
       
  1009 
       
  1010     // binary search
       
  1011     struct elf_sym key;
       
  1012     struct elf_sym *sym;
       
  1013 
       
  1014     key.st_value = orig_addr;
       
  1015 
       
  1016     sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), symfind);
       
  1017     if (sym != 0) {
       
  1018         return s->disas_strtab + sym->st_name;
       
  1019     }
       
  1020 
       
  1021     return "";
       
  1022 }
       
  1023 
       
  1024 /* FIXME: This should use elf_ops.h  */
       
  1025 static int symcmp(const void *s0, const void *s1)
       
  1026 {
       
  1027     struct elf_sym *sym0 = (struct elf_sym *)s0;
       
  1028     struct elf_sym *sym1 = (struct elf_sym *)s1;
       
  1029     return (sym0->st_value < sym1->st_value)
       
  1030         ? -1
       
  1031         : ((sym0->st_value > sym1->st_value) ? 1 : 0);
       
  1032 }
       
  1033 
       
  1034 /* Best attempt to load symbols from this ELF object. */
       
  1035 static void load_symbols(struct elfhdr *hdr, int fd)
       
  1036 {
       
  1037     unsigned int i, nsyms;
       
  1038     struct elf_shdr sechdr, symtab, strtab;
       
  1039     char *strings;
       
  1040     struct syminfo *s;
       
  1041     struct elf_sym *syms;
       
  1042 
       
  1043     lseek(fd, hdr->e_shoff, SEEK_SET);
       
  1044     for (i = 0; i < hdr->e_shnum; i++) {
       
  1045         if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
       
  1046             return;
       
  1047 #ifdef BSWAP_NEEDED
       
  1048         bswap_shdr(&sechdr);
       
  1049 #endif
       
  1050         if (sechdr.sh_type == SHT_SYMTAB) {
       
  1051             symtab = sechdr;
       
  1052             lseek(fd, hdr->e_shoff
       
  1053                   + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
       
  1054             if (read(fd, &strtab, sizeof(strtab))
       
  1055                 != sizeof(strtab))
       
  1056                 return;
       
  1057 #ifdef BSWAP_NEEDED
       
  1058             bswap_shdr(&strtab);
       
  1059 #endif
       
  1060             goto found;
       
  1061         }
       
  1062     }
       
  1063     return; /* Shouldn't happen... */
       
  1064 
       
  1065  found:
       
  1066     /* Now know where the strtab and symtab are.  Snarf them. */
       
  1067     s = malloc(sizeof(*s));
       
  1068     syms = malloc(symtab.sh_size);
       
  1069     if (!syms)
       
  1070         return;
       
  1071     s->disas_strtab = strings = malloc(strtab.sh_size);
       
  1072     if (!s->disas_strtab)
       
  1073         return;
       
  1074 
       
  1075     lseek(fd, symtab.sh_offset, SEEK_SET);
       
  1076     if (read(fd, syms, symtab.sh_size) != symtab.sh_size)
       
  1077         return;
       
  1078 
       
  1079     nsyms = symtab.sh_size / sizeof(struct elf_sym);
       
  1080 
       
  1081     i = 0;
       
  1082     while (i < nsyms) {
       
  1083 #ifdef BSWAP_NEEDED
       
  1084         bswap_sym(syms + i);
       
  1085 #endif
       
  1086         // Throw away entries which we do not need.
       
  1087         if (syms[i].st_shndx == SHN_UNDEF ||
       
  1088                 syms[i].st_shndx >= SHN_LORESERVE ||
       
  1089                 ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
       
  1090             nsyms--;
       
  1091             if (i < nsyms) {
       
  1092                 syms[i] = syms[nsyms];
       
  1093             }
       
  1094             continue;
       
  1095         }
       
  1096 #if defined(TARGET_ARM) || defined (TARGET_MIPS)
       
  1097         /* The bottom address bit marks a Thumb or MIPS16 symbol.  */
       
  1098         syms[i].st_value &= ~(target_ulong)1;
       
  1099 #endif
       
  1100         i++;
       
  1101     }
       
  1102     syms = realloc(syms, nsyms * sizeof(*syms));
       
  1103 
       
  1104     qsort(syms, nsyms, sizeof(*syms), symcmp);
       
  1105 
       
  1106     lseek(fd, strtab.sh_offset, SEEK_SET);
       
  1107     if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
       
  1108         return;
       
  1109     s->disas_num_syms = nsyms;
       
  1110 #if ELF_CLASS == ELFCLASS32
       
  1111     s->disas_symtab.elf32 = syms;
       
  1112     s->lookup_symbol = lookup_symbolxx;
       
  1113 #else
       
  1114     s->disas_symtab.elf64 = syms;
       
  1115     s->lookup_symbol = lookup_symbolxx;
       
  1116 #endif
       
  1117     s->next = syminfos;
       
  1118     syminfos = s;
       
  1119 }
       
  1120 
       
  1121 int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
       
  1122                     struct image_info * info)
       
  1123 {
       
  1124     struct elfhdr elf_ex;
       
  1125     struct elfhdr interp_elf_ex;
       
  1126     struct exec interp_ex;
       
  1127     int interpreter_fd = -1; /* avoid warning */
       
  1128     abi_ulong load_addr, load_bias;
       
  1129     int load_addr_set = 0;
       
  1130     unsigned int interpreter_type = INTERPRETER_NONE;
       
  1131     unsigned char ibcs2_interpreter;
       
  1132     int i;
       
  1133     abi_ulong mapped_addr;
       
  1134     struct elf_phdr * elf_ppnt;
       
  1135     struct elf_phdr *elf_phdata;
       
  1136     abi_ulong elf_bss, k, elf_brk;
       
  1137     int retval;
       
  1138     char * elf_interpreter;
       
  1139     abi_ulong elf_entry, interp_load_addr = 0;
       
  1140     int status;
       
  1141     abi_ulong start_code, end_code, start_data, end_data;
       
  1142     abi_ulong reloc_func_desc = 0;
       
  1143     abi_ulong elf_stack;
       
  1144     char passed_fileno[6];
       
  1145 
       
  1146     ibcs2_interpreter = 0;
       
  1147     status = 0;
       
  1148     load_addr = 0;
       
  1149     load_bias = 0;
       
  1150     elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
       
  1151 #ifdef BSWAP_NEEDED
       
  1152     bswap_ehdr(&elf_ex);
       
  1153 #endif
       
  1154 
       
  1155     /* First of all, some simple consistency checks */
       
  1156     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
       
  1157                                 (! elf_check_arch(elf_ex.e_machine))) {
       
  1158             return -ENOEXEC;
       
  1159     }
       
  1160 
       
  1161     bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
       
  1162     bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
       
  1163     bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
       
  1164     if (!bprm->p) {
       
  1165         retval = -E2BIG;
       
  1166     }
       
  1167 
       
  1168     /* Now read in all of the header information */
       
  1169     elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
       
  1170     if (elf_phdata == NULL) {
       
  1171         return -ENOMEM;
       
  1172     }
       
  1173 
       
  1174     retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
       
  1175     if(retval > 0) {
       
  1176         retval = read(bprm->fd, (char *) elf_phdata,
       
  1177                                 elf_ex.e_phentsize * elf_ex.e_phnum);
       
  1178     }
       
  1179 
       
  1180     if (retval < 0) {
       
  1181         perror("load_elf_binary");
       
  1182         exit(-1);
       
  1183         free (elf_phdata);
       
  1184         return -errno;
       
  1185     }
       
  1186 
       
  1187 #ifdef BSWAP_NEEDED
       
  1188     elf_ppnt = elf_phdata;
       
  1189     for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
       
  1190         bswap_phdr(elf_ppnt);
       
  1191     }
       
  1192 #endif
       
  1193     elf_ppnt = elf_phdata;
       
  1194 
       
  1195     elf_bss = 0;
       
  1196     elf_brk = 0;
       
  1197 
       
  1198 
       
  1199     elf_stack = ~((abi_ulong)0UL);
       
  1200     elf_interpreter = NULL;
       
  1201     start_code = ~((abi_ulong)0UL);
       
  1202     end_code = 0;
       
  1203     start_data = 0;
       
  1204     end_data = 0;
       
  1205     interp_ex.a_info = 0;
       
  1206 
       
  1207     for(i=0;i < elf_ex.e_phnum; i++) {
       
  1208         if (elf_ppnt->p_type == PT_INTERP) {
       
  1209             if ( elf_interpreter != NULL )
       
  1210             {
       
  1211                 free (elf_phdata);
       
  1212                 free(elf_interpreter);
       
  1213                 close(bprm->fd);
       
  1214                 return -EINVAL;
       
  1215             }
       
  1216 
       
  1217             /* This is the program interpreter used for
       
  1218              * shared libraries - for now assume that this
       
  1219              * is an a.out format binary
       
  1220              */
       
  1221 
       
  1222             elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
       
  1223 
       
  1224             if (elf_interpreter == NULL) {
       
  1225                 free (elf_phdata);
       
  1226                 close(bprm->fd);
       
  1227                 return -ENOMEM;
       
  1228             }
       
  1229 
       
  1230             retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
       
  1231             if(retval >= 0) {
       
  1232                 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
       
  1233             }
       
  1234             if(retval < 0) {
       
  1235                 perror("load_elf_binary2");
       
  1236                 exit(-1);
       
  1237             }
       
  1238 
       
  1239             /* If the program interpreter is one of these two,
       
  1240                then assume an iBCS2 image. Otherwise assume
       
  1241                a native linux image. */
       
  1242 
       
  1243             /* JRP - Need to add X86 lib dir stuff here... */
       
  1244 
       
  1245             if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
       
  1246                 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
       
  1247               ibcs2_interpreter = 1;
       
  1248             }
       
  1249 
       
  1250 #if 0
       
  1251             printf("Using ELF interpreter %s\n", elf_interpreter);
       
  1252 #endif
       
  1253             if (retval >= 0) {
       
  1254                 retval = open(path(elf_interpreter), O_RDONLY);
       
  1255                 if(retval >= 0) {
       
  1256                     interpreter_fd = retval;
       
  1257                 }
       
  1258                 else {
       
  1259                     perror(elf_interpreter);
       
  1260                     exit(-1);
       
  1261                     /* retval = -errno; */
       
  1262                 }
       
  1263             }
       
  1264 
       
  1265             if (retval >= 0) {
       
  1266                 retval = lseek(interpreter_fd, 0, SEEK_SET);
       
  1267                 if(retval >= 0) {
       
  1268                     retval = read(interpreter_fd,bprm->buf,128);
       
  1269                 }
       
  1270             }
       
  1271             if (retval >= 0) {
       
  1272                 interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
       
  1273                 interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
       
  1274             }
       
  1275             if (retval < 0) {
       
  1276                 perror("load_elf_binary3");
       
  1277                 exit(-1);
       
  1278                 free (elf_phdata);
       
  1279                 free(elf_interpreter);
       
  1280                 close(bprm->fd);
       
  1281                 return retval;
       
  1282             }
       
  1283         }
       
  1284         elf_ppnt++;
       
  1285     }
       
  1286 
       
  1287     /* Some simple consistency checks for the interpreter */
       
  1288     if (elf_interpreter){
       
  1289         interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
       
  1290 
       
  1291         /* Now figure out which format our binary is */
       
  1292         if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
       
  1293                 (N_MAGIC(interp_ex) != QMAGIC)) {
       
  1294           interpreter_type = INTERPRETER_ELF;
       
  1295         }
       
  1296 
       
  1297         if (interp_elf_ex.e_ident[0] != 0x7f ||
       
  1298                 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
       
  1299             interpreter_type &= ~INTERPRETER_ELF;
       
  1300         }
       
  1301 
       
  1302         if (!interpreter_type) {
       
  1303             free(elf_interpreter);
       
  1304             free(elf_phdata);
       
  1305             close(bprm->fd);
       
  1306             return -ELIBBAD;
       
  1307         }
       
  1308     }
       
  1309 
       
  1310     /* OK, we are done with that, now set up the arg stuff,
       
  1311        and then start this sucker up */
       
  1312 
       
  1313     {
       
  1314         char * passed_p;
       
  1315 
       
  1316         if (interpreter_type == INTERPRETER_AOUT) {
       
  1317             snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
       
  1318             passed_p = passed_fileno;
       
  1319 
       
  1320             if (elf_interpreter) {
       
  1321                 bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);
       
  1322                 bprm->argc++;
       
  1323             }
       
  1324         }
       
  1325         if (!bprm->p) {
       
  1326             if (elf_interpreter) {
       
  1327                 free(elf_interpreter);
       
  1328             }
       
  1329             free (elf_phdata);
       
  1330             close(bprm->fd);
       
  1331             return -E2BIG;
       
  1332         }
       
  1333     }
       
  1334 
       
  1335     /* OK, This is the point of no return */
       
  1336     info->end_data = 0;
       
  1337     info->end_code = 0;
       
  1338     info->start_mmap = (abi_ulong)ELF_START_MMAP;
       
  1339     info->mmap = 0;
       
  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 }