(linenum→info "unix/slp.c:2238")

qemu/0.9.1/linux-user/elfload.c

    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: /* from personality.h */
   16: 
   17: /*
   18:  * Flags for bug emulation.
   19:  *
   20:  * These occupy the top three bytes.
   21:  */
   22: enum {
   23:         ADDR_NO_RANDOMIZE =    0x0040000,        /* disable randomization of VA space */
   24:         FDPIC_FUNCPTRS =       0x0080000,    /* userspace function ptrs point to descriptors
   25:                                                  * (signal handling)
   26:                                                  */
   27:         MMAP_PAGE_ZERO =       0x0100000,
   28:         ADDR_COMPAT_LAYOUT =   0x0200000,
   29:         READ_IMPLIES_EXEC =    0x0400000,
   30:         ADDR_LIMIT_32BIT =     0x0800000,
   31:         SHORT_INODE =          0x1000000,
   32:         WHOLE_SECONDS =                0x2000000,
   33:         STICKY_TIMEOUTS        =      0x4000000,
   34:         ADDR_LIMIT_3GB =       0x8000000,
   35: };
   36: 
   37: /*
   38:  * Personality types.
   39:  *
   40:  * These go in the low byte.  Avoid using the top bit, it will
   41:  * conflict with error returns.
   42:  */
   43: enum {
   44:         PER_LINUX =            0x0000,
   45:         PER_LINUX_32BIT =      0x0000 | ADDR_LIMIT_32BIT,
   46:         PER_LINUX_FDPIC =      0x0000 | FDPIC_FUNCPTRS,
   47:         PER_SVR4 =             0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
   48:         PER_SVR3 =             0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
   49:         PER_SCOSVR3 =          0x0003 | STICKY_TIMEOUTS |
   50:                                          WHOLE_SECONDS | SHORT_INODE,
   51:         PER_OSR5 =             0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
   52:         PER_WYSEV386 =         0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
   53:         PER_ISCR4 =            0x0005 | STICKY_TIMEOUTS,
   54:         PER_BSD =              0x0006,
   55:         PER_SUNOS =            0x0006 | STICKY_TIMEOUTS,
   56:         PER_XENIX =            0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
   57:         PER_LINUX32 =          0x0008,
   58:         PER_LINUX32_3GB =      0x0008 | ADDR_LIMIT_3GB,
   59:         PER_IRIX32 =           0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
   60:         PER_IRIXN32 =          0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
   61:         PER_IRIX64 =           0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
   62:         PER_RISCOS =           0x000c,
   63:         PER_SOLARIS =          0x000d | STICKY_TIMEOUTS,
   64:         PER_UW7 =              0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
   65:         PER_OSF4 =             0x000f,                     /* OSF/1 v4 */
   66:         PER_HPUX =             0x0010,
   67:         PER_MASK =             0x00ff,
   68: };
   69: 
   70: /*
   71:  * Return the base personality without flags.
   72:  */
   73: #define personality(pers)       (pers & PER_MASK)
   74: 
   75: /* this flag is uneffective under linux too, should be deleted */
   76: #ifndef MAP_DENYWRITE
   77: #define MAP_DENYWRITE 0
   78: #endif
   79: 
   80: /* should probably go in elf.h */
   81: #ifndef ELIBBAD
   82: #define ELIBBAD 80
   83: #endif
   84: 
   85: #ifdef TARGET_I386
   86: 
   87: #define ELF_PLATFORM get_elf_platform()
   88: 
   89: static const char *get_elf_platform(void)
   90: {
   91:     static char elf_platform[] = "i386";
   92:     int family = (global_env->cpuid_version >> 8) & 0xff;
   93:     if (family > 6)
   94:         family = 6;
   95:     if (family >= 3)
   96:         elf_platform[1] = '0' + family;
   97:     return elf_platform;
   98: }
   99: 
  100: #define ELF_HWCAP get_elf_hwcap()
  101: 
  102: static uint32_t get_elf_hwcap(void)
  103: {
  104:   return global_env->cpuid_features;
  105: }
  106: 
  107: #ifdef TARGET_X86_64
  108: #define ELF_START_MMAP 0x2aaaaab000ULL
  109: #define elf_check_arch(x) ( ((x) == ELF_ARCH) )
  110: 
  111: #define ELF_CLASS      ELFCLASS64
  112: #define ELF_DATA       ELFDATA2LSB
  113: #define ELF_ARCH       EM_X86_64
  114: 
  115: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  116: {
  117:     regs->rax = 0;
  118:     regs->rsp = infop->start_stack;
  119:     regs->rip = infop->entry;
  120: }
  121: 
  122: #else
  123: 
  124: #define ELF_START_MMAP 0x80000000
  125: 
  126: /*
  127:  * This is used to ensure we don't load something for the wrong architecture.
  128:  */
  129: #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
  130: 
  131: /*
  132:  * These are used to set parameters in the core dumps.
  133:  */
  134: #define ELF_CLASS       ELFCLASS32
  135: #define ELF_DATA        ELFDATA2LSB
  136: #define ELF_ARCH        EM_386
  137: 
  138: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  139: {
  140:     regs->esp = infop->start_stack;
  141:     regs->eip = infop->entry;
  142: 
  143:     /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
  144:        starts %edx contains a pointer to a function which might be
  145:        registered using `atexit'.  This provides a mean for the
  146:        dynamic linker to call DT_FINI functions for shared libraries
  147:        that have been loaded before the code runs.
  148: 
  149:        A value of 0 tells we have no such handler.  */
  150:     regs->edx = 0;
  151: }
  152: #endif
  153: 
  154: #define USE_ELF_CORE_DUMP
  155: #define ELF_EXEC_PAGESIZE       4096
  156: 
  157: #endif
  158: 
  159: #ifdef TARGET_ARM
  160: 
  161: #define ELF_START_MMAP 0x80000000
  162: 
  163: #define elf_check_arch(x) ( (x) == EM_ARM )
  164: 
  165: #define ELF_CLASS       ELFCLASS32
  166: #ifdef TARGET_WORDS_BIGENDIAN
  167: #define ELF_DATA        ELFDATA2MSB
  168: #else
  169: #define ELF_DATA        ELFDATA2LSB
  170: #endif
  171: #define ELF_ARCH        EM_ARM
  172: 
  173: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  174: {
  175:     abi_long stack = infop->start_stack;
  176:     memset(regs, 0, sizeof(*regs));
  177:     regs->ARM_cpsr = 0x10;
  178:     if (infop->entry & 1)
  179:       regs->ARM_cpsr |= CPSR_T;
  180:     regs->ARM_pc = infop->entry & 0xfffffffe;
  181:     regs->ARM_sp = infop->start_stack;
  182:     /* FIXME - what to for failure of get_user()? */
  183:     get_user_ual(regs->ARM_r2, stack + 8); /* envp */
  184:     get_user_ual(regs->ARM_r1, stack + 4); /* envp */
  185:     /* XXX: it seems that r0 is zeroed after ! */
  186:     regs->ARM_r0 = 0;
  187:     /* For uClinux PIC binaries.  */
  188:     /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
  189:     regs->ARM_r10 = infop->start_data;
  190: }
  191: 
  192: #define USE_ELF_CORE_DUMP
  193: #define ELF_EXEC_PAGESIZE       4096
  194: 
  195: enum
  196: {
  197:   ARM_HWCAP_ARM_SWP       = 1 << 0,
  198:   ARM_HWCAP_ARM_HALF      = 1 << 1,
  199:   ARM_HWCAP_ARM_THUMB     = 1 << 2,
  200:   ARM_HWCAP_ARM_26BIT     = 1 << 3,
  201:   ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
  202:   ARM_HWCAP_ARM_FPA       = 1 << 5,
  203:   ARM_HWCAP_ARM_VFP       = 1 << 6,
  204:   ARM_HWCAP_ARM_EDSP      = 1 << 7,
  205: };
  206: 
  207: #define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \
  208:                     | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \
  209:                     | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
  210: 
  211: #endif
  212: 
  213: #ifdef TARGET_SPARC
  214: #ifdef TARGET_SPARC64
  215: 
  216: #define ELF_START_MMAP 0x80000000
  217: 
  218: #ifndef TARGET_ABI32
  219: #define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
  220: #else
  221: #define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
  222: #endif
  223: 
  224: #define ELF_CLASS   ELFCLASS64
  225: #define ELF_DATA    ELFDATA2MSB
  226: #define ELF_ARCH    EM_SPARCV9
  227: 
  228: #define STACK_BIAS              2047
  229: 
  230: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  231: {
  232: #ifndef TARGET_ABI32
  233:     regs->tstate = 0;
  234: #endif
  235:     regs->pc = infop->entry;
  236:     regs->npc = regs->pc + 4;
  237:     regs->y = 0;
  238: #ifdef TARGET_ABI32
  239:     regs->u_regs[14] = infop->start_stack - 16 * 4;
  240: #else
  241:     if (personality(infop->personality) == PER_LINUX32)
  242:         regs->u_regs[14] = infop->start_stack - 16 * 4;
  243:     else
  244:         regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
  245: #endif
  246: }
  247: 
  248: #else
  249: #define ELF_START_MMAP 0x80000000
  250: 
  251: #define elf_check_arch(x) ( (x) == EM_SPARC )
  252: 
  253: #define ELF_CLASS   ELFCLASS32
  254: #define ELF_DATA    ELFDATA2MSB
  255: #define ELF_ARCH    EM_SPARC
  256: 
  257: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  258: {
  259:     regs->psr = 0;
  260:     regs->pc = infop->entry;
  261:     regs->npc = regs->pc + 4;
  262:     regs->y = 0;
  263:     regs->u_regs[14] = infop->start_stack - 16 * 4;
  264: }
  265: 
  266: #endif
  267: #endif
  268: 
  269: #ifdef TARGET_PPC
  270: 
  271: #define ELF_START_MMAP 0x80000000
  272: 
  273: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
  274: 
  275: #define elf_check_arch(x) ( (x) == EM_PPC64 )
  276: 
  277: #define ELF_CLASS       ELFCLASS64
  278: 
  279: #else
  280: 
  281: #define elf_check_arch(x) ( (x) == EM_PPC )
  282: 
  283: #define ELF_CLASS       ELFCLASS32
  284: 
  285: #endif
  286: 
  287: #ifdef TARGET_WORDS_BIGENDIAN
  288: #define ELF_DATA        ELFDATA2MSB
  289: #else
  290: #define ELF_DATA        ELFDATA2LSB
  291: #endif
  292: #define ELF_ARCH        EM_PPC
  293: 
  294: /*
  295:  * We need to put in some extra aux table entries to tell glibc what
  296:  * the cache block size is, so it can use the dcbz instruction safely.
  297:  */
  298: #define AT_DCACHEBSIZE          19
  299: #define AT_ICACHEBSIZE          20
  300: #define AT_UCACHEBSIZE          21
  301: /* A special ignored type value for PPC, for glibc compatibility.  */
  302: #define AT_IGNOREPPC            22
  303: /*
  304:  * The requirements here are:
  305:  * - keep the final alignment of sp (sp & 0xf)
  306:  * - make sure the 32-bit value at the first 16 byte aligned position of
  307:  *   AUXV is greater than 16 for glibc compatibility.
  308:  *   AT_IGNOREPPC is used for that.
  309:  * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
  310:  *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
  311:  */
  312: #define DLINFO_ARCH_ITEMS       5
  313: #define ARCH_DLINFO                                                     \
  314: do {                                                                    \
  315:         NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \
  316:         NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \
  317:         NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \
  318:         /*                                                              \
  319:          * Now handle glibc compatibility.                              \
  320:          */                                                             \
  321:         NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                       \
  322:         NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                       \
  323:  } while (0)
  324: 
  325: static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
  326: {
  327:     abi_ulong pos = infop->start_stack;
  328:     abi_ulong tmp;
  329: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
  330:     abi_ulong entry, toc;
  331: #endif
  332: 
  333:     _regs->gpr[1] = infop->start_stack;
  334: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
  335:     entry = ldq_raw(infop->entry) + infop->load_addr;
  336:     toc = ldq_raw(infop->entry + 8) + infop->load_addr;
  337:     _regs->gpr[2] = toc;
  338:     infop->entry = entry;
  339: #endif
  340:     _regs->nip = infop->entry;
  341:     /* Note that isn't exactly what regular kernel does
  342:      * but this is what the ABI wants and is needed to allow
  343:      * execution of PPC BSD programs.
  344:      */
  345:     /* FIXME - what to for failure of get_user()? */
  346:     get_user_ual(_regs->gpr[3], pos);
  347:     pos += sizeof(abi_ulong);
  348:     _regs->gpr[4] = pos;
  349:     for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
  350:         tmp = ldl(pos);
  351:     _regs->gpr[5] = pos;
  352: }
  353: 
  354: #define USE_ELF_CORE_DUMP
  355: #define ELF_EXEC_PAGESIZE       4096
  356: 
  357: #endif
  358: 
  359: #ifdef TARGET_MIPS
  360: 
  361: #define ELF_START_MMAP 0x80000000
  362: 
  363: #define elf_check_arch(x) ( (x) == EM_MIPS )
  364: 
  365: #ifdef TARGET_MIPS64
  366: #define ELF_CLASS   ELFCLASS64
  367: #else
  368: #define ELF_CLASS   ELFCLASS32
  369: #endif
  370: #ifdef TARGET_WORDS_BIGENDIAN
  371: #define ELF_DATA        ELFDATA2MSB
  372: #else
  373: #define ELF_DATA        ELFDATA2LSB
  374: #endif
  375: #define ELF_ARCH    EM_MIPS
  376: 
  377: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  378: {
  379:     regs->cp0_status = 2 << CP0St_KSU;
  380:     regs->cp0_epc = infop->entry;
  381:     regs->regs[29] = infop->start_stack;
  382: }
  383: 
  384: #define USE_ELF_CORE_DUMP
  385: #define ELF_EXEC_PAGESIZE        4096
  386: 
  387: #endif /* TARGET_MIPS */
  388: 
  389: #ifdef TARGET_SH4
  390: 
  391: #define ELF_START_MMAP 0x80000000
  392: 
  393: #define elf_check_arch(x) ( (x) == EM_SH )
  394: 
  395: #define ELF_CLASS ELFCLASS32
  396: #define ELF_DATA  ELFDATA2LSB
  397: #define ELF_ARCH  EM_SH
  398: 
  399: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  400: {
  401:   /* Check other registers XXXXX */
  402:   regs->pc = infop->entry;
  403:   regs->regs[15] = infop->start_stack;
  404: }
  405: 
  406: #define USE_ELF_CORE_DUMP
  407: #define ELF_EXEC_PAGESIZE        4096
  408: 
  409: #endif
  410: 
  411: #ifdef TARGET_CRIS
  412: 
  413: #define ELF_START_MMAP 0x80000000
  414: 
  415: #define elf_check_arch(x) ( (x) == EM_CRIS )
  416: 
  417: #define ELF_CLASS ELFCLASS32
  418: #define ELF_DATA  ELFDATA2LSB
  419: #define ELF_ARCH  EM_CRIS
  420: 
  421: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  422: {
  423:   regs->erp = infop->entry;
  424: }
  425: 
  426: #define USE_ELF_CORE_DUMP
  427: #define ELF_EXEC_PAGESIZE        8192
  428: 
  429: #endif
  430: 
  431: #ifdef TARGET_M68K
  432: 
  433: #define ELF_START_MMAP 0x80000000
  434: 
  435: #define elf_check_arch(x) ( (x) == EM_68K )
  436: 
  437: #define ELF_CLASS       ELFCLASS32
  438: #define ELF_DATA        ELFDATA2MSB
  439: #define ELF_ARCH        EM_68K
  440: 
  441: /* ??? Does this need to do anything?
  442: #define ELF_PLAT_INIT(_r) */
  443: 
  444: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  445: {
  446:     regs->usp = infop->start_stack;
  447:     regs->sr = 0;
  448:     regs->pc = infop->entry;
  449: }
  450: 
  451: #define USE_ELF_CORE_DUMP
  452: #define ELF_EXEC_PAGESIZE       8192
  453: 
  454: #endif
  455: 
  456: #ifdef TARGET_ALPHA
  457: 
  458: #define ELF_START_MMAP (0x30000000000ULL)
  459: 
  460: #define elf_check_arch(x) ( (x) == ELF_ARCH )
  461: 
  462: #define ELF_CLASS      ELFCLASS64
  463: #define ELF_DATA       ELFDATA2MSB
  464: #define ELF_ARCH       EM_ALPHA
  465: 
  466: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
  467: {
  468:     regs->pc = infop->entry;
  469:     regs->ps = 8;
  470:     regs->usp = infop->start_stack;
  471:     regs->unique = infop->start_data; /* ? */
  472:     printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",
  473:            regs->unique, infop->start_data);
  474: }
  475: 
  476: #define USE_ELF_CORE_DUMP
  477: #define ELF_EXEC_PAGESIZE        8192
  478: 
  479: #endif /* TARGET_ALPHA */
  480: 
  481: #ifndef ELF_PLATFORM
  482: #define ELF_PLATFORM (NULL)
  483: #endif
  484: 
  485: #ifndef ELF_HWCAP
  486: #define ELF_HWCAP 0
  487: #endif
  488: 
  489: #ifdef TARGET_ABI32
  490: #undef ELF_CLASS
  491: #define ELF_CLASS ELFCLASS32
  492: #undef bswaptls
  493: #define bswaptls(ptr) bswap32s(ptr)
  494: #endif
  495: 
  496: #include "elf.h"
  497: 
  498: struct exec
  499: {
  500:   unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
  501:   unsigned int a_text;   /* length of text, in bytes */
  502:   unsigned int a_data;   /* length of data, in bytes */
  503:   unsigned int a_bss;    /* length of uninitialized data area, in bytes */
  504:   unsigned int a_syms;   /* length of symbol table data in file, in bytes */
  505:   unsigned int a_entry;  /* start address */
  506:   unsigned int a_trsize; /* length of relocation info for text, in bytes */
  507:   unsigned int a_drsize; /* length of relocation info for data, in bytes */
  508: };
  509: 
  510: 
  511: #define N_MAGIC(exec) ((exec).a_info & 0xffff)
  512: #define OMAGIC 0407
  513: #define NMAGIC 0410
  514: #define ZMAGIC 0413
  515: #define QMAGIC 0314
  516: 
  517: /* max code+data+bss space allocated to elf interpreter */
  518: #define INTERP_MAP_SIZE (32 * 1024 * 1024)
  519: 
  520: /* max code+data+bss+brk space allocated to ET_DYN executables */
  521: #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
  522: 
  523: /* Necessary parameters */
  524: #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE