Annotation of qemu/linux-user/elfload.c, revision 1.1.1.11

1.1       root        1: /* This is the Linux kernel elf-loading code, ported into user space */
1.1.1.8   root        2: #include <sys/time.h>
                      3: #include <sys/param.h>
1.1       root        4: 
                      5: #include <stdio.h>
                      6: #include <sys/types.h>
                      7: #include <fcntl.h>
                      8: #include <errno.h>
                      9: #include <unistd.h>
                     10: #include <sys/mman.h>
1.1.1.8   root       11: #include <sys/resource.h>
1.1       root       12: #include <stdlib.h>
                     13: #include <string.h>
1.1.1.8   root       14: #include <time.h>
1.1       root       15: 
                     16: #include "qemu.h"
                     17: #include "disas.h"
                     18: 
1.1.1.7   root       19: #ifdef _ARCH_PPC64
                     20: #undef ARCH_DLINFO
                     21: #undef ELF_PLATFORM
                     22: #undef ELF_HWCAP
                     23: #undef ELF_CLASS
                     24: #undef ELF_DATA
                     25: #undef ELF_ARCH
                     26: #endif
                     27: 
1.1.1.8   root       28: #define ELF_OSABI   ELFOSABI_SYSV
                     29: 
1.1.1.6   root       30: /* from personality.h */
                     31: 
                     32: /*
                     33:  * Flags for bug emulation.
                     34:  *
                     35:  * These occupy the top three bytes.
                     36:  */
                     37: enum {
                     38:        ADDR_NO_RANDOMIZE =     0x0040000,      /* disable randomization of VA space */
                     39:        FDPIC_FUNCPTRS =        0x0080000,      /* userspace function ptrs point to descriptors
                     40:                                                 * (signal handling)
                     41:                                                 */
                     42:        MMAP_PAGE_ZERO =        0x0100000,
                     43:        ADDR_COMPAT_LAYOUT =    0x0200000,
                     44:        READ_IMPLIES_EXEC =     0x0400000,
                     45:        ADDR_LIMIT_32BIT =      0x0800000,
                     46:        SHORT_INODE =           0x1000000,
                     47:        WHOLE_SECONDS =         0x2000000,
                     48:        STICKY_TIMEOUTS =       0x4000000,
                     49:        ADDR_LIMIT_3GB =        0x8000000,
                     50: };
                     51: 
                     52: /*
                     53:  * Personality types.
                     54:  *
                     55:  * These go in the low byte.  Avoid using the top bit, it will
                     56:  * conflict with error returns.
                     57:  */
                     58: enum {
                     59:        PER_LINUX =             0x0000,
                     60:        PER_LINUX_32BIT =       0x0000 | ADDR_LIMIT_32BIT,
                     61:        PER_LINUX_FDPIC =       0x0000 | FDPIC_FUNCPTRS,
                     62:        PER_SVR4 =              0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
                     63:        PER_SVR3 =              0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
                     64:        PER_SCOSVR3 =           0x0003 | STICKY_TIMEOUTS |
                     65:                                         WHOLE_SECONDS | SHORT_INODE,
                     66:        PER_OSR5 =              0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
                     67:        PER_WYSEV386 =          0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
                     68:        PER_ISCR4 =             0x0005 | STICKY_TIMEOUTS,
                     69:        PER_BSD =               0x0006,
                     70:        PER_SUNOS =             0x0006 | STICKY_TIMEOUTS,
                     71:        PER_XENIX =             0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
                     72:        PER_LINUX32 =           0x0008,
                     73:        PER_LINUX32_3GB =       0x0008 | ADDR_LIMIT_3GB,
                     74:        PER_IRIX32 =            0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
                     75:        PER_IRIXN32 =           0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
                     76:        PER_IRIX64 =            0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
                     77:        PER_RISCOS =            0x000c,
                     78:        PER_SOLARIS =           0x000d | STICKY_TIMEOUTS,
                     79:        PER_UW7 =               0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
                     80:        PER_OSF4 =              0x000f,                  /* OSF/1 v4 */
                     81:        PER_HPUX =              0x0010,
                     82:        PER_MASK =              0x00ff,
                     83: };
                     84: 
                     85: /*
                     86:  * Return the base personality without flags.
                     87:  */
                     88: #define personality(pers)      (pers & PER_MASK)
                     89: 
1.1       root       90: /* this flag is uneffective under linux too, should be deleted */
                     91: #ifndef MAP_DENYWRITE
                     92: #define MAP_DENYWRITE 0
                     93: #endif
                     94: 
                     95: /* should probably go in elf.h */
                     96: #ifndef ELIBBAD
                     97: #define ELIBBAD 80
                     98: #endif
                     99: 
1.1.1.11! root      100: typedef target_ulong   target_elf_greg_t;
        !           101: #ifdef USE_UID16
        !           102: typedef uint16_t       target_uid_t;
        !           103: typedef uint16_t       target_gid_t;
        !           104: #else
        !           105: typedef uint32_t       target_uid_t;
        !           106: typedef uint32_t       target_gid_t;
        !           107: #endif
        !           108: typedef int32_t                target_pid_t;
        !           109: 
1.1       root      110: #ifdef TARGET_I386
                    111: 
1.1.1.2   root      112: #define ELF_PLATFORM get_elf_platform()
                    113: 
                    114: static const char *get_elf_platform(void)
                    115: {
                    116:     static char elf_platform[] = "i386";
1.1.1.7   root      117:     int family = (thread_env->cpuid_version >> 8) & 0xff;
1.1.1.2   root      118:     if (family > 6)
                    119:         family = 6;
                    120:     if (family >= 3)
                    121:         elf_platform[1] = '0' + family;
                    122:     return elf_platform;
                    123: }
                    124: 
                    125: #define ELF_HWCAP get_elf_hwcap()
                    126: 
                    127: static uint32_t get_elf_hwcap(void)
                    128: {
1.1.1.7   root      129:   return thread_env->cpuid_features;
1.1.1.2   root      130: }
                    131: 
1.1.1.6   root      132: #ifdef TARGET_X86_64
                    133: #define ELF_START_MMAP 0x2aaaaab000ULL
                    134: #define elf_check_arch(x) ( ((x) == ELF_ARCH) )
                    135: 
                    136: #define ELF_CLASS      ELFCLASS64
                    137: #define ELF_DATA       ELFDATA2LSB
                    138: #define ELF_ARCH       EM_X86_64
                    139: 
                    140: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    141: {
                    142:     regs->rax = 0;
                    143:     regs->rsp = infop->start_stack;
                    144:     regs->rip = infop->entry;
                    145: }
                    146: 
1.1.1.8   root      147: #define ELF_NREG    27
1.1.1.9   root      148: typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
1.1.1.8   root      149: 
                    150: /*
                    151:  * Note that ELF_NREG should be 29 as there should be place for
                    152:  * TRAPNO and ERR "registers" as well but linux doesn't dump
                    153:  * those.
                    154:  *
                    155:  * See linux kernel: arch/x86/include/asm/elf.h
                    156:  */
1.1.1.9   root      157: static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
1.1.1.8   root      158: {
                    159:     (*regs)[0] = env->regs[15];
                    160:     (*regs)[1] = env->regs[14];
                    161:     (*regs)[2] = env->regs[13];
                    162:     (*regs)[3] = env->regs[12];
                    163:     (*regs)[4] = env->regs[R_EBP];
                    164:     (*regs)[5] = env->regs[R_EBX];
                    165:     (*regs)[6] = env->regs[11];
                    166:     (*regs)[7] = env->regs[10];
                    167:     (*regs)[8] = env->regs[9];
                    168:     (*regs)[9] = env->regs[8];
                    169:     (*regs)[10] = env->regs[R_EAX];
                    170:     (*regs)[11] = env->regs[R_ECX];
                    171:     (*regs)[12] = env->regs[R_EDX];
                    172:     (*regs)[13] = env->regs[R_ESI];
                    173:     (*regs)[14] = env->regs[R_EDI];
                    174:     (*regs)[15] = env->regs[R_EAX]; /* XXX */
                    175:     (*regs)[16] = env->eip;
                    176:     (*regs)[17] = env->segs[R_CS].selector & 0xffff;
                    177:     (*regs)[18] = env->eflags;
                    178:     (*regs)[19] = env->regs[R_ESP];
                    179:     (*regs)[20] = env->segs[R_SS].selector & 0xffff;
                    180:     (*regs)[21] = env->segs[R_FS].selector & 0xffff;
                    181:     (*regs)[22] = env->segs[R_GS].selector & 0xffff;
                    182:     (*regs)[23] = env->segs[R_DS].selector & 0xffff;
                    183:     (*regs)[24] = env->segs[R_ES].selector & 0xffff;
                    184:     (*regs)[25] = env->segs[R_FS].selector & 0xffff;
                    185:     (*regs)[26] = env->segs[R_GS].selector & 0xffff;
                    186: }
                    187: 
1.1.1.6   root      188: #else
                    189: 
1.1       root      190: #define ELF_START_MMAP 0x80000000
                    191: 
                    192: /*
                    193:  * This is used to ensure we don't load something for the wrong architecture.
                    194:  */
                    195: #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
                    196: 
                    197: /*
                    198:  * These are used to set parameters in the core dumps.
                    199:  */
                    200: #define ELF_CLASS      ELFCLASS32
                    201: #define ELF_DATA       ELFDATA2LSB
                    202: #define ELF_ARCH       EM_386
                    203: 
                    204: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    205: {
                    206:     regs->esp = infop->start_stack;
                    207:     regs->eip = infop->entry;
1.1.1.4   root      208: 
                    209:     /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
                    210:        starts %edx contains a pointer to a function which might be
                    211:        registered using `atexit'.  This provides a mean for the
                    212:        dynamic linker to call DT_FINI functions for shared libraries
                    213:        that have been loaded before the code runs.
                    214: 
                    215:        A value of 0 tells we have no such handler.  */
                    216:     regs->edx = 0;
1.1       root      217: }
1.1.1.8   root      218: 
                    219: #define ELF_NREG    17
1.1.1.9   root      220: typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
1.1.1.8   root      221: 
                    222: /*
                    223:  * Note that ELF_NREG should be 19 as there should be place for
                    224:  * TRAPNO and ERR "registers" as well but linux doesn't dump
                    225:  * those.
                    226:  *
                    227:  * See linux kernel: arch/x86/include/asm/elf.h
                    228:  */
1.1.1.9   root      229: static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
1.1.1.8   root      230: {
                    231:     (*regs)[0] = env->regs[R_EBX];
                    232:     (*regs)[1] = env->regs[R_ECX];
                    233:     (*regs)[2] = env->regs[R_EDX];
                    234:     (*regs)[3] = env->regs[R_ESI];
                    235:     (*regs)[4] = env->regs[R_EDI];
                    236:     (*regs)[5] = env->regs[R_EBP];
                    237:     (*regs)[6] = env->regs[R_EAX];
                    238:     (*regs)[7] = env->segs[R_DS].selector & 0xffff;
                    239:     (*regs)[8] = env->segs[R_ES].selector & 0xffff;
                    240:     (*regs)[9] = env->segs[R_FS].selector & 0xffff;
                    241:     (*regs)[10] = env->segs[R_GS].selector & 0xffff;
                    242:     (*regs)[11] = env->regs[R_EAX]; /* XXX */
                    243:     (*regs)[12] = env->eip;
                    244:     (*regs)[13] = env->segs[R_CS].selector & 0xffff;
                    245:     (*regs)[14] = env->eflags;
                    246:     (*regs)[15] = env->regs[R_ESP];
                    247:     (*regs)[16] = env->segs[R_SS].selector & 0xffff;
                    248: }
1.1.1.6   root      249: #endif
1.1       root      250: 
                    251: #define USE_ELF_CORE_DUMP
                    252: #define ELF_EXEC_PAGESIZE      4096
                    253: 
                    254: #endif
                    255: 
                    256: #ifdef TARGET_ARM
                    257: 
                    258: #define ELF_START_MMAP 0x80000000
                    259: 
                    260: #define elf_check_arch(x) ( (x) == EM_ARM )
                    261: 
                    262: #define ELF_CLASS      ELFCLASS32
                    263: #ifdef TARGET_WORDS_BIGENDIAN
                    264: #define ELF_DATA       ELFDATA2MSB
                    265: #else
                    266: #define ELF_DATA       ELFDATA2LSB
                    267: #endif
                    268: #define ELF_ARCH       EM_ARM
                    269: 
                    270: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    271: {
1.1.1.6   root      272:     abi_long stack = infop->start_stack;
1.1       root      273:     memset(regs, 0, sizeof(*regs));
                    274:     regs->ARM_cpsr = 0x10;
1.1.1.3   root      275:     if (infop->entry & 1)
                    276:       regs->ARM_cpsr |= CPSR_T;
                    277:     regs->ARM_pc = infop->entry & 0xfffffffe;
1.1       root      278:     regs->ARM_sp = infop->start_stack;
1.1.1.6   root      279:     /* FIXME - what to for failure of get_user()? */
                    280:     get_user_ual(regs->ARM_r2, stack + 8); /* envp */
                    281:     get_user_ual(regs->ARM_r1, stack + 4); /* envp */
1.1       root      282:     /* XXX: it seems that r0 is zeroed after ! */
1.1.1.4   root      283:     regs->ARM_r0 = 0;
                    284:     /* For uClinux PIC binaries.  */
1.1.1.6   root      285:     /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
1.1.1.4   root      286:     regs->ARM_r10 = infop->start_data;
1.1       root      287: }
                    288: 
1.1.1.8   root      289: #define ELF_NREG    18
1.1.1.9   root      290: typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
1.1.1.8   root      291: 
1.1.1.9   root      292: static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
1.1.1.8   root      293: {
1.1.1.11! root      294:     (*regs)[0] = tswapl(env->regs[0]);
        !           295:     (*regs)[1] = tswapl(env->regs[1]);
        !           296:     (*regs)[2] = tswapl(env->regs[2]);
        !           297:     (*regs)[3] = tswapl(env->regs[3]);
        !           298:     (*regs)[4] = tswapl(env->regs[4]);
        !           299:     (*regs)[5] = tswapl(env->regs[5]);
        !           300:     (*regs)[6] = tswapl(env->regs[6]);
        !           301:     (*regs)[7] = tswapl(env->regs[7]);
        !           302:     (*regs)[8] = tswapl(env->regs[8]);
        !           303:     (*regs)[9] = tswapl(env->regs[9]);
        !           304:     (*regs)[10] = tswapl(env->regs[10]);
        !           305:     (*regs)[11] = tswapl(env->regs[11]);
        !           306:     (*regs)[12] = tswapl(env->regs[12]);
        !           307:     (*regs)[13] = tswapl(env->regs[13]);
        !           308:     (*regs)[14] = tswapl(env->regs[14]);
        !           309:     (*regs)[15] = tswapl(env->regs[15]);
1.1.1.8   root      310: 
1.1.1.11! root      311:     (*regs)[16] = tswapl(cpsr_read((CPUState *)env));
        !           312:     (*regs)[17] = tswapl(env->regs[0]); /* XXX */
1.1.1.8   root      313: }
                    314: 
1.1       root      315: #define USE_ELF_CORE_DUMP
                    316: #define ELF_EXEC_PAGESIZE      4096
                    317: 
1.1.1.2   root      318: enum
                    319: {
                    320:   ARM_HWCAP_ARM_SWP       = 1 << 0,
                    321:   ARM_HWCAP_ARM_HALF      = 1 << 1,
                    322:   ARM_HWCAP_ARM_THUMB     = 1 << 2,
                    323:   ARM_HWCAP_ARM_26BIT     = 1 << 3,
                    324:   ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
                    325:   ARM_HWCAP_ARM_FPA       = 1 << 5,
                    326:   ARM_HWCAP_ARM_VFP       = 1 << 6,
                    327:   ARM_HWCAP_ARM_EDSP      = 1 << 7,
1.1.1.10  root      328:   ARM_HWCAP_ARM_JAVA      = 1 << 8,
                    329:   ARM_HWCAP_ARM_IWMMXT    = 1 << 9,
                    330:   ARM_HWCAP_ARM_THUMBEE   = 1 << 10,
                    331:   ARM_HWCAP_ARM_NEON      = 1 << 11,
                    332:   ARM_HWCAP_ARM_VFPv3     = 1 << 12,
                    333:   ARM_HWCAP_ARM_VFPv3D16  = 1 << 13,
1.1.1.2   root      334: };
                    335: 
                    336: #define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \
                    337:                     | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \
1.1.1.10  root      338:                     | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP \
                    339:                     | ARM_HWCAP_ARM_NEON | ARM_HWCAP_ARM_VFPv3 )
1.1.1.2   root      340: 
1.1       root      341: #endif
                    342: 
                    343: #ifdef TARGET_SPARC
                    344: #ifdef TARGET_SPARC64
                    345: 
                    346: #define ELF_START_MMAP 0x80000000
                    347: 
1.1.1.6   root      348: #ifndef TARGET_ABI32
                    349: #define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
                    350: #else
                    351: #define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
                    352: #endif
1.1       root      353: 
                    354: #define ELF_CLASS   ELFCLASS64
                    355: #define ELF_DATA    ELFDATA2MSB
1.1.1.4   root      356: #define ELF_ARCH    EM_SPARCV9
1.1       root      357: 
1.1.1.4   root      358: #define STACK_BIAS             2047
1.1       root      359: 
                    360: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    361: {
1.1.1.6   root      362: #ifndef TARGET_ABI32
1.1       root      363:     regs->tstate = 0;
1.1.1.6   root      364: #endif
1.1       root      365:     regs->pc = infop->entry;
                    366:     regs->npc = regs->pc + 4;
                    367:     regs->y = 0;
1.1.1.6   root      368: #ifdef TARGET_ABI32
                    369:     regs->u_regs[14] = infop->start_stack - 16 * 4;
                    370: #else
                    371:     if (personality(infop->personality) == PER_LINUX32)
                    372:         regs->u_regs[14] = infop->start_stack - 16 * 4;
                    373:     else
                    374:         regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
                    375: #endif
1.1       root      376: }
                    377: 
                    378: #else
                    379: #define ELF_START_MMAP 0x80000000
                    380: 
                    381: #define elf_check_arch(x) ( (x) == EM_SPARC )
                    382: 
                    383: #define ELF_CLASS   ELFCLASS32
                    384: #define ELF_DATA    ELFDATA2MSB
                    385: #define ELF_ARCH    EM_SPARC
                    386: 
                    387: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    388: {
                    389:     regs->psr = 0;
                    390:     regs->pc = infop->entry;
                    391:     regs->npc = regs->pc + 4;
                    392:     regs->y = 0;
                    393:     regs->u_regs[14] = infop->start_stack - 16 * 4;
                    394: }
                    395: 
                    396: #endif
                    397: #endif
                    398: 
                    399: #ifdef TARGET_PPC
                    400: 
                    401: #define ELF_START_MMAP 0x80000000
                    402: 
1.1.1.6   root      403: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
                    404: 
                    405: #define elf_check_arch(x) ( (x) == EM_PPC64 )
                    406: 
                    407: #define ELF_CLASS      ELFCLASS64
                    408: 
                    409: #else
                    410: 
1.1       root      411: #define elf_check_arch(x) ( (x) == EM_PPC )
                    412: 
                    413: #define ELF_CLASS      ELFCLASS32
1.1.1.6   root      414: 
                    415: #endif
                    416: 
1.1       root      417: #ifdef TARGET_WORDS_BIGENDIAN
                    418: #define ELF_DATA       ELFDATA2MSB
                    419: #else
                    420: #define ELF_DATA       ELFDATA2LSB
                    421: #endif
                    422: #define ELF_ARCH       EM_PPC
                    423: 
1.1.1.8   root      424: /* Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP).
                    425:    See arch/powerpc/include/asm/cputable.h.  */
                    426: enum {
1.1.1.10  root      427:     QEMU_PPC_FEATURE_32 = 0x80000000,
                    428:     QEMU_PPC_FEATURE_64 = 0x40000000,
                    429:     QEMU_PPC_FEATURE_601_INSTR = 0x20000000,
                    430:     QEMU_PPC_FEATURE_HAS_ALTIVEC = 0x10000000,
                    431:     QEMU_PPC_FEATURE_HAS_FPU = 0x08000000,
                    432:     QEMU_PPC_FEATURE_HAS_MMU = 0x04000000,
                    433:     QEMU_PPC_FEATURE_HAS_4xxMAC = 0x02000000,
                    434:     QEMU_PPC_FEATURE_UNIFIED_CACHE = 0x01000000,
                    435:     QEMU_PPC_FEATURE_HAS_SPE = 0x00800000,
                    436:     QEMU_PPC_FEATURE_HAS_EFP_SINGLE = 0x00400000,
                    437:     QEMU_PPC_FEATURE_HAS_EFP_DOUBLE = 0x00200000,
                    438:     QEMU_PPC_FEATURE_NO_TB = 0x00100000,
                    439:     QEMU_PPC_FEATURE_POWER4 = 0x00080000,
                    440:     QEMU_PPC_FEATURE_POWER5 = 0x00040000,
                    441:     QEMU_PPC_FEATURE_POWER5_PLUS = 0x00020000,
                    442:     QEMU_PPC_FEATURE_CELL = 0x00010000,
                    443:     QEMU_PPC_FEATURE_BOOKE = 0x00008000,
                    444:     QEMU_PPC_FEATURE_SMT = 0x00004000,
                    445:     QEMU_PPC_FEATURE_ICACHE_SNOOP = 0x00002000,
                    446:     QEMU_PPC_FEATURE_ARCH_2_05 = 0x00001000,
                    447:     QEMU_PPC_FEATURE_PA6T = 0x00000800,
                    448:     QEMU_PPC_FEATURE_HAS_DFP = 0x00000400,
                    449:     QEMU_PPC_FEATURE_POWER6_EXT = 0x00000200,
                    450:     QEMU_PPC_FEATURE_ARCH_2_06 = 0x00000100,
                    451:     QEMU_PPC_FEATURE_HAS_VSX = 0x00000080,
                    452:     QEMU_PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040,
1.1.1.8   root      453: 
1.1.1.10  root      454:     QEMU_PPC_FEATURE_TRUE_LE = 0x00000002,
                    455:     QEMU_PPC_FEATURE_PPC_LE = 0x00000001,
1.1.1.8   root      456: };
                    457: 
                    458: #define ELF_HWCAP get_elf_hwcap()
                    459: 
                    460: static uint32_t get_elf_hwcap(void)
                    461: {
                    462:     CPUState *e = thread_env;
                    463:     uint32_t features = 0;
                    464: 
                    465:     /* We don't have to be terribly complete here; the high points are
                    466:        Altivec/FP/SPE support.  Anything else is just a bonus.  */
                    467: #define GET_FEATURE(flag, feature)              \
                    468:     do {if (e->insns_flags & flag) features |= feature; } while(0)
1.1.1.10  root      469:     GET_FEATURE(PPC_64B, QEMU_PPC_FEATURE_64);
                    470:     GET_FEATURE(PPC_FLOAT, QEMU_PPC_FEATURE_HAS_FPU);
                    471:     GET_FEATURE(PPC_ALTIVEC, QEMU_PPC_FEATURE_HAS_ALTIVEC);
                    472:     GET_FEATURE(PPC_SPE, QEMU_PPC_FEATURE_HAS_SPE);
                    473:     GET_FEATURE(PPC_SPE_SINGLE, QEMU_PPC_FEATURE_HAS_EFP_SINGLE);
                    474:     GET_FEATURE(PPC_SPE_DOUBLE, QEMU_PPC_FEATURE_HAS_EFP_DOUBLE);
                    475:     GET_FEATURE(PPC_BOOKE, QEMU_PPC_FEATURE_BOOKE);
                    476:     GET_FEATURE(PPC_405_MAC, QEMU_PPC_FEATURE_HAS_4xxMAC);
1.1.1.8   root      477: #undef GET_FEATURE
                    478: 
                    479:     return features;
                    480: }
                    481: 
1.1       root      482: /*
                    483:  * We need to put in some extra aux table entries to tell glibc what
                    484:  * the cache block size is, so it can use the dcbz instruction safely.
                    485:  */
                    486: #define AT_DCACHEBSIZE          19
                    487: #define AT_ICACHEBSIZE          20
                    488: #define AT_UCACHEBSIZE          21
                    489: /* A special ignored type value for PPC, for glibc compatibility.  */
                    490: #define AT_IGNOREPPC            22
                    491: /*
                    492:  * The requirements here are:
                    493:  * - keep the final alignment of sp (sp & 0xf)
                    494:  * - make sure the 32-bit value at the first 16 byte aligned position of
                    495:  *   AUXV is greater than 16 for glibc compatibility.
                    496:  *   AT_IGNOREPPC is used for that.
                    497:  * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
                    498:  *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
                    499:  */
                    500: #define DLINFO_ARCH_ITEMS       5
                    501: #define ARCH_DLINFO                                                     \
                    502: do {                                                                    \
                    503:         NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \
                    504:         NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \
                    505:         NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \
                    506:         /*                                                              \
                    507:          * Now handle glibc compatibility.                              \
                    508:          */                                                             \
                    509:        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
                    510:        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
                    511:  } while (0)
                    512: 
                    513: static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
                    514: {
                    515:     _regs->gpr[1] = infop->start_stack;
1.1.1.6   root      516: #if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
1.1.1.11! root      517:     _regs->gpr[2] = ldq_raw(infop->entry + 8) + infop->load_addr;
        !           518:     infop->entry = ldq_raw(infop->entry) + infop->load_addr;
1.1.1.6   root      519: #endif
1.1       root      520:     _regs->nip = infop->entry;
                    521: }
                    522: 
1.1.1.11! root      523: /* See linux kernel: arch/powerpc/include/asm/elf.h.  */
        !           524: #define ELF_NREG 48
        !           525: typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
        !           526: 
        !           527: static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
        !           528: {
        !           529:     int i;
        !           530:     target_ulong ccr = 0;
        !           531: 
        !           532:     for (i = 0; i < ARRAY_SIZE(env->gpr); i++) {
        !           533:         (*regs)[i] = tswapl(env->gpr[i]);
        !           534:     }
        !           535: 
        !           536:     (*regs)[32] = tswapl(env->nip);
        !           537:     (*regs)[33] = tswapl(env->msr);
        !           538:     (*regs)[35] = tswapl(env->ctr);
        !           539:     (*regs)[36] = tswapl(env->lr);
        !           540:     (*regs)[37] = tswapl(env->xer);
        !           541: 
        !           542:     for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
        !           543:         ccr |= env->crf[i] << (32 - ((i + 1) * 4));
        !           544:     }
        !           545:     (*regs)[38] = tswapl(ccr);
        !           546: }
        !           547: 
        !           548: #define USE_ELF_CORE_DUMP
1.1       root      549: #define ELF_EXEC_PAGESIZE      4096
                    550: 
                    551: #endif
                    552: 
1.1.1.2   root      553: #ifdef TARGET_MIPS
                    554: 
                    555: #define ELF_START_MMAP 0x80000000
                    556: 
                    557: #define elf_check_arch(x) ( (x) == EM_MIPS )
                    558: 
1.1.1.6   root      559: #ifdef TARGET_MIPS64
                    560: #define ELF_CLASS   ELFCLASS64
                    561: #else
1.1.1.2   root      562: #define ELF_CLASS   ELFCLASS32
1.1.1.6   root      563: #endif
1.1.1.2   root      564: #ifdef TARGET_WORDS_BIGENDIAN
                    565: #define ELF_DATA       ELFDATA2MSB
                    566: #else
                    567: #define ELF_DATA       ELFDATA2LSB
                    568: #endif
                    569: #define ELF_ARCH    EM_MIPS
                    570: 
                    571: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    572: {
1.1.1.6   root      573:     regs->cp0_status = 2 << CP0St_KSU;
1.1.1.2   root      574:     regs->cp0_epc = infop->entry;
                    575:     regs->regs[29] = infop->start_stack;
                    576: }
                    577: 
1.1.1.11! root      578: /* See linux kernel: arch/mips/include/asm/elf.h.  */
        !           579: #define ELF_NREG 45
        !           580: typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
        !           581: 
        !           582: /* See linux kernel: arch/mips/include/asm/reg.h.  */
        !           583: enum {
        !           584: #ifdef TARGET_MIPS64
        !           585:     TARGET_EF_R0 = 0,
        !           586: #else
        !           587:     TARGET_EF_R0 = 6,
        !           588: #endif
        !           589:     TARGET_EF_R26 = TARGET_EF_R0 + 26,
        !           590:     TARGET_EF_R27 = TARGET_EF_R0 + 27,
        !           591:     TARGET_EF_LO = TARGET_EF_R0 + 32,
        !           592:     TARGET_EF_HI = TARGET_EF_R0 + 33,
        !           593:     TARGET_EF_CP0_EPC = TARGET_EF_R0 + 34,
        !           594:     TARGET_EF_CP0_BADVADDR = TARGET_EF_R0 + 35,
        !           595:     TARGET_EF_CP0_STATUS = TARGET_EF_R0 + 36,
        !           596:     TARGET_EF_CP0_CAUSE = TARGET_EF_R0 + 37
        !           597: };
        !           598: 
        !           599: /* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs.  */
        !           600: static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
        !           601: {
        !           602:     int i;
        !           603: 
        !           604:     for (i = 0; i < TARGET_EF_R0; i++) {
        !           605:         (*regs)[i] = 0;
        !           606:     }
        !           607:     (*regs)[TARGET_EF_R0] = 0;
        !           608: 
        !           609:     for (i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) {
        !           610:         (*regs)[TARGET_EF_R0 + i] = tswapl(env->active_tc.gpr[i]);
        !           611:     }
        !           612: 
        !           613:     (*regs)[TARGET_EF_R26] = 0;
        !           614:     (*regs)[TARGET_EF_R27] = 0;
        !           615:     (*regs)[TARGET_EF_LO] = tswapl(env->active_tc.LO[0]);
        !           616:     (*regs)[TARGET_EF_HI] = tswapl(env->active_tc.HI[0]);
        !           617:     (*regs)[TARGET_EF_CP0_EPC] = tswapl(env->active_tc.PC);
        !           618:     (*regs)[TARGET_EF_CP0_BADVADDR] = tswapl(env->CP0_BadVAddr);
        !           619:     (*regs)[TARGET_EF_CP0_STATUS] = tswapl(env->CP0_Status);
        !           620:     (*regs)[TARGET_EF_CP0_CAUSE] = tswapl(env->CP0_Cause);
        !           621: }
        !           622: 
        !           623: #define USE_ELF_CORE_DUMP
1.1.1.6   root      624: #define ELF_EXEC_PAGESIZE        4096
                    625: 
1.1.1.2   root      626: #endif /* TARGET_MIPS */
                    627: 
1.1.1.8   root      628: #ifdef TARGET_MICROBLAZE
                    629: 
                    630: #define ELF_START_MMAP 0x80000000
                    631: 
1.1.1.11! root      632: #define elf_check_arch(x) ( (x) == EM_MICROBLAZE || (x) == EM_MICROBLAZE_OLD)
1.1.1.8   root      633: 
                    634: #define ELF_CLASS   ELFCLASS32
                    635: #define ELF_DATA       ELFDATA2MSB
1.1.1.11! root      636: #define ELF_ARCH    EM_MICROBLAZE
1.1.1.8   root      637: 
                    638: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    639: {
                    640:     regs->pc = infop->entry;
                    641:     regs->r1 = infop->start_stack;
                    642: 
                    643: }
                    644: 
                    645: #define ELF_EXEC_PAGESIZE        4096
                    646: 
1.1.1.11! root      647: #define USE_ELF_CORE_DUMP
        !           648: #define ELF_NREG 38
        !           649: typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
        !           650: 
        !           651: /* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs.  */
        !           652: static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
        !           653: {
        !           654:     int i, pos = 0;
        !           655: 
        !           656:     for (i = 0; i < 32; i++) {
        !           657:         (*regs)[pos++] = tswapl(env->regs[i]);
        !           658:     }
        !           659: 
        !           660:     for (i = 0; i < 6; i++) {
        !           661:         (*regs)[pos++] = tswapl(env->sregs[i]);
        !           662:     }
        !           663: }
        !           664: 
1.1.1.8   root      665: #endif /* TARGET_MICROBLAZE */
                    666: 
1.1.1.3   root      667: #ifdef TARGET_SH4
                    668: 
                    669: #define ELF_START_MMAP 0x80000000
                    670: 
                    671: #define elf_check_arch(x) ( (x) == EM_SH )
                    672: 
                    673: #define ELF_CLASS ELFCLASS32
                    674: #define ELF_DATA  ELFDATA2LSB
                    675: #define ELF_ARCH  EM_SH
                    676: 
                    677: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    678: {
                    679:   /* Check other registers XXXXX */
                    680:   regs->pc = infop->entry;
1.1.1.6   root      681:   regs->regs[15] = infop->start_stack;
1.1.1.3   root      682: }
                    683: 
1.1.1.11! root      684: /* See linux kernel: arch/sh/include/asm/elf.h.  */
        !           685: #define ELF_NREG 23
        !           686: typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
        !           687: 
        !           688: /* See linux kernel: arch/sh/include/asm/ptrace.h.  */
        !           689: enum {
        !           690:     TARGET_REG_PC = 16,
        !           691:     TARGET_REG_PR = 17,
        !           692:     TARGET_REG_SR = 18,
        !           693:     TARGET_REG_GBR = 19,
        !           694:     TARGET_REG_MACH = 20,
        !           695:     TARGET_REG_MACL = 21,
        !           696:     TARGET_REG_SYSCALL = 22
        !           697: };
        !           698: 
        !           699: static inline void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
        !           700: {
        !           701:     int i;
        !           702: 
        !           703:     for (i = 0; i < 16; i++) {
        !           704:         (*regs[i]) = tswapl(env->gregs[i]);
        !           705:     }
        !           706: 
        !           707:     (*regs)[TARGET_REG_PC] = tswapl(env->pc);
        !           708:     (*regs)[TARGET_REG_PR] = tswapl(env->pr);
        !           709:     (*regs)[TARGET_REG_SR] = tswapl(env->sr);
        !           710:     (*regs)[TARGET_REG_GBR] = tswapl(env->gbr);
        !           711:     (*regs)[TARGET_REG_MACH] = tswapl(env->mach);
        !           712:     (*regs)[TARGET_REG_MACL] = tswapl(env->macl);
        !           713:     (*regs)[TARGET_REG_SYSCALL] = 0; /* FIXME */
        !           714: }
        !           715: 
        !           716: #define USE_ELF_CORE_DUMP
1.1.1.3   root      717: #define ELF_EXEC_PAGESIZE        4096
                    718: 
                    719: #endif
                    720: 
1.1.1.6   root      721: #ifdef TARGET_CRIS
                    722: 
                    723: #define ELF_START_MMAP 0x80000000
                    724: 
                    725: #define elf_check_arch(x) ( (x) == EM_CRIS )
                    726: 
                    727: #define ELF_CLASS ELFCLASS32
                    728: #define ELF_DATA  ELFDATA2LSB
                    729: #define ELF_ARCH  EM_CRIS
                    730: 
                    731: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    732: {
                    733:   regs->erp = infop->entry;
                    734: }
                    735: 
                    736: #define ELF_EXEC_PAGESIZE        8192
                    737: 
                    738: #endif
                    739: 
1.1.1.5   root      740: #ifdef TARGET_M68K
                    741: 
                    742: #define ELF_START_MMAP 0x80000000
                    743: 
                    744: #define elf_check_arch(x) ( (x) == EM_68K )
                    745: 
                    746: #define ELF_CLASS      ELFCLASS32
                    747: #define ELF_DATA       ELFDATA2MSB
                    748: #define ELF_ARCH       EM_68K
                    749: 
                    750: /* ??? Does this need to do anything?
                    751: #define ELF_PLAT_INIT(_r) */
                    752: 
                    753: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    754: {
                    755:     regs->usp = infop->start_stack;
                    756:     regs->sr = 0;
                    757:     regs->pc = infop->entry;
                    758: }
                    759: 
1.1.1.11! root      760: /* See linux kernel: arch/m68k/include/asm/elf.h.  */
        !           761: #define ELF_NREG 20
        !           762: typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
        !           763: 
        !           764: static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
        !           765: {
        !           766:     (*regs)[0] = tswapl(env->dregs[1]);
        !           767:     (*regs)[1] = tswapl(env->dregs[2]);
        !           768:     (*regs)[2] = tswapl(env->dregs[3]);
        !           769:     (*regs)[3] = tswapl(env->dregs[4]);
        !           770:     (*regs)[4] = tswapl(env->dregs[5]);
        !           771:     (*regs)[5] = tswapl(env->dregs[6]);
        !           772:     (*regs)[6] = tswapl(env->dregs[7]);
        !           773:     (*regs)[7] = tswapl(env->aregs[0]);
        !           774:     (*regs)[8] = tswapl(env->aregs[1]);
        !           775:     (*regs)[9] = tswapl(env->aregs[2]);
        !           776:     (*regs)[10] = tswapl(env->aregs[3]);
        !           777:     (*regs)[11] = tswapl(env->aregs[4]);
        !           778:     (*regs)[12] = tswapl(env->aregs[5]);
        !           779:     (*regs)[13] = tswapl(env->aregs[6]);
        !           780:     (*regs)[14] = tswapl(env->dregs[0]);
        !           781:     (*regs)[15] = tswapl(env->aregs[7]);
        !           782:     (*regs)[16] = tswapl(env->dregs[0]); /* FIXME: orig_d0 */
        !           783:     (*regs)[17] = tswapl(env->sr);
        !           784:     (*regs)[18] = tswapl(env->pc);
        !           785:     (*regs)[19] = 0;  /* FIXME: regs->format | regs->vector */
        !           786: }
        !           787: 
        !           788: #define USE_ELF_CORE_DUMP
1.1.1.5   root      789: #define ELF_EXEC_PAGESIZE      8192
                    790: 
                    791: #endif
                    792: 
1.1.1.6   root      793: #ifdef TARGET_ALPHA
                    794: 
                    795: #define ELF_START_MMAP (0x30000000000ULL)
                    796: 
                    797: #define elf_check_arch(x) ( (x) == ELF_ARCH )
                    798: 
                    799: #define ELF_CLASS      ELFCLASS64
                    800: #define ELF_DATA       ELFDATA2MSB
                    801: #define ELF_ARCH       EM_ALPHA
                    802: 
                    803: static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
                    804: {
                    805:     regs->pc = infop->entry;
                    806:     regs->ps = 8;
                    807:     regs->usp = infop->start_stack;
                    808: }
                    809: 
                    810: #define ELF_EXEC_PAGESIZE        8192
                    811: 
                    812: #endif /* TARGET_ALPHA */
                    813: 
1.1.1.2   root      814: #ifndef ELF_PLATFORM
                    815: #define ELF_PLATFORM (NULL)
                    816: #endif
                    817: 
                    818: #ifndef ELF_HWCAP
                    819: #define ELF_HWCAP 0
                    820: #endif
                    821: 
1.1.1.6   root      822: #ifdef TARGET_ABI32
                    823: #undef ELF_CLASS
                    824: #define ELF_CLASS ELFCLASS32
                    825: #undef bswaptls
                    826: #define bswaptls(ptr) bswap32s(ptr)
                    827: #endif
                    828: 
1.1       root      829: #include "elf.h"
                    830: 
                    831: struct exec
                    832: {
                    833:   unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
                    834:   unsigned int a_text;   /* length of text, in bytes */
                    835:   unsigned int a_data;   /* length of data, in bytes */
                    836:   unsigned int a_bss;    /* length of uninitialized data area, in bytes */
                    837:   unsigned int a_syms;   /* length of symbol table data in file, in bytes */
                    838:   unsigned int a_entry;  /* start address */
                    839:   unsigned int a_trsize; /* length of relocation info for text, in bytes */
                    840:   unsigned int a_drsize; /* length of relocation info for data, in bytes */
                    841: };
                    842: 
                    843: 
                    844: #define N_MAGIC(exec) ((exec).a_info & 0xffff)
                    845: #define OMAGIC 0407
                    846: #define NMAGIC 0410
                    847: #define ZMAGIC 0413
                    848: #define QMAGIC 0314
                    849: 
                    850: /* max code+data+bss space allocated to elf interpreter */
                    851: #define INTERP_MAP_SIZE (32 * 1024 * 1024)
                    852: 
                    853: /* max code+data+bss+brk space allocated to ET_DYN executables */
                    854: #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
                    855: 
                    856: /* Necessary parameters */
                    857: #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
                    858: #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
                    859: #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
                    860: 
                    861: #define INTERPRETER_NONE 0
                    862: #define INTERPRETER_AOUT 1
                    863: #define INTERPRETER_ELF 2
                    864: 
1.1.1.2   root      865: #define DLINFO_ITEMS 12
1.1       root      866: 
                    867: static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
                    868: {
                    869:        memcpy(to, from, n);
                    870: }
                    871: 
                    872: static int load_aout_interp(void * exptr, int interp_fd);
                    873: 
                    874: #ifdef BSWAP_NEEDED
                    875: static void bswap_ehdr(struct elfhdr *ehdr)
                    876: {
                    877:     bswap16s(&ehdr->e_type);                   /* Object file type */
                    878:     bswap16s(&ehdr->e_machine);                /* Architecture */
                    879:     bswap32s(&ehdr->e_version);                /* Object file version */
                    880:     bswaptls(&ehdr->e_entry);          /* Entry point virtual address */
                    881:     bswaptls(&ehdr->e_phoff);          /* Program header table file offset */
                    882:     bswaptls(&ehdr->e_shoff);          /* Section header table file offset */
                    883:     bswap32s(&ehdr->e_flags);          /* Processor-specific flags */
                    884:     bswap16s(&ehdr->e_ehsize);         /* ELF header size in bytes */
                    885:     bswap16s(&ehdr->e_phentsize);              /* Program header table entry size */
                    886:     bswap16s(&ehdr->e_phnum);          /* Program header table entry count */
                    887:     bswap16s(&ehdr->e_shentsize);              /* Section header table entry size */
                    888:     bswap16s(&ehdr->e_shnum);          /* Section header table entry count */
                    889:     bswap16s(&ehdr->e_shstrndx);               /* Section header string table index */
                    890: }
                    891: 
                    892: static void bswap_phdr(struct elf_phdr *phdr)
                    893: {
                    894:     bswap32s(&phdr->p_type);                   /* Segment type */
                    895:     bswaptls(&phdr->p_offset);         /* Segment file offset */
                    896:     bswaptls(&phdr->p_vaddr);          /* Segment virtual address */
                    897:     bswaptls(&phdr->p_paddr);          /* Segment physical address */
                    898:     bswaptls(&phdr->p_filesz);         /* Segment size in file */
                    899:     bswaptls(&phdr->p_memsz);          /* Segment size in memory */
                    900:     bswap32s(&phdr->p_flags);          /* Segment flags */
                    901:     bswaptls(&phdr->p_align);          /* Segment alignment */
                    902: }
                    903: 
                    904: static void bswap_shdr(struct elf_shdr *shdr)
                    905: {
                    906:     bswap32s(&shdr->sh_name);
                    907:     bswap32s(&shdr->sh_type);
                    908:     bswaptls(&shdr->sh_flags);
                    909:     bswaptls(&shdr->sh_addr);
                    910:     bswaptls(&shdr->sh_offset);
                    911:     bswaptls(&shdr->sh_size);
                    912:     bswap32s(&shdr->sh_link);
                    913:     bswap32s(&shdr->sh_info);
                    914:     bswaptls(&shdr->sh_addralign);
                    915:     bswaptls(&shdr->sh_entsize);
                    916: }
                    917: 
1.1.1.6   root      918: static void bswap_sym(struct elf_sym *sym)
1.1       root      919: {
                    920:     bswap32s(&sym->st_name);
1.1.1.6   root      921:     bswaptls(&sym->st_value);
                    922:     bswaptls(&sym->st_size);
1.1       root      923:     bswap16s(&sym->st_shndx);
                    924: }
                    925: #endif
                    926: 
1.1.1.8   root      927: #ifdef USE_ELF_CORE_DUMP
                    928: static int elf_core_dump(int, const CPUState *);
                    929: 
                    930: #ifdef BSWAP_NEEDED
                    931: static void bswap_note(struct elf_note *en)
                    932: {
1.1.1.10  root      933:     bswap32s(&en->n_namesz);
                    934:     bswap32s(&en->n_descsz);
                    935:     bswap32s(&en->n_type);
1.1.1.8   root      936: }
                    937: #endif /* BSWAP_NEEDED */
                    938: 
                    939: #endif /* USE_ELF_CORE_DUMP */
                    940: 
1.1       root      941: /*
1.1.1.4   root      942:  * 'copy_elf_strings()' copies argument/envelope strings from user
1.1       root      943:  * memory to free pages in kernel mem. These are in a format ready
                    944:  * to be put directly into the top of new user memory.
                    945:  *
                    946:  */
1.1.1.6   root      947: static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
                    948:                                   abi_ulong p)
1.1       root      949: {
                    950:     char *tmp, *tmp1, *pag = NULL;
                    951:     int len, offset = 0;
                    952: 
                    953:     if (!p) {
                    954:        return 0;       /* bullet-proofing */
                    955:     }
                    956:     while (argc-- > 0) {
                    957:         tmp = argv[argc];
                    958:         if (!tmp) {
                    959:            fprintf(stderr, "VFS: argc is wrong");
                    960:            exit(-1);
                    961:        }
                    962:         tmp1 = tmp;
                    963:        while (*tmp++);
                    964:        len = tmp - tmp1;
                    965:        if (p < len) {  /* this shouldn't happen - 128kB */
                    966:                return 0;
                    967:        }
                    968:        while (len) {
                    969:            --p; --tmp; --len;
                    970:            if (--offset < 0) {
                    971:                offset = p % TARGET_PAGE_SIZE;
1.1.1.3   root      972:                 pag = (char *)page[p/TARGET_PAGE_SIZE];
1.1       root      973:                 if (!pag) {
1.1.1.3   root      974:                     pag = (char *)malloc(TARGET_PAGE_SIZE);
1.1.1.6   root      975:                     memset(pag, 0, TARGET_PAGE_SIZE);
1.1.1.3   root      976:                     page[p/TARGET_PAGE_SIZE] = pag;
1.1       root      977:                     if (!pag)
                    978:                         return 0;
                    979:                }
                    980:            }
                    981:            if (len == 0 || offset == 0) {
                    982:                *(pag + offset) = *tmp;
                    983:            }
                    984:            else {
                    985:              int bytes_to_copy = (len > offset) ? offset : len;
                    986:              tmp -= bytes_to_copy;
                    987:              p -= bytes_to_copy;
                    988:              offset -= bytes_to_copy;
                    989:              len -= bytes_to_copy;
                    990:              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
                    991:            }
                    992:        }
                    993:     }
                    994:     return p;
                    995: }
                    996: 
1.1.1.6   root      997: static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
                    998:                                  struct image_info *info)
1.1       root      999: {
1.1.1.6   root     1000:     abi_ulong stack_base, size, error;
1.1       root     1001:     int i;
                   1002: 
                   1003:     /* Create enough stack to hold everything.  If we don't use
                   1004:      * it for args, we'll use it for something else...
                   1005:      */
1.1.1.11! root     1006:     size = guest_stack_size;
1.1       root     1007:     if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
                   1008:         size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
1.1.1.6   root     1009:     error = target_mmap(0,
1.1       root     1010:                         size + qemu_host_page_size,
                   1011:                         PROT_READ | PROT_WRITE,
                   1012:                         MAP_PRIVATE | MAP_ANONYMOUS,
                   1013:                         -1, 0);
                   1014:     if (error == -1) {
                   1015:         perror("stk mmap");
                   1016:         exit(-1);
                   1017:     }
                   1018:     /* we reserve one extra page at the top of the stack as guard */
                   1019:     target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
                   1020: 
1.1.1.11! root     1021:     info->stack_limit = error;
1.1       root     1022:     stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
                   1023:     p += stack_base;
                   1024: 
                   1025:     for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
                   1026:        if (bprm->page[i]) {
                   1027:            info->rss++;
1.1.1.6   root     1028:             /* FIXME - check return value of memcpy_to_target() for failure */
1.1.1.3   root     1029:            memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
                   1030:            free(bprm->page[i]);
1.1       root     1031:        }
1.1.1.3   root     1032:         stack_base += TARGET_PAGE_SIZE;
1.1       root     1033:     }
                   1034:     return p;
                   1035: }
                   1036: 
1.1.1.6   root     1037: static void set_brk(abi_ulong start, abi_ulong end)
1.1       root     1038: {
                   1039:        /* page-align the start and end addresses... */
                   1040:         start = HOST_PAGE_ALIGN(start);
                   1041:         end = HOST_PAGE_ALIGN(end);
                   1042:         if (end <= start)
                   1043:                 return;
                   1044:         if(target_mmap(start, end - start,
                   1045:                        PROT_READ | PROT_WRITE | PROT_EXEC,
                   1046:                        MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
                   1047:            perror("cannot mmap brk");
                   1048:            exit(-1);
                   1049:        }
                   1050: }
                   1051: 
                   1052: 
                   1053: /* We need to explicitly zero any fractional pages after the data
                   1054:    section (i.e. bss).  This would contain the junk from the file that
                   1055:    should not be in memory. */
1.1.1.6   root     1056: static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
1.1       root     1057: {
1.1.1.6   root     1058:         abi_ulong nbyte;
1.1       root     1059: 
1.1.1.5   root     1060:        if (elf_bss >= last_bss)
                   1061:                return;
                   1062: 
1.1       root     1063:         /* XXX: this is really a hack : if the real host page size is
                   1064:            smaller than the target page size, some pages after the end
                   1065:            of the file may not be mapped. A better fix would be to
                   1066:            patch target_mmap(), but it is more complicated as the file
                   1067:            size must be known */
                   1068:         if (qemu_real_host_page_size < qemu_host_page_size) {
1.1.1.6   root     1069:             abi_ulong end_addr, end_addr1;
                   1070:             end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
1.1       root     1071:                 ~(qemu_real_host_page_size - 1);
                   1072:             end_addr = HOST_PAGE_ALIGN(elf_bss);
                   1073:             if (end_addr1 < end_addr) {
1.1.1.6   root     1074:                 mmap((void *)g2h(end_addr1), end_addr - end_addr1,
1.1       root     1075:                      PROT_READ|PROT_WRITE|PROT_EXEC,
                   1076:                      MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
                   1077:             }
                   1078:         }
                   1079: 
                   1080:         nbyte = elf_bss & (qemu_host_page_size-1);
                   1081:         if (nbyte) {
                   1082:            nbyte = qemu_host_page_size - nbyte;
                   1083:            do {
1.1.1.6   root     1084:                 /* FIXME - what to do if put_user() fails? */
                   1085:                put_user_u8(0, elf_bss);
1.1.1.3   root     1086:                 elf_bss++;
1.1       root     1087:            } while (--nbyte);
                   1088:         }
                   1089: }
                   1090: 
1.1.1.3   root     1091: 
1.1.1.6   root     1092: static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
                   1093:                                    struct elfhdr * exec,
                   1094:                                    abi_ulong load_addr,
                   1095:                                    abi_ulong load_bias,
                   1096:                                    abi_ulong interp_load_addr, int ibcs,
                   1097:                                    struct image_info *info)
1.1.1.3   root     1098: {
1.1.1.6   root     1099:         abi_ulong sp;
1.1.1.3   root     1100:         int size;
1.1.1.6   root     1101:         abi_ulong u_platform;
1.1.1.2   root     1102:         const char *k_platform;
1.1.1.6   root     1103:         const int n = sizeof(elf_addr_t);
1.1       root     1104: 
1.1.1.3   root     1105:         sp = p;
                   1106:         u_platform = 0;
1.1.1.2   root     1107:         k_platform = ELF_PLATFORM;
                   1108:         if (k_platform) {
                   1109:             size_t len = strlen(k_platform) + 1;
1.1.1.3   root     1110:             sp -= (len + n - 1) & ~(n - 1);
                   1111:             u_platform = sp;
1.1.1.6   root     1112:             /* FIXME - check return value of memcpy_to_target() for failure */
1.1.1.3   root     1113:             memcpy_to_target(sp, k_platform, len);
1.1.1.2   root     1114:         }
1.1.1.3   root     1115:        /*
                   1116:         * Force 16 byte _final_ alignment here for generality.
                   1117:         */
1.1.1.6   root     1118:         sp = sp &~ (abi_ulong)15;
1.1.1.3   root     1119:         size = (DLINFO_ITEMS + 1) * 2;
1.1.1.2   root     1120:         if (k_platform)
1.1.1.3   root     1121:           size += 2;
1.1       root     1122: #ifdef DLINFO_ARCH_ITEMS
1.1.1.3   root     1123:        size += DLINFO_ARCH_ITEMS * 2;
1.1       root     1124: #endif
1.1.1.3   root     1125:         size += envc + argc + 2;
                   1126:        size += (!ibcs ? 3 : 1);        /* argc itself */
                   1127:         size *= n;
                   1128:         if (size & 15)
                   1129:             sp -= 16 - (size & 15);
1.1.1.6   root     1130: 
                   1131:         /* This is correct because Linux defines
                   1132:          * elf_addr_t as Elf32_Off / Elf64_Off
                   1133:          */
                   1134: #define NEW_AUX_ENT(id, val) do {              \
                   1135:             sp -= n; put_user_ual(val, sp);    \
                   1136:             sp -= n; put_user_ual(id, sp);     \
1.1.1.3   root     1137:           } while(0)
1.1.1.6   root     1138: 
1.1       root     1139:         NEW_AUX_ENT (AT_NULL, 0);
                   1140: 
                   1141:         /* There must be exactly DLINFO_ITEMS entries here.  */
1.1.1.6   root     1142:         NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
                   1143:         NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
                   1144:         NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
                   1145:         NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
                   1146:         NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
                   1147:         NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
1.1       root     1148:         NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
1.1.1.6   root     1149:         NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
                   1150:         NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
                   1151:         NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
                   1152:         NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
                   1153:         NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
1.1.1.7   root     1154:         NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
1.1.1.2   root     1155:         if (k_platform)
1.1.1.3   root     1156:             NEW_AUX_ENT(AT_PLATFORM, u_platform);
1.1       root     1157: #ifdef ARCH_DLINFO
1.1.1.6   root     1158:        /*
1.1       root     1159:         * ARCH_DLINFO must come last so platform specific code can enforce
                   1160:         * special alignment requirements on the AUXV if necessary (eg. PPC).
                   1161:         */
                   1162:         ARCH_DLINFO;
                   1163: #endif
                   1164: #undef NEW_AUX_ENT
                   1165: 
1.1.1.8   root     1166:         info->saved_auxv = sp;
                   1167: 
1.1.1.4   root     1168:         sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
1.1       root     1169:         return sp;
                   1170: }
                   1171: 
                   1172: 
1.1.1.6   root     1173: static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
                   1174:                                  int interpreter_fd,
                   1175:                                  abi_ulong *interp_load_addr)
1.1       root     1176: {
                   1177:        struct elf_phdr *elf_phdata  =  NULL;
                   1178:        struct elf_phdr *eppnt;
1.1.1.6   root     1179:        abi_ulong load_addr = 0;
1.1       root     1180:        int load_addr_set = 0;
                   1181:        int retval;
1.1.1.6   root     1182:        abi_ulong last_bss, elf_bss;
                   1183:        abi_ulong error;
1.1       root     1184:        int i;
1.1.1.6   root     1185: 
1.1       root     1186:        elf_bss = 0;
                   1187:        last_bss = 0;
                   1188:        error = 0;
                   1189: 
                   1190: #ifdef BSWAP_NEEDED
                   1191:         bswap_ehdr(interp_elf_ex);
                   1192: #endif
                   1193:        /* First of all, some simple consistency checks */
1.1.1.6   root     1194:        if ((interp_elf_ex->e_type != ET_EXEC &&
                   1195:              interp_elf_ex->e_type != ET_DYN) ||
1.1       root     1196:           !elf_check_arch(interp_elf_ex->e_machine)) {
1.1.1.6   root     1197:                return ~((abi_ulong)0UL);
1.1       root     1198:        }
1.1.1.6   root     1199: 
1.1       root     1200: 
                   1201:        /* Now read in all of the header information */
1.1.1.6   root     1202: 
1.1       root     1203:        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
1.1.1.6   root     1204:            return ~(abi_ulong)0UL;
                   1205: 
                   1206:        elf_phdata =  (struct elf_phdr *)
1.1       root     1207:                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
                   1208: 
                   1209:        if (!elf_phdata)
1.1.1.6   root     1210:          return ~((abi_ulong)0UL);
                   1211: 
1.1       root     1212:        /*
                   1213:         * If the size of this structure has changed, then punt, since
                   1214:         * we will be doing the wrong thing.
                   1215:         */
                   1216:        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
                   1217:            free(elf_phdata);
1.1.1.6   root     1218:            return ~((abi_ulong)0UL);
1.1       root     1219:         }
                   1220: 
                   1221:        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
                   1222:        if(retval >= 0) {
                   1223:            retval = read(interpreter_fd,
                   1224:                           (char *) elf_phdata,
                   1225:                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
                   1226:        }
                   1227:        if (retval < 0) {
                   1228:                perror("load_elf_interp");
                   1229:                exit(-1);
                   1230:                free (elf_phdata);
                   1231:                return retval;
                   1232:        }
                   1233: #ifdef BSWAP_NEEDED
                   1234:        eppnt = elf_phdata;
                   1235:        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
                   1236:             bswap_phdr(eppnt);
                   1237:         }
                   1238: #endif
                   1239: 
                   1240:         if (interp_elf_ex->e_type == ET_DYN) {
1.1.1.6   root     1241:             /* in order to avoid hardcoding the interpreter load
1.1       root     1242:                address in qemu, we allocate a big enough memory zone */
                   1243:             error = target_mmap(0, INTERP_MAP_SIZE,
1.1.1.6   root     1244:                                 PROT_NONE, MAP_PRIVATE | MAP_ANON,
1.1       root     1245:                                 -1, 0);
                   1246:             if (error == -1) {
                   1247:                 perror("mmap");
                   1248:                 exit(-1);
                   1249:             }
                   1250:             load_addr = error;
                   1251:             load_addr_set = 1;
                   1252:         }
                   1253: 
                   1254:        eppnt = elf_phdata;
                   1255:        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
                   1256:          if (eppnt->p_type == PT_LOAD) {
                   1257:            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
                   1258:            int elf_prot = 0;
1.1.1.6   root     1259:            abi_ulong vaddr = 0;
                   1260:            abi_ulong k;
1.1       root     1261: 
                   1262:            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
                   1263:            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
                   1264:            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
                   1265:            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
                   1266:                elf_type |= MAP_FIXED;
                   1267:                vaddr = eppnt->p_vaddr;
                   1268:            }
                   1269:            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
                   1270:                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
                   1271:                 elf_prot,
                   1272:                 elf_type,
                   1273:                 interpreter_fd,
                   1274:                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
1.1.1.6   root     1275: 
1.1.1.3   root     1276:            if (error == -1) {
1.1       root     1277:              /* Real error */
                   1278:              close(interpreter_fd);
                   1279:              free(elf_phdata);
1.1.1.6   root     1280:              return ~((abi_ulong)0UL);
1.1       root     1281:            }
                   1282: 
                   1283:            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
                   1284:              load_addr = error;
                   1285:              load_addr_set = 1;
                   1286:            }
                   1287: 
                   1288:            /*
                   1289:             * Find the end of the file  mapping for this phdr, and keep
                   1290:             * track of the largest address we see for this.
                   1291:             */
                   1292:            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
                   1293:            if (k > elf_bss) elf_bss = k;
                   1294: 
                   1295:            /*
                   1296:             * Do the same thing for the memory mapping - between
                   1297:             * elf_bss and last_bss is the bss section.
                   1298:             */
                   1299:            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
                   1300:            if (k > last_bss) last_bss = k;
                   1301:          }
1.1.1.6   root     1302: 
1.1       root     1303:        /* Now use mmap to map the library into memory. */
                   1304: 
                   1305:        close(interpreter_fd);
                   1306: 
                   1307:        /*
                   1308:         * Now fill out the bss section.  First pad the last page up
                   1309:         * to the page boundary, and then perform a mmap to make sure
                   1310:         * that there are zeromapped pages up to and including the last
                   1311:         * bss page.
                   1312:         */
1.1.1.5   root     1313:        padzero(elf_bss, last_bss);
1.1       root     1314:        elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
                   1315: 
                   1316:        /* Map the last of the bss segment */
                   1317:        if (last_bss > elf_bss) {
                   1318:             target_mmap(elf_bss, last_bss-elf_bss,
                   1319:                         PROT_READ|PROT_WRITE|PROT_EXEC,
                   1320:                         MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
                   1321:        }
                   1322:        free(elf_phdata);
                   1323: 
                   1324:        *interp_load_addr = load_addr;
1.1.1.6   root     1325:        return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
1.1       root     1326: }
                   1327: 
1.1.1.7   root     1328: static int symfind(const void *s0, const void *s1)
                   1329: {
                   1330:     struct elf_sym *key = (struct elf_sym *)s0;
                   1331:     struct elf_sym *sym = (struct elf_sym *)s1;
                   1332:     int result = 0;
                   1333:     if (key->st_value < sym->st_value) {
                   1334:         result = -1;
1.1.1.8   root     1335:     } else if (key->st_value >= sym->st_value + sym->st_size) {
1.1.1.7   root     1336:         result = 1;
                   1337:     }
                   1338:     return result;
                   1339: }
                   1340: 
                   1341: static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
                   1342: {
                   1343: #if ELF_CLASS == ELFCLASS32
                   1344:     struct elf_sym *syms = s->disas_symtab.elf32;
                   1345: #else
                   1346:     struct elf_sym *syms = s->disas_symtab.elf64;
                   1347: #endif
                   1348: 
                   1349:     // binary search
                   1350:     struct elf_sym key;
                   1351:     struct elf_sym *sym;
                   1352: 
                   1353:     key.st_value = orig_addr;
                   1354: 
                   1355:     sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), symfind);
1.1.1.8   root     1356:     if (sym != NULL) {
1.1.1.7   root     1357:         return s->disas_strtab + sym->st_name;
                   1358:     }
                   1359: 
                   1360:     return "";
                   1361: }
                   1362: 
                   1363: /* FIXME: This should use elf_ops.h  */
                   1364: static int symcmp(const void *s0, const void *s1)
                   1365: {
                   1366:     struct elf_sym *sym0 = (struct elf_sym *)s0;
                   1367:     struct elf_sym *sym1 = (struct elf_sym *)s1;
                   1368:     return (sym0->st_value < sym1->st_value)
                   1369:         ? -1
                   1370:         : ((sym0->st_value > sym1->st_value) ? 1 : 0);
                   1371: }
                   1372: 
1.1       root     1373: /* Best attempt to load symbols from this ELF object. */
                   1374: static void load_symbols(struct elfhdr *hdr, int fd)
                   1375: {
1.1.1.7   root     1376:     unsigned int i, nsyms;
1.1       root     1377:     struct elf_shdr sechdr, symtab, strtab;
                   1378:     char *strings;
                   1379:     struct syminfo *s;
1.1.1.7   root     1380:     struct elf_sym *syms;
1.1       root     1381: 
                   1382:     lseek(fd, hdr->e_shoff, SEEK_SET);
                   1383:     for (i = 0; i < hdr->e_shnum; i++) {
1.1.1.7   root     1384:         if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
                   1385:             return;
1.1       root     1386: #ifdef BSWAP_NEEDED
1.1.1.7   root     1387:         bswap_shdr(&sechdr);
1.1       root     1388: #endif
1.1.1.7   root     1389:         if (sechdr.sh_type == SHT_SYMTAB) {
                   1390:             symtab = sechdr;
                   1391:             lseek(fd, hdr->e_shoff
                   1392:                   + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
                   1393:             if (read(fd, &strtab, sizeof(strtab))
                   1394:                 != sizeof(strtab))
                   1395:                 return;
1.1       root     1396: #ifdef BSWAP_NEEDED
1.1.1.7   root     1397:             bswap_shdr(&strtab);
1.1       root     1398: #endif
1.1.1.7   root     1399:             goto found;
                   1400:         }
1.1       root     1401:     }
                   1402:     return; /* Shouldn't happen... */
                   1403: 
                   1404:  found:
                   1405:     /* Now know where the strtab and symtab are.  Snarf them. */
                   1406:     s = malloc(sizeof(*s));
1.1.1.7   root     1407:     syms = malloc(symtab.sh_size);
                   1408:     if (!syms)
                   1409:         return;
1.1       root     1410:     s->disas_strtab = strings = malloc(strtab.sh_size);
1.1.1.7   root     1411:     if (!s->disas_strtab)
                   1412:         return;
1.1.1.6   root     1413: 
1.1       root     1414:     lseek(fd, symtab.sh_offset, SEEK_SET);
1.1.1.7   root     1415:     if (read(fd, syms, symtab.sh_size) != symtab.sh_size)
                   1416:         return;
                   1417: 
                   1418:     nsyms = symtab.sh_size / sizeof(struct elf_sym);
1.1       root     1419: 
1.1.1.7   root     1420:     i = 0;
                   1421:     while (i < nsyms) {
1.1       root     1422: #ifdef BSWAP_NEEDED
1.1.1.7   root     1423:         bswap_sym(syms + i);
1.1       root     1424: #endif
1.1.1.7   root     1425:         // Throw away entries which we do not need.
                   1426:         if (syms[i].st_shndx == SHN_UNDEF ||
                   1427:                 syms[i].st_shndx >= SHN_LORESERVE ||
                   1428:                 ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
                   1429:             nsyms--;
                   1430:             if (i < nsyms) {
                   1431:                 syms[i] = syms[nsyms];
                   1432:             }
                   1433:             continue;
                   1434:         }
                   1435: #if defined(TARGET_ARM) || defined (TARGET_MIPS)
                   1436:         /* The bottom address bit marks a Thumb or MIPS16 symbol.  */
                   1437:         syms[i].st_value &= ~(target_ulong)1;
1.1.1.6   root     1438: #endif
1.1.1.7   root     1439:         i++;
1.1.1.6   root     1440:     }
1.1.1.7   root     1441:     syms = realloc(syms, nsyms * sizeof(*syms));
                   1442: 
                   1443:     qsort(syms, nsyms, sizeof(*syms), symcmp);
1.1       root     1444: 
                   1445:     lseek(fd, strtab.sh_offset, SEEK_SET);
                   1446:     if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
1.1.1.7   root     1447:         return;
                   1448:     s->disas_num_syms = nsyms;
                   1449: #if ELF_CLASS == ELFCLASS32
                   1450:     s->disas_symtab.elf32 = syms;
1.1.1.11! root     1451:     s->lookup_symbol = lookup_symbolxx;
1.1.1.7   root     1452: #else
                   1453:     s->disas_symtab.elf64 = syms;
1.1.1.11! root     1454:     s->lookup_symbol = lookup_symbolxx;
1.1.1.7   root     1455: #endif
1.1       root     1456:     s->next = syminfos;
                   1457:     syminfos = s;
                   1458: }
                   1459: 
1.1.1.4   root     1460: int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
                   1461:                     struct image_info * info)
1.1       root     1462: {
                   1463:     struct elfhdr elf_ex;
                   1464:     struct elfhdr interp_elf_ex;
                   1465:     struct exec interp_ex;
                   1466:     int interpreter_fd = -1; /* avoid warning */
1.1.1.6   root     1467:     abi_ulong load_addr, load_bias;
1.1       root     1468:     int load_addr_set = 0;
                   1469:     unsigned int interpreter_type = INTERPRETER_NONE;
                   1470:     unsigned char ibcs2_interpreter;
                   1471:     int i;
1.1.1.6   root     1472:     abi_ulong mapped_addr;
1.1       root     1473:     struct elf_phdr * elf_ppnt;
                   1474:     struct elf_phdr *elf_phdata;
1.1.1.6   root     1475:     abi_ulong elf_bss, k, elf_brk;
1.1       root     1476:     int retval;
                   1477:     char * elf_interpreter;
1.1.1.6   root     1478:     abi_ulong elf_entry, interp_load_addr = 0;
1.1       root     1479:     int status;
1.1.1.6   root     1480:     abi_ulong start_code, end_code, start_data, end_data;
                   1481:     abi_ulong reloc_func_desc = 0;
                   1482:     abi_ulong elf_stack;
1.1       root     1483:     char passed_fileno[6];
                   1484: 
                   1485:     ibcs2_interpreter = 0;
                   1486:     status = 0;
                   1487:     load_addr = 0;
                   1488:     load_bias = 0;
                   1489:     elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
                   1490: #ifdef BSWAP_NEEDED
                   1491:     bswap_ehdr(&elf_ex);
                   1492: #endif
                   1493: 
                   1494:     /* First of all, some simple consistency checks */
                   1495:     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
                   1496:                                        (! elf_check_arch(elf_ex.e_machine))) {
                   1497:            return -ENOEXEC;
                   1498:     }
                   1499: 
1.1.1.4   root     1500:     bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
                   1501:     bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
                   1502:     bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
                   1503:     if (!bprm->p) {
                   1504:         retval = -E2BIG;
                   1505:     }
                   1506: 
1.1       root     1507:     /* Now read in all of the header information */
                   1508:     elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
                   1509:     if (elf_phdata == NULL) {
                   1510:        return -ENOMEM;
                   1511:     }
                   1512: 
                   1513:     retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
                   1514:     if(retval > 0) {
1.1.1.6   root     1515:        retval = read(bprm->fd, (char *) elf_phdata,
1.1       root     1516:                                elf_ex.e_phentsize * elf_ex.e_phnum);
                   1517:     }
                   1518: 
                   1519:     if (retval < 0) {
                   1520:        perror("load_elf_binary");
                   1521:        exit(-1);
                   1522:        free (elf_phdata);
                   1523:        return -errno;
                   1524:     }
                   1525: 
                   1526: #ifdef BSWAP_NEEDED
                   1527:     elf_ppnt = elf_phdata;
                   1528:     for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
                   1529:         bswap_phdr(elf_ppnt);
                   1530:     }
                   1531: #endif
                   1532:     elf_ppnt = elf_phdata;
                   1533: 
                   1534:     elf_bss = 0;
                   1535:     elf_brk = 0;
                   1536: 
                   1537: 
1.1.1.6   root     1538:     elf_stack = ~((abi_ulong)0UL);
1.1       root     1539:     elf_interpreter = NULL;
1.1.1.6   root     1540:     start_code = ~((abi_ulong)0UL);
1.1       root     1541:     end_code = 0;
1.1.1.6   root     1542:     start_data = 0;
1.1       root     1543:     end_data = 0;
1.1.1.7   root     1544:     interp_ex.a_info = 0;
1.1       root     1545: 
                   1546:     for(i=0;i < elf_ex.e_phnum; i++) {
                   1547:        if (elf_ppnt->p_type == PT_INTERP) {
                   1548:            if ( elf_interpreter != NULL )
                   1549:            {
                   1550:                free (elf_phdata);
                   1551:                free(elf_interpreter);
                   1552:                close(bprm->fd);
                   1553:                return -EINVAL;
                   1554:            }
                   1555: 
                   1556:            /* This is the program interpreter used for
                   1557:             * shared libraries - for now assume that this
                   1558:             * is an a.out format binary
                   1559:             */
                   1560: 
                   1561:            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
                   1562: 
                   1563:            if (elf_interpreter == NULL) {
                   1564:                free (elf_phdata);
                   1565:                close(bprm->fd);
                   1566:                return -ENOMEM;
                   1567:            }
                   1568: 
                   1569:            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
                   1570:            if(retval >= 0) {
                   1571:                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
                   1572:            }
                   1573:            if(retval < 0) {
                   1574:                perror("load_elf_binary2");
                   1575:                exit(-1);
1.1.1.6   root     1576:            }
1.1       root     1577: 
                   1578:            /* If the program interpreter is one of these two,
                   1579:               then assume an iBCS2 image. Otherwise assume
                   1580:               a native linux image. */
                   1581: 
                   1582:            /* JRP - Need to add X86 lib dir stuff here... */
                   1583: 
                   1584:            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
                   1585:                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
                   1586:              ibcs2_interpreter = 1;
                   1587:            }
                   1588: 
                   1589: #if 0
1.1.1.10  root     1590:            printf("Using ELF interpreter %s\n", path(elf_interpreter));
1.1       root     1591: #endif
                   1592:            if (retval >= 0) {
                   1593:                retval = open(path(elf_interpreter), O_RDONLY);
                   1594:                if(retval >= 0) {
                   1595:                    interpreter_fd = retval;
                   1596:                }
                   1597:                else {
                   1598:                    perror(elf_interpreter);
                   1599:                    exit(-1);
                   1600:                    /* retval = -errno; */
                   1601:                }
                   1602:            }
                   1603: 
                   1604:            if (retval >= 0) {
                   1605:                retval = lseek(interpreter_fd, 0, SEEK_SET);
                   1606:                if(retval >= 0) {
                   1607:                    retval = read(interpreter_fd,bprm->buf,128);
                   1608:                }
                   1609:            }
                   1610:            if (retval >= 0) {
                   1611:                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
1.1.1.10  root     1612:                interp_elf_ex = *((struct elfhdr *) bprm->buf); /* elf exec-header */
1.1       root     1613:            }
                   1614:            if (retval < 0) {
                   1615:                perror("load_elf_binary3");
                   1616:                exit(-1);
                   1617:                free (elf_phdata);
                   1618:                free(elf_interpreter);
                   1619:                close(bprm->fd);
                   1620:                return retval;
                   1621:            }
                   1622:        }
                   1623:        elf_ppnt++;
                   1624:     }
                   1625: 
                   1626:     /* Some simple consistency checks for the interpreter */
                   1627:     if (elf_interpreter){
                   1628:        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
                   1629: 
                   1630:        /* Now figure out which format our binary is */
                   1631:        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
                   1632:                (N_MAGIC(interp_ex) != QMAGIC)) {
                   1633:          interpreter_type = INTERPRETER_ELF;
                   1634:        }
                   1635: 
                   1636:        if (interp_elf_ex.e_ident[0] != 0x7f ||
1.1.1.7   root     1637:             strncmp((char *)&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1.1       root     1638:            interpreter_type &= ~INTERPRETER_ELF;
                   1639:        }
                   1640: 
                   1641:        if (!interpreter_type) {
                   1642:            free(elf_interpreter);
                   1643:            free(elf_phdata);
                   1644:            close(bprm->fd);
                   1645:            return -ELIBBAD;
                   1646:        }
                   1647:     }
                   1648: 
                   1649:     /* OK, we are done with that, now set up the arg stuff,
                   1650:        and then start this sucker up */
                   1651: 
1.1.1.4   root     1652:     {
1.1       root     1653:        char * passed_p;
                   1654: 
                   1655:        if (interpreter_type == INTERPRETER_AOUT) {
                   1656:            snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
                   1657:            passed_p = passed_fileno;
                   1658: 
                   1659:            if (elf_interpreter) {
1.1.1.4   root     1660:                bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);
1.1       root     1661:                bprm->argc++;
                   1662:            }
                   1663:        }
                   1664:        if (!bprm->p) {
                   1665:            if (elf_interpreter) {
                   1666:                free(elf_interpreter);
                   1667:            }
                   1668:            free (elf_phdata);
                   1669:            close(bprm->fd);
                   1670:            return -E2BIG;
                   1671:        }
                   1672:     }
                   1673: 
                   1674:     /* OK, This is the point of no return */
                   1675:     info->end_data = 0;
                   1676:     info->end_code = 0;
1.1.1.6   root     1677:     info->start_mmap = (abi_ulong)ELF_START_MMAP;
1.1       root     1678:     info->mmap = 0;
1.1.1.6   root     1679:     elf_entry = (abi_ulong) elf_ex.e_entry;
1.1       root     1680: 
1.1.1.10  root     1681: #if defined(CONFIG_USE_GUEST_BASE)
                   1682:     /*
                   1683:      * In case where user has not explicitly set the guest_base, we
                   1684:      * probe here that should we set it automatically.
                   1685:      */
1.1.1.11! root     1686:     if (!(have_guest_base || reserved_va)) {
1.1.1.10  root     1687:         /*
1.1.1.11! root     1688:          * Go through ELF program header table and find the address
        !          1689:          * range used by loadable segments.  Check that this is available on
        !          1690:          * the host, and if not find a suitable value for guest_base.  */
        !          1691:         abi_ulong app_start = ~0;
        !          1692:         abi_ulong app_end = 0;
        !          1693:         abi_ulong addr;
        !          1694:         unsigned long host_start;
        !          1695:         unsigned long real_start;
        !          1696:         unsigned long host_size;
1.1.1.10  root     1697:         for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum;
                   1698:             i++, elf_ppnt++) {
                   1699:             if (elf_ppnt->p_type != PT_LOAD)
                   1700:                 continue;
1.1.1.11! root     1701:             addr = elf_ppnt->p_vaddr;
        !          1702:             if (addr < app_start) {
        !          1703:                 app_start = addr;
        !          1704:             }
        !          1705:             addr += elf_ppnt->p_memsz;
        !          1706:             if (addr > app_end) {
        !          1707:                 app_end = addr;
        !          1708:             }
        !          1709:         }
        !          1710: 
        !          1711:         /* If we don't have any loadable segments then something
        !          1712:            is very wrong.  */
        !          1713:         assert(app_start < app_end);
        !          1714: 
        !          1715:         /* Round addresses to page boundaries.  */
        !          1716:         app_start = app_start & qemu_host_page_mask;
        !          1717:         app_end = HOST_PAGE_ALIGN(app_end);
        !          1718:         if (app_start < mmap_min_addr) {
        !          1719:             host_start = HOST_PAGE_ALIGN(mmap_min_addr);
        !          1720:         } else {
        !          1721:             host_start = app_start;
        !          1722:             if (host_start != app_start) {
        !          1723:                 fprintf(stderr, "qemu: Address overflow loading ELF binary\n");
        !          1724:                 abort();
        !          1725:             }
        !          1726:         }
        !          1727:         host_size = app_end - app_start;
        !          1728:         while (1) {
        !          1729:             /* Do not use mmap_find_vma here because that is limited to the
        !          1730:                guest address space.  We are going to make the
        !          1731:                guest address space fit whatever we're given.  */
        !          1732:             real_start = (unsigned long)mmap((void *)host_start, host_size,
        !          1733:                 PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
        !          1734:             if (real_start == (unsigned long)-1) {
        !          1735:                 fprintf(stderr, "qemu: Virtual memory exausted\n");
        !          1736:                 abort();
        !          1737:             }
        !          1738:             if (real_start == host_start) {
1.1.1.10  root     1739:                 break;
                   1740:             }
1.1.1.11! root     1741:             /* That address didn't work.  Unmap and try a different one.
        !          1742:                The address the host picked because is typically
        !          1743:                right at the top of the host address space and leaves the
        !          1744:                guest with no usable address space.  Resort to a linear search.
        !          1745:                We already compensated for mmap_min_addr, so this should not
        !          1746:                happen often.  Probably means we got unlucky and host address
        !          1747:                space randomization put a shared library somewhere
        !          1748:                inconvenient.  */
        !          1749:             munmap((void *)real_start, host_size);
        !          1750:             host_start += qemu_host_page_size;
        !          1751:             if (host_start == app_start) {
        !          1752:                 /* Theoretically possible if host doesn't have any
        !          1753:                    suitably aligned areas.  Normally the first mmap will
        !          1754:                    fail.  */
        !          1755:                 fprintf(stderr, "qemu: Unable to find space for application\n");
        !          1756:                 abort();
        !          1757:             }
1.1.1.10  root     1758:         }
1.1.1.11! root     1759:         qemu_log("Relocating guest address space from 0x" TARGET_ABI_FMT_lx
        !          1760:                  " to 0x%lx\n", app_start, real_start);
        !          1761:         guest_base = real_start - app_start;
1.1.1.10  root     1762:     }
                   1763: #endif /* CONFIG_USE_GUEST_BASE */
                   1764: 
1.1       root     1765:     /* Do this so that we can load the interpreter, if need be.  We will
                   1766:        change some of these later */
                   1767:     info->rss = 0;
                   1768:     bprm->p = setup_arg_pages(bprm->p, bprm, info);
                   1769:     info->start_stack = bprm->p;
                   1770: 
                   1771:     /* Now we do a little grungy work by mmaping the ELF image into
                   1772:      * the correct location in memory.  At this point, we assume that
                   1773:      * the image should be loaded at fixed address, not at a variable
                   1774:      * address.
                   1775:      */
                   1776: 
                   1777:     for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
                   1778:         int elf_prot = 0;
                   1779:         int elf_flags = 0;
1.1.1.6   root     1780:         abi_ulong error;
                   1781: 
1.1       root     1782:        if (elf_ppnt->p_type != PT_LOAD)
                   1783:             continue;
1.1.1.6   root     1784: 
1.1       root     1785:         if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
                   1786:         if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
                   1787:         if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
                   1788:         elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
                   1789:         if (elf_ex.e_type == ET_EXEC || load_addr_set) {
                   1790:             elf_flags |= MAP_FIXED;
                   1791:         } else if (elf_ex.e_type == ET_DYN) {
                   1792:             /* Try and get dynamic programs out of the way of the default mmap
                   1793:                base, as well as whatever program they might try to exec.  This
                   1794:                is because the brk will follow the loader, and is not movable.  */
                   1795:             /* NOTE: for qemu, we do a big mmap to get enough space
1.1.1.6   root     1796:                without hardcoding any address */
1.1       root     1797:             error = target_mmap(0, ET_DYN_MAP_SIZE,
1.1.1.6   root     1798:                                 PROT_NONE, MAP_PRIVATE | MAP_ANON,
1.1       root     1799:                                 -1, 0);
                   1800:             if (error == -1) {
                   1801:                 perror("mmap");
                   1802:                 exit(-1);
                   1803:             }
                   1804:             load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
                   1805:         }
1.1.1.6   root     1806: 
1.1       root     1807:         error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
                   1808:                             (elf_ppnt->p_filesz +
                   1809:                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
                   1810:                             elf_prot,
                   1811:                             (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
                   1812:                             bprm->fd,
1.1.1.6   root     1813:                             (elf_ppnt->p_offset -
1.1       root     1814:                              TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
                   1815:         if (error == -1) {
                   1816:             perror("mmap");
                   1817:             exit(-1);
                   1818:         }
                   1819: 
                   1820: #ifdef LOW_ELF_STACK
                   1821:         if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
                   1822:             elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
                   1823: #endif
1.1.1.6   root     1824: 
1.1       root     1825:         if (!load_addr_set) {
                   1826:             load_addr_set = 1;
                   1827:             load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
                   1828:             if (elf_ex.e_type == ET_DYN) {
                   1829:                 load_bias += error -
                   1830:                     TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
                   1831:                 load_addr += load_bias;
1.1.1.6   root     1832:                 reloc_func_desc = load_bias;
1.1       root     1833:             }
                   1834:         }
                   1835:         k = elf_ppnt->p_vaddr;
1.1.1.6   root     1836:         if (k < start_code)
1.1       root     1837:             start_code = k;
1.1.1.6   root     1838:         if (start_data < k)
                   1839:             start_data = k;
1.1       root     1840:         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1.1.1.6   root     1841:         if (k > elf_bss)
1.1       root     1842:             elf_bss = k;
                   1843:         if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
                   1844:             end_code = k;
1.1.1.6   root     1845:         if (end_data < k)
1.1       root     1846:             end_data = k;
                   1847:         k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
                   1848:         if (k > elf_brk) elf_brk = k;
                   1849:     }
                   1850: 
                   1851:     elf_entry += load_bias;
                   1852:     elf_bss += load_bias;
                   1853:     elf_brk += load_bias;
                   1854:     start_code += load_bias;
                   1855:     end_code += load_bias;
1.1.1.6   root     1856:     start_data += load_bias;
1.1       root     1857:     end_data += load_bias;
                   1858: 
                   1859:     if (elf_interpreter) {
                   1860:        if (interpreter_type & 1) {
                   1861:            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
                   1862:        }
                   1863:        else if (interpreter_type & 2) {
                   1864:            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
                   1865:                                            &interp_load_addr);
                   1866:        }
1.1.1.6   root     1867:         reloc_func_desc = interp_load_addr;
1.1       root     1868: 
                   1869:        close(interpreter_fd);
                   1870:        free(elf_interpreter);
                   1871: 
1.1.1.6   root     1872:        if (elf_entry == ~((abi_ulong)0UL)) {
1.1       root     1873:            printf("Unable to load interpreter\n");
                   1874:            free(elf_phdata);
                   1875:            exit(-1);
                   1876:            return 0;
                   1877:        }
                   1878:     }
                   1879: 
                   1880:     free(elf_phdata);
                   1881: 
1.1.1.7   root     1882:     if (qemu_log_enabled())
1.1       root     1883:        load_symbols(&elf_ex, bprm->fd);
                   1884: 
                   1885:     if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
                   1886:     info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
                   1887: 
                   1888: #ifdef LOW_ELF_STACK
                   1889:     info->start_stack = bprm->p = elf_stack - 4;
                   1890: #endif
1.1.1.3   root     1891:     bprm->p = create_elf_tables(bprm->p,
1.1       root     1892:                    bprm->argc,
                   1893:                    bprm->envc,
                   1894:                     &elf_ex,
                   1895:                     load_addr, load_bias,
                   1896:                    interp_load_addr,
                   1897:                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
                   1898:                    info);
1.1.1.6   root     1899:     info->load_addr = reloc_func_desc;
1.1       root     1900:     info->start_brk = info->brk = elf_brk;
                   1901:     info->end_code = end_code;
                   1902:     info->start_code = start_code;
1.1.1.6   root     1903:     info->start_data = start_data;
1.1       root     1904:     info->end_data = end_data;
                   1905:     info->start_stack = bprm->p;
                   1906: 
                   1907:     /* Calling set_brk effectively mmaps the pages that we need for the bss and break
                   1908:        sections */
                   1909:     set_brk(elf_bss, elf_brk);
                   1910: 
1.1.1.5   root     1911:     padzero(elf_bss, elf_brk);
1.1       root     1912: 
                   1913: #if 0
                   1914:     printf("(start_brk) %x\n" , info->start_brk);
                   1915:     printf("(end_code) %x\n" , info->end_code);
                   1916:     printf("(start_code) %x\n" , info->start_code);
                   1917:     printf("(end_data) %x\n" , info->end_data);
                   1918:     printf("(start_stack) %x\n" , info->start_stack);
                   1919:     printf("(brk) %x\n" , info->brk);
                   1920: #endif
                   1921: 
                   1922:     if ( info->personality == PER_SVR4 )
                   1923:     {
                   1924:            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
                   1925:               and some applications "depend" upon this behavior.
                   1926:               Since we do not have the power to recompile these, we
                   1927:               emulate the SVr4 behavior.  Sigh.  */
                   1928:            mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
                   1929:                                       MAP_FIXED | MAP_PRIVATE, -1, 0);
                   1930:     }
                   1931: 
                   1932:     info->entry = elf_entry;
                   1933: 
1.1.1.8   root     1934: #ifdef USE_ELF_CORE_DUMP
                   1935:     bprm->core_dump = &elf_core_dump;
                   1936: #endif
                   1937: 
1.1       root     1938:     return 0;
                   1939: }
                   1940: 
1.1.1.8   root     1941: #ifdef USE_ELF_CORE_DUMP
                   1942: 
                   1943: /*
                   1944:  * Definitions to generate Intel SVR4-like core files.
1.1.1.9   root     1945:  * These mostly have the same names as the SVR4 types with "target_elf_"
1.1.1.8   root     1946:  * tacked on the front to prevent clashes with linux definitions,
                   1947:  * and the typedef forms have been avoided.  This is mostly like
                   1948:  * the SVR4 structure, but more Linuxy, with things that Linux does
                   1949:  * not support and which gdb doesn't really use excluded.
                   1950:  *
                   1951:  * Fields we don't dump (their contents is zero) in linux-user qemu
                   1952:  * are marked with XXX.
                   1953:  *
                   1954:  * Core dump code is copied from linux kernel (fs/binfmt_elf.c).
                   1955:  *
                   1956:  * Porting ELF coredump for target is (quite) simple process.  First you
1.1.1.11! root     1957:  * define USE_ELF_CORE_DUMP in target ELF code (where init_thread() for
1.1.1.8   root     1958:  * the target resides):
                   1959:  *
                   1960:  * #define USE_ELF_CORE_DUMP
                   1961:  *
                   1962:  * Next you define type of register set used for dumping.  ELF specification
                   1963:  * says that it needs to be array of elf_greg_t that has size of ELF_NREG.
                   1964:  *
1.1.1.9   root     1965:  * typedef <target_regtype> target_elf_greg_t;
1.1.1.8   root     1966:  * #define ELF_NREG <number of registers>
1.1.1.9   root     1967:  * typedef taret_elf_greg_t target_elf_gregset_t[ELF_NREG];
1.1.1.8   root     1968:  *
                   1969:  * Last step is to implement target specific function that copies registers
                   1970:  * from given cpu into just specified register set.  Prototype is:
                   1971:  *
1.1.1.9   root     1972:  * static void elf_core_copy_regs(taret_elf_gregset_t *regs,
                   1973:  *                                const CPUState *env);
1.1.1.8   root     1974:  *
                   1975:  * Parameters:
                   1976:  *     regs - copy register values into here (allocated and zeroed by caller)
                   1977:  *     env - copy registers from here
                   1978:  *
                   1979:  * Example for ARM target is provided in this file.
                   1980:  */
                   1981: 
                   1982: /* An ELF note in memory */
                   1983: struct memelfnote {
                   1984:     const char *name;
                   1985:     size_t     namesz;
                   1986:     size_t     namesz_rounded;
                   1987:     int        type;
                   1988:     size_t     datasz;
                   1989:     void       *data;
                   1990:     size_t     notesz;
                   1991: };
                   1992: 
1.1.1.9   root     1993: struct target_elf_siginfo {
1.1.1.8   root     1994:     int  si_signo; /* signal number */
                   1995:     int  si_code;  /* extra code */
                   1996:     int  si_errno; /* errno */
                   1997: };
                   1998: 
1.1.1.9   root     1999: struct target_elf_prstatus {
                   2000:     struct target_elf_siginfo pr_info;      /* Info associated with signal */
1.1.1.8   root     2001:     short              pr_cursig;    /* Current signal */
                   2002:     target_ulong       pr_sigpend;   /* XXX */
                   2003:     target_ulong       pr_sighold;   /* XXX */
                   2004:     target_pid_t       pr_pid;
                   2005:     target_pid_t       pr_ppid;
                   2006:     target_pid_t       pr_pgrp;
                   2007:     target_pid_t       pr_sid;
                   2008:     struct target_timeval pr_utime;  /* XXX User time */
                   2009:     struct target_timeval pr_stime;  /* XXX System time */
                   2010:     struct target_timeval pr_cutime; /* XXX Cumulative user time */
                   2011:     struct target_timeval pr_cstime; /* XXX Cumulative system time */
1.1.1.9   root     2012:     target_elf_gregset_t      pr_reg;       /* GP registers */
1.1.1.8   root     2013:     int                pr_fpvalid;   /* XXX */
                   2014: };
                   2015: 
                   2016: #define ELF_PRARGSZ     (80) /* Number of chars for args */
                   2017: 
1.1.1.9   root     2018: struct target_elf_prpsinfo {
1.1.1.8   root     2019:     char         pr_state;       /* numeric process state */
                   2020:     char         pr_sname;       /* char for pr_state */
                   2021:     char         pr_zomb;        /* zombie */
                   2022:     char         pr_nice;        /* nice val */
                   2023:     target_ulong pr_flag;        /* flags */
                   2024:     target_uid_t pr_uid;
                   2025:     target_gid_t pr_gid;
                   2026:     target_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
                   2027:     /* Lots missing */
                   2028:     char    pr_fname[16];           /* filename of executable */
                   2029:     char    pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
                   2030: };
                   2031: 
                   2032: /* Here is the structure in which status of each thread is captured. */
                   2033: struct elf_thread_status {
1.1.1.10  root     2034:     QTAILQ_ENTRY(elf_thread_status)  ets_link;
1.1.1.9   root     2035:     struct target_elf_prstatus prstatus;   /* NT_PRSTATUS */
1.1.1.8   root     2036: #if 0
                   2037:     elf_fpregset_t fpu;             /* NT_PRFPREG */
                   2038:     struct task_struct *thread;
                   2039:     elf_fpxregset_t xfpu;           /* ELF_CORE_XFPREG_TYPE */
                   2040: #endif
                   2041:     struct memelfnote notes[1];
                   2042:     int num_notes;
                   2043: };
                   2044: 
                   2045: struct elf_note_info {
                   2046:     struct memelfnote   *notes;
1.1.1.9   root     2047:     struct target_elf_prstatus *prstatus;  /* NT_PRSTATUS */
                   2048:     struct target_elf_prpsinfo *psinfo;    /* NT_PRPSINFO */
1.1.1.8   root     2049: 
1.1.1.10  root     2050:     QTAILQ_HEAD(thread_list_head, elf_thread_status) thread_list;
1.1.1.8   root     2051: #if 0
                   2052:     /*
                   2053:      * Current version of ELF coredump doesn't support
                   2054:      * dumping fp regs etc.
                   2055:      */
                   2056:     elf_fpregset_t *fpu;
                   2057:     elf_fpxregset_t *xfpu;
                   2058:     int thread_status_size;
                   2059: #endif
                   2060:     int notes_size;
                   2061:     int numnote;
                   2062: };
                   2063: 
                   2064: struct vm_area_struct {
                   2065:     abi_ulong   vma_start;  /* start vaddr of memory region */
                   2066:     abi_ulong   vma_end;    /* end vaddr of memory region */
                   2067:     abi_ulong   vma_flags;  /* protection etc. flags for the region */
1.1.1.10  root     2068:     QTAILQ_ENTRY(vm_area_struct) vma_link;
1.1.1.8   root     2069: };
                   2070: 
                   2071: struct mm_struct {
1.1.1.10  root     2072:     QTAILQ_HEAD(, vm_area_struct) mm_mmap;
1.1.1.8   root     2073:     int mm_count;           /* number of mappings */
                   2074: };
                   2075: 
                   2076: static struct mm_struct *vma_init(void);
                   2077: static void vma_delete(struct mm_struct *);
                   2078: static int vma_add_mapping(struct mm_struct *, abi_ulong,
                   2079:     abi_ulong, abi_ulong);
                   2080: static int vma_get_mapping_count(const struct mm_struct *);
                   2081: static struct vm_area_struct *vma_first(const struct mm_struct *);
                   2082: static struct vm_area_struct *vma_next(struct vm_area_struct *);
                   2083: static abi_ulong vma_dump_size(const struct vm_area_struct *);
1.1.1.11! root     2084: static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
1.1.1.8   root     2085:     unsigned long flags);
                   2086: 
                   2087: static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
                   2088: static void fill_note(struct memelfnote *, const char *, int,
                   2089:     unsigned int, void *);
1.1.1.9   root     2090: static void fill_prstatus(struct target_elf_prstatus *, const TaskState *, int);
                   2091: static int fill_psinfo(struct target_elf_prpsinfo *, const TaskState *);
1.1.1.8   root     2092: static void fill_auxv_note(struct memelfnote *, const TaskState *);
                   2093: static void fill_elf_note_phdr(struct elf_phdr *, int, off_t);
                   2094: static size_t note_size(const struct memelfnote *);
                   2095: static void free_note_info(struct elf_note_info *);
                   2096: static int fill_note_info(struct elf_note_info *, long, const CPUState *);
                   2097: static void fill_thread_info(struct elf_note_info *, const CPUState *);
                   2098: static int core_dump_filename(const TaskState *, char *, size_t);
                   2099: 
                   2100: static int dump_write(int, const void *, size_t);
                   2101: static int write_note(struct memelfnote *, int);
                   2102: static int write_note_info(struct elf_note_info *, int);
                   2103: 
                   2104: #ifdef BSWAP_NEEDED
1.1.1.9   root     2105: static void bswap_prstatus(struct target_elf_prstatus *);
                   2106: static void bswap_psinfo(struct target_elf_prpsinfo *);
1.1.1.8   root     2107: 
1.1.1.9   root     2108: static void bswap_prstatus(struct target_elf_prstatus *prstatus)
1.1.1.8   root     2109: {
                   2110:     prstatus->pr_info.si_signo = tswapl(prstatus->pr_info.si_signo);
                   2111:     prstatus->pr_info.si_code = tswapl(prstatus->pr_info.si_code);
                   2112:     prstatus->pr_info.si_errno = tswapl(prstatus->pr_info.si_errno);
                   2113:     prstatus->pr_cursig = tswap16(prstatus->pr_cursig);
                   2114:     prstatus->pr_sigpend = tswapl(prstatus->pr_sigpend);
                   2115:     prstatus->pr_sighold = tswapl(prstatus->pr_sighold);
                   2116:     prstatus->pr_pid = tswap32(prstatus->pr_pid);
                   2117:     prstatus->pr_ppid = tswap32(prstatus->pr_ppid);
                   2118:     prstatus->pr_pgrp = tswap32(prstatus->pr_pgrp);
                   2119:     prstatus->pr_sid = tswap32(prstatus->pr_sid);
                   2120:     /* cpu times are not filled, so we skip them */
                   2121:     /* regs should be in correct format already */
                   2122:     prstatus->pr_fpvalid = tswap32(prstatus->pr_fpvalid);
                   2123: }
                   2124: 
1.1.1.9   root     2125: static void bswap_psinfo(struct target_elf_prpsinfo *psinfo)
1.1.1.8   root     2126: {
                   2127:     psinfo->pr_flag = tswapl(psinfo->pr_flag);
                   2128:     psinfo->pr_uid = tswap16(psinfo->pr_uid);
                   2129:     psinfo->pr_gid = tswap16(psinfo->pr_gid);
                   2130:     psinfo->pr_pid = tswap32(psinfo->pr_pid);
                   2131:     psinfo->pr_ppid = tswap32(psinfo->pr_ppid);
                   2132:     psinfo->pr_pgrp = tswap32(psinfo->pr_pgrp);
                   2133:     psinfo->pr_sid = tswap32(psinfo->pr_sid);
                   2134: }
                   2135: #endif /* BSWAP_NEEDED */
                   2136: 
                   2137: /*
                   2138:  * Minimal support for linux memory regions.  These are needed
                   2139:  * when we are finding out what memory exactly belongs to
                   2140:  * emulated process.  No locks needed here, as long as
                   2141:  * thread that received the signal is stopped.
                   2142:  */
                   2143: 
                   2144: static struct mm_struct *vma_init(void)
                   2145: {
                   2146:     struct mm_struct *mm;
                   2147: 
                   2148:     if ((mm = qemu_malloc(sizeof (*mm))) == NULL)
                   2149:         return (NULL);
                   2150: 
                   2151:     mm->mm_count = 0;
1.1.1.10  root     2152:     QTAILQ_INIT(&mm->mm_mmap);
1.1.1.8   root     2153: 
                   2154:     return (mm);
                   2155: }
                   2156: 
                   2157: static void vma_delete(struct mm_struct *mm)
                   2158: {
                   2159:     struct vm_area_struct *vma;
                   2160: 
                   2161:     while ((vma = vma_first(mm)) != NULL) {
1.1.1.10  root     2162:         QTAILQ_REMOVE(&mm->mm_mmap, vma, vma_link);
1.1.1.8   root     2163:         qemu_free(vma);
                   2164:     }
                   2165:     qemu_free(mm);
                   2166: }
                   2167: 
                   2168: static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
                   2169:     abi_ulong end, abi_ulong flags)
                   2170: {
                   2171:     struct vm_area_struct *vma;
                   2172: 
                   2173:     if ((vma = qemu_mallocz(sizeof (*vma))) == NULL)
                   2174:         return (-1);
                   2175: 
                   2176:     vma->vma_start = start;
                   2177:     vma->vma_end = end;
                   2178:     vma->vma_flags = flags;
                   2179: 
1.1.1.10  root     2180:     QTAILQ_INSERT_TAIL(&mm->mm_mmap, vma, vma_link);
1.1.1.8   root     2181:     mm->mm_count++;
                   2182: 
                   2183:     return (0);
                   2184: }
                   2185: 
                   2186: static struct vm_area_struct *vma_first(const struct mm_struct *mm)
                   2187: {
1.1.1.10  root     2188:     return (QTAILQ_FIRST(&mm->mm_mmap));
1.1.1.8   root     2189: }
                   2190: 
                   2191: static struct vm_area_struct *vma_next(struct vm_area_struct *vma)
                   2192: {
1.1.1.10  root     2193:     return (QTAILQ_NEXT(vma, vma_link));
1.1.1.8   root     2194: }
                   2195: 
                   2196: static int vma_get_mapping_count(const struct mm_struct *mm)
                   2197: {
                   2198:     return (mm->mm_count);
                   2199: }
                   2200: 
                   2201: /*
                   2202:  * Calculate file (dump) size of given memory region.
                   2203:  */
                   2204: static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
                   2205: {
                   2206:     /* if we cannot even read the first page, skip it */
                   2207:     if (!access_ok(VERIFY_READ, vma->vma_start, TARGET_PAGE_SIZE))
                   2208:         return (0);
                   2209: 
                   2210:     /*
                   2211:      * Usually we don't dump executable pages as they contain
                   2212:      * non-writable code that debugger can read directly from
                   2213:      * target library etc.  However, thread stacks are marked
                   2214:      * also executable so we read in first page of given region
                   2215:      * and check whether it contains elf header.  If there is
                   2216:      * no elf header, we dump it.
                   2217:      */
                   2218:     if (vma->vma_flags & PROT_EXEC) {
                   2219:         char page[TARGET_PAGE_SIZE];
                   2220: 
                   2221:         copy_from_user(page, vma->vma_start, sizeof (page));
                   2222:         if ((page[EI_MAG0] == ELFMAG0) &&
                   2223:             (page[EI_MAG1] == ELFMAG1) &&
                   2224:             (page[EI_MAG2] == ELFMAG2) &&
                   2225:             (page[EI_MAG3] == ELFMAG3)) {
                   2226:             /*
                   2227:              * Mappings are possibly from ELF binary.  Don't dump
                   2228:              * them.
                   2229:              */
                   2230:             return (0);
                   2231:         }
                   2232:     }
                   2233: 
                   2234:     return (vma->vma_end - vma->vma_start);
                   2235: }
                   2236: 
1.1.1.11! root     2237: static int vma_walker(void *priv, abi_ulong start, abi_ulong end,
1.1.1.8   root     2238:     unsigned long flags)
                   2239: {
                   2240:     struct mm_struct *mm = (struct mm_struct *)priv;
                   2241: 
                   2242:     vma_add_mapping(mm, start, end, flags);
                   2243:     return (0);
                   2244: }
                   2245: 
                   2246: static void fill_note(struct memelfnote *note, const char *name, int type,
                   2247:     unsigned int sz, void *data)
                   2248: {
                   2249:     unsigned int namesz;
                   2250: 
                   2251:     namesz = strlen(name) + 1;
                   2252:     note->name = name;
                   2253:     note->namesz = namesz;
                   2254:     note->namesz_rounded = roundup(namesz, sizeof (int32_t));
                   2255:     note->type = type;
                   2256:     note->datasz = roundup(sz, sizeof (int32_t));;
                   2257:     note->data = data;
                   2258: 
                   2259:     /*
                   2260:      * We calculate rounded up note size here as specified by
                   2261:      * ELF document.
                   2262:      */
                   2263:     note->notesz = sizeof (struct elf_note) +
                   2264:         note->namesz_rounded + note->datasz;
                   2265: }
                   2266: 
                   2267: static void fill_elf_header(struct elfhdr *elf, int segs, uint16_t machine,
                   2268:     uint32_t flags)
                   2269: {
                   2270:     (void) memset(elf, 0, sizeof(*elf));
                   2271: 
                   2272:     (void) memcpy(elf->e_ident, ELFMAG, SELFMAG);
                   2273:     elf->e_ident[EI_CLASS] = ELF_CLASS;
                   2274:     elf->e_ident[EI_DATA] = ELF_DATA;
                   2275:     elf->e_ident[EI_VERSION] = EV_CURRENT;
                   2276:     elf->e_ident[EI_OSABI] = ELF_OSABI;
                   2277: 
                   2278:     elf->e_type = ET_CORE;
                   2279:     elf->e_machine = machine;
                   2280:     elf->e_version = EV_CURRENT;
                   2281:     elf->e_phoff = sizeof(struct elfhdr);
                   2282:     elf->e_flags = flags;
                   2283:     elf->e_ehsize = sizeof(struct elfhdr);
                   2284:     elf->e_phentsize = sizeof(struct elf_phdr);
                   2285:     elf->e_phnum = segs;
                   2286: 
                   2287: #ifdef BSWAP_NEEDED
                   2288:     bswap_ehdr(elf);
                   2289: #endif
                   2290: }
                   2291: 
                   2292: static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, off_t offset)
                   2293: {
                   2294:     phdr->p_type = PT_NOTE;
                   2295:     phdr->p_offset = offset;
                   2296:     phdr->p_vaddr = 0;
                   2297:     phdr->p_paddr = 0;
                   2298:     phdr->p_filesz = sz;
                   2299:     phdr->p_memsz = 0;
                   2300:     phdr->p_flags = 0;
                   2301:     phdr->p_align = 0;
                   2302: 
                   2303: #ifdef BSWAP_NEEDED
                   2304:     bswap_phdr(phdr);
                   2305: #endif
                   2306: }
                   2307: 
                   2308: static size_t note_size(const struct memelfnote *note)
                   2309: {
                   2310:     return (note->notesz);
                   2311: }
                   2312: 
1.1.1.9   root     2313: static void fill_prstatus(struct target_elf_prstatus *prstatus,
1.1.1.8   root     2314:     const TaskState *ts, int signr)
                   2315: {
                   2316:     (void) memset(prstatus, 0, sizeof (*prstatus));
                   2317:     prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
                   2318:     prstatus->pr_pid = ts->ts_tid;
                   2319:     prstatus->pr_ppid = getppid();
                   2320:     prstatus->pr_pgrp = getpgrp();
                   2321:     prstatus->pr_sid = getsid(0);
                   2322: 
                   2323: #ifdef BSWAP_NEEDED
                   2324:     bswap_prstatus(prstatus);
                   2325: #endif
                   2326: }
                   2327: 
1.1.1.9   root     2328: static int fill_psinfo(struct target_elf_prpsinfo *psinfo, const TaskState *ts)
1.1.1.8   root     2329: {
                   2330:     char *filename, *base_filename;
                   2331:     unsigned int i, len;
                   2332: 
                   2333:     (void) memset(psinfo, 0, sizeof (*psinfo));
                   2334: 
                   2335:     len = ts->info->arg_end - ts->info->arg_start;
                   2336:     if (len >= ELF_PRARGSZ)
                   2337:         len = ELF_PRARGSZ - 1;
                   2338:     if (copy_from_user(&psinfo->pr_psargs, ts->info->arg_start, len))
                   2339:         return -EFAULT;
                   2340:     for (i = 0; i < len; i++)
                   2341:         if (psinfo->pr_psargs[i] == 0)
                   2342:             psinfo->pr_psargs[i] = ' ';
                   2343:     psinfo->pr_psargs[len] = 0;
                   2344: 
                   2345:     psinfo->pr_pid = getpid();
                   2346:     psinfo->pr_ppid = getppid();
                   2347:     psinfo->pr_pgrp = getpgrp();
                   2348:     psinfo->pr_sid = getsid(0);
                   2349:     psinfo->pr_uid = getuid();
                   2350:     psinfo->pr_gid = getgid();
                   2351: 
                   2352:     filename = strdup(ts->bprm->filename);
                   2353:     base_filename = strdup(basename(filename));
                   2354:     (void) strncpy(psinfo->pr_fname, base_filename,
                   2355:         sizeof(psinfo->pr_fname));
                   2356:     free(base_filename);
                   2357:     free(filename);
                   2358: 
                   2359: #ifdef BSWAP_NEEDED
                   2360:     bswap_psinfo(psinfo);
                   2361: #endif
                   2362:     return (0);
                   2363: }
                   2364: 
                   2365: static void fill_auxv_note(struct memelfnote *note, const TaskState *ts)
                   2366: {
                   2367:     elf_addr_t auxv = (elf_addr_t)ts->info->saved_auxv;
                   2368:     elf_addr_t orig_auxv = auxv;
                   2369:     abi_ulong val;
                   2370:     void *ptr;
                   2371:     int i, len;
                   2372: 
                   2373:     /*
                   2374:      * Auxiliary vector is stored in target process stack.  It contains
                   2375:      * {type, value} pairs that we need to dump into note.  This is not
                   2376:      * strictly necessary but we do it here for sake of completeness.
                   2377:      */
                   2378: 
                   2379:     /* find out lenght of the vector, AT_NULL is terminator */
                   2380:     i = len = 0;
                   2381:     do {
                   2382:         get_user_ual(val, auxv);
                   2383:         i += 2;
                   2384:         auxv += 2 * sizeof (elf_addr_t);
                   2385:     } while (val != AT_NULL);
                   2386:     len = i * sizeof (elf_addr_t);
                   2387: 
                   2388:     /* read in whole auxv vector and copy it to memelfnote */
                   2389:     ptr = lock_user(VERIFY_READ, orig_auxv, len, 0);
                   2390:     if (ptr != NULL) {
                   2391:         fill_note(note, "CORE", NT_AUXV, len, ptr);
                   2392:         unlock_user(ptr, auxv, len);
                   2393:     }
                   2394: }
                   2395: 
                   2396: /*
                   2397:  * Constructs name of coredump file.  We have following convention
                   2398:  * for the name:
                   2399:  *     qemu_<basename-of-target-binary>_<date>-<time>_<pid>.core
                   2400:  *
                   2401:  * Returns 0 in case of success, -1 otherwise (errno is set).
                   2402:  */
                   2403: static int core_dump_filename(const TaskState *ts, char *buf,
                   2404:     size_t bufsize)
                   2405: {
                   2406:     char timestamp[64];
                   2407:     char *filename = NULL;
                   2408:     char *base_filename = NULL;
                   2409:     struct timeval tv;
                   2410:     struct tm tm;
                   2411: 
                   2412:     assert(bufsize >= PATH_MAX);
                   2413: 
                   2414:     if (gettimeofday(&tv, NULL) < 0) {
                   2415:         (void) fprintf(stderr, "unable to get current timestamp: %s",
                   2416:             strerror(errno));
                   2417:         return (-1);
                   2418:     }
                   2419: 
                   2420:     filename = strdup(ts->bprm->filename);
                   2421:     base_filename = strdup(basename(filename));
                   2422:     (void) strftime(timestamp, sizeof (timestamp), "%Y%m%d-%H%M%S",
                   2423:         localtime_r(&tv.tv_sec, &tm));
                   2424:     (void) snprintf(buf, bufsize, "qemu_%s_%s_%d.core",
                   2425:         base_filename, timestamp, (int)getpid());
                   2426:     free(base_filename);
                   2427:     free(filename);
                   2428: 
                   2429:     return (0);
                   2430: }
                   2431: 
                   2432: static int dump_write(int fd, const void *ptr, size_t size)
                   2433: {
                   2434:     const char *bufp = (const char *)ptr;
                   2435:     ssize_t bytes_written, bytes_left;
                   2436:     struct rlimit dumpsize;
                   2437:     off_t pos;
                   2438: 
                   2439:     bytes_written = 0;
                   2440:     getrlimit(RLIMIT_CORE, &dumpsize);
                   2441:     if ((pos = lseek(fd, 0, SEEK_CUR))==-1) {
                   2442:         if (errno == ESPIPE) { /* not a seekable stream */
                   2443:             bytes_left = size;
                   2444:         } else {
                   2445:             return pos;
                   2446:         }
                   2447:     } else {
                   2448:         if (dumpsize.rlim_cur <= pos) {
                   2449:             return -1;
                   2450:         } else if (dumpsize.rlim_cur == RLIM_INFINITY) {
                   2451:             bytes_left = size;
                   2452:         } else {
                   2453:             size_t limit_left=dumpsize.rlim_cur - pos;
                   2454:             bytes_left = limit_left >= size ? size : limit_left ;
                   2455:         }
                   2456:     }
                   2457: 
                   2458:     /*
                   2459:      * In normal conditions, single write(2) should do but
                   2460:      * in case of socket etc. this mechanism is more portable.
                   2461:      */
                   2462:     do {
                   2463:         bytes_written = write(fd, bufp, bytes_left);
                   2464:         if (bytes_written < 0) {
                   2465:             if (errno == EINTR)
                   2466:                 continue;
                   2467:             return (-1);
                   2468:         } else if (bytes_written == 0) { /* eof */
                   2469:             return (-1);
                   2470:         }
                   2471:         bufp += bytes_written;
                   2472:         bytes_left -= bytes_written;
                   2473:     } while (bytes_left > 0);
                   2474: 
                   2475:     return (0);
                   2476: }
                   2477: 
                   2478: static int write_note(struct memelfnote *men, int fd)
                   2479: {
                   2480:     struct elf_note en;
                   2481: 
                   2482:     en.n_namesz = men->namesz;
                   2483:     en.n_type = men->type;
                   2484:     en.n_descsz = men->datasz;
                   2485: 
                   2486: #ifdef BSWAP_NEEDED
                   2487:     bswap_note(&en);
                   2488: #endif
                   2489: 
                   2490:     if (dump_write(fd, &en, sizeof(en)) != 0)
                   2491:         return (-1);
                   2492:     if (dump_write(fd, men->name, men->namesz_rounded) != 0)
                   2493:         return (-1);
                   2494:     if (dump_write(fd, men->data, men->datasz) != 0)
                   2495:         return (-1);
                   2496: 
                   2497:     return (0);
                   2498: }
                   2499: 
                   2500: static void fill_thread_info(struct elf_note_info *info, const CPUState *env)
                   2501: {
                   2502:     TaskState *ts = (TaskState *)env->opaque;
                   2503:     struct elf_thread_status *ets;
                   2504: 
                   2505:     ets = qemu_mallocz(sizeof (*ets));
                   2506:     ets->num_notes = 1; /* only prstatus is dumped */
                   2507:     fill_prstatus(&ets->prstatus, ts, 0);
                   2508:     elf_core_copy_regs(&ets->prstatus.pr_reg, env);
                   2509:     fill_note(&ets->notes[0], "CORE", NT_PRSTATUS, sizeof (ets->prstatus),
                   2510:         &ets->prstatus);
                   2511: 
1.1.1.10  root     2512:     QTAILQ_INSERT_TAIL(&info->thread_list, ets, ets_link);
1.1.1.8   root     2513: 
                   2514:     info->notes_size += note_size(&ets->notes[0]);
                   2515: }
                   2516: 
                   2517: static int fill_note_info(struct elf_note_info *info,
                   2518:     long signr, const CPUState *env)
                   2519: {
                   2520: #define NUMNOTES 3
                   2521:     CPUState *cpu = NULL;
                   2522:     TaskState *ts = (TaskState *)env->opaque;
                   2523:     int i;
                   2524: 
                   2525:     (void) memset(info, 0, sizeof (*info));
                   2526: 
1.1.1.10  root     2527:     QTAILQ_INIT(&info->thread_list);
1.1.1.8   root     2528: 
                   2529:     info->notes = qemu_mallocz(NUMNOTES * sizeof (struct memelfnote));
                   2530:     if (info->notes == NULL)
                   2531:         return (-ENOMEM);
                   2532:     info->prstatus = qemu_mallocz(sizeof (*info->prstatus));
                   2533:     if (info->prstatus == NULL)
                   2534:         return (-ENOMEM);
                   2535:     info->psinfo = qemu_mallocz(sizeof (*info->psinfo));
                   2536:     if (info->prstatus == NULL)
                   2537:         return (-ENOMEM);
                   2538: 
                   2539:     /*
                   2540:      * First fill in status (and registers) of current thread
                   2541:      * including process info & aux vector.
                   2542:      */
                   2543:     fill_prstatus(info->prstatus, ts, signr);
                   2544:     elf_core_copy_regs(&info->prstatus->pr_reg, env);
                   2545:     fill_note(&info->notes[0], "CORE", NT_PRSTATUS,
                   2546:         sizeof (*info->prstatus), info->prstatus);
                   2547:     fill_psinfo(info->psinfo, ts);
                   2548:     fill_note(&info->notes[1], "CORE", NT_PRPSINFO,
                   2549:         sizeof (*info->psinfo), info->psinfo);
                   2550:     fill_auxv_note(&info->notes[2], ts);
                   2551:     info->numnote = 3;
                   2552: 
                   2553:     info->notes_size = 0;
                   2554:     for (i = 0; i < info->numnote; i++)
                   2555:         info->notes_size += note_size(&info->notes[i]);
                   2556: 
                   2557:     /* read and fill status of all threads */
                   2558:     cpu_list_lock();
                   2559:     for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
                   2560:         if (cpu == thread_env)
                   2561:             continue;
                   2562:         fill_thread_info(info, cpu);
                   2563:     }
                   2564:     cpu_list_unlock();
                   2565: 
                   2566:     return (0);
                   2567: }
                   2568: 
                   2569: static void free_note_info(struct elf_note_info *info)
                   2570: {
                   2571:     struct elf_thread_status *ets;
                   2572: 
1.1.1.10  root     2573:     while (!QTAILQ_EMPTY(&info->thread_list)) {
                   2574:         ets = QTAILQ_FIRST(&info->thread_list);
                   2575:         QTAILQ_REMOVE(&info->thread_list, ets, ets_link);
1.1.1.8   root     2576:         qemu_free(ets);
                   2577:     }
                   2578: 
                   2579:     qemu_free(info->prstatus);
                   2580:     qemu_free(info->psinfo);
                   2581:     qemu_free(info->notes);
                   2582: }
                   2583: 
                   2584: static int write_note_info(struct elf_note_info *info, int fd)
                   2585: {
                   2586:     struct elf_thread_status *ets;
                   2587:     int i, error = 0;
                   2588: 
                   2589:     /* write prstatus, psinfo and auxv for current thread */
                   2590:     for (i = 0; i < info->numnote; i++)
                   2591:         if ((error = write_note(&info->notes[i], fd)) != 0)
                   2592:             return (error);
                   2593: 
                   2594:     /* write prstatus for each thread */
                   2595:     for (ets = info->thread_list.tqh_first; ets != NULL;
                   2596:         ets = ets->ets_link.tqe_next) {
                   2597:         if ((error = write_note(&ets->notes[0], fd)) != 0)
                   2598:             return (error);
                   2599:     }
                   2600: 
                   2601:     return (0);
                   2602: }
                   2603: 
                   2604: /*
                   2605:  * Write out ELF coredump.
                   2606:  *
                   2607:  * See documentation of ELF object file format in:
                   2608:  * http://www.caldera.com/developers/devspecs/gabi41.pdf
                   2609:  *
                   2610:  * Coredump format in linux is following:
                   2611:  *
                   2612:  * 0   +----------------------+         \
                   2613:  *     | ELF header           | ET_CORE  |
                   2614:  *     +----------------------+          |
                   2615:  *     | ELF program headers  |          |--- headers
                   2616:  *     | - NOTE section       |          |
                   2617:  *     | - PT_LOAD sections   |          |
                   2618:  *     +----------------------+         /
                   2619:  *     | NOTEs:               |
                   2620:  *     | - NT_PRSTATUS        |
                   2621:  *     | - NT_PRSINFO         |
                   2622:  *     | - NT_AUXV            |
                   2623:  *     +----------------------+ <-- aligned to target page
                   2624:  *     | Process memory dump  |
                   2625:  *     :                      :
                   2626:  *     .                      .
                   2627:  *     :                      :
                   2628:  *     |                      |
                   2629:  *     +----------------------+
                   2630:  *
                   2631:  * NT_PRSTATUS -> struct elf_prstatus (per thread)
                   2632:  * NT_PRSINFO  -> struct elf_prpsinfo
                   2633:  * NT_AUXV is array of { type, value } pairs (see fill_auxv_note()).
                   2634:  *
                   2635:  * Format follows System V format as close as possible.  Current
                   2636:  * version limitations are as follows:
                   2637:  *     - no floating point registers are dumped
                   2638:  *
                   2639:  * Function returns 0 in case of success, negative errno otherwise.
                   2640:  *
                   2641:  * TODO: make this work also during runtime: it should be
                   2642:  * possible to force coredump from running process and then
                   2643:  * continue processing.  For example qemu could set up SIGUSR2
                   2644:  * handler (provided that target process haven't registered
                   2645:  * handler for that) that does the dump when signal is received.
                   2646:  */
                   2647: static int elf_core_dump(int signr, const CPUState *env)
                   2648: {
                   2649:     const TaskState *ts = (const TaskState *)env->opaque;
                   2650:     struct vm_area_struct *vma = NULL;
                   2651:     char corefile[PATH_MAX];
                   2652:     struct elf_note_info info;
                   2653:     struct elfhdr elf;
                   2654:     struct elf_phdr phdr;
                   2655:     struct rlimit dumpsize;
                   2656:     struct mm_struct *mm = NULL;
                   2657:     off_t offset = 0, data_offset = 0;
                   2658:     int segs = 0;
                   2659:     int fd = -1;
                   2660: 
                   2661:     errno = 0;
                   2662:     getrlimit(RLIMIT_CORE, &dumpsize);
                   2663:     if (dumpsize.rlim_cur == 0)
                   2664:        return 0;
                   2665: 
                   2666:     if (core_dump_filename(ts, corefile, sizeof (corefile)) < 0)
                   2667:         return (-errno);
                   2668: 
                   2669:     if ((fd = open(corefile, O_WRONLY | O_CREAT,
                   2670:         S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
                   2671:         return (-errno);
                   2672: 
                   2673:     /*
                   2674:      * Walk through target process memory mappings and
                   2675:      * set up structure containing this information.  After
                   2676:      * this point vma_xxx functions can be used.
                   2677:      */
                   2678:     if ((mm = vma_init()) == NULL)
                   2679:         goto out;
                   2680: 
                   2681:     walk_memory_regions(mm, vma_walker);
                   2682:     segs = vma_get_mapping_count(mm);
                   2683: 
                   2684:     /*
                   2685:      * Construct valid coredump ELF header.  We also
                   2686:      * add one more segment for notes.
                   2687:      */
                   2688:     fill_elf_header(&elf, segs + 1, ELF_MACHINE, 0);
                   2689:     if (dump_write(fd, &elf, sizeof (elf)) != 0)
                   2690:         goto out;
                   2691: 
                   2692:     /* fill in in-memory version of notes */
                   2693:     if (fill_note_info(&info, signr, env) < 0)
                   2694:         goto out;
                   2695: 
                   2696:     offset += sizeof (elf);                             /* elf header */
                   2697:     offset += (segs + 1) * sizeof (struct elf_phdr);    /* program headers */
                   2698: 
                   2699:     /* write out notes program header */
                   2700:     fill_elf_note_phdr(&phdr, info.notes_size, offset);
                   2701: 
                   2702:     offset += info.notes_size;
                   2703:     if (dump_write(fd, &phdr, sizeof (phdr)) != 0)
                   2704:         goto out;
                   2705: 
                   2706:     /*
                   2707:      * ELF specification wants data to start at page boundary so
                   2708:      * we align it here.
                   2709:      */
                   2710:     offset = roundup(offset, ELF_EXEC_PAGESIZE);
                   2711: 
                   2712:     /*
                   2713:      * Write program headers for memory regions mapped in
                   2714:      * the target process.
                   2715:      */
                   2716:     for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {
                   2717:         (void) memset(&phdr, 0, sizeof (phdr));
                   2718: 
                   2719:         phdr.p_type = PT_LOAD;
                   2720:         phdr.p_offset = offset;
                   2721:         phdr.p_vaddr = vma->vma_start;
                   2722:         phdr.p_paddr = 0;
                   2723:         phdr.p_filesz = vma_dump_size(vma);
                   2724:         offset += phdr.p_filesz;
                   2725:         phdr.p_memsz = vma->vma_end - vma->vma_start;
                   2726:         phdr.p_flags = vma->vma_flags & PROT_READ ? PF_R : 0;
                   2727:         if (vma->vma_flags & PROT_WRITE)
                   2728:             phdr.p_flags |= PF_W;
                   2729:         if (vma->vma_flags & PROT_EXEC)
                   2730:             phdr.p_flags |= PF_X;
                   2731:         phdr.p_align = ELF_EXEC_PAGESIZE;
                   2732: 
                   2733:         dump_write(fd, &phdr, sizeof (phdr));
                   2734:     }
                   2735: 
                   2736:     /*
                   2737:      * Next we write notes just after program headers.  No
                   2738:      * alignment needed here.
                   2739:      */
                   2740:     if (write_note_info(&info, fd) < 0)
                   2741:         goto out;
                   2742: 
                   2743:     /* align data to page boundary */
                   2744:     data_offset = lseek(fd, 0, SEEK_CUR);
                   2745:     data_offset = TARGET_PAGE_ALIGN(data_offset);
                   2746:     if (lseek(fd, data_offset, SEEK_SET) != data_offset)
                   2747:         goto out;
                   2748: 
                   2749:     /*
                   2750:      * Finally we can dump process memory into corefile as well.
                   2751:      */
                   2752:     for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {
                   2753:         abi_ulong addr;
                   2754:         abi_ulong end;
                   2755: 
                   2756:         end = vma->vma_start + vma_dump_size(vma);
                   2757: 
                   2758:         for (addr = vma->vma_start; addr < end;
                   2759:             addr += TARGET_PAGE_SIZE) {
                   2760:             char page[TARGET_PAGE_SIZE];
                   2761:             int error;
                   2762: 
                   2763:             /*
                   2764:              *  Read in page from target process memory and
                   2765:              *  write it to coredump file.
                   2766:              */
                   2767:             error = copy_from_user(page, addr, sizeof (page));
                   2768:             if (error != 0) {
1.1.1.11! root     2769:                 (void) fprintf(stderr, "unable to dump " TARGET_ABI_FMT_lx "\n",
1.1.1.8   root     2770:                     addr);
                   2771:                 errno = -error;
                   2772:                 goto out;
                   2773:             }
                   2774:             if (dump_write(fd, page, TARGET_PAGE_SIZE) < 0)
                   2775:                 goto out;
                   2776:         }
                   2777:     }
                   2778: 
                   2779: out:
                   2780:     free_note_info(&info);
                   2781:     if (mm != NULL)
                   2782:         vma_delete(mm);
                   2783:     (void) close(fd);
                   2784: 
                   2785:     if (errno != 0)
                   2786:         return (-errno);
                   2787:     return (0);
                   2788: }
                   2789: 
                   2790: #endif /* USE_ELF_CORE_DUMP */
                   2791: 
1.1       root     2792: static int load_aout_interp(void * exptr, int interp_fd)
                   2793: {
                   2794:     printf("a.out interpreter not yet supported\n");
                   2795:     return(0);
                   2796: }
                   2797: 
1.1.1.4   root     2798: void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
                   2799: {
                   2800:     init_thread(regs, infop);
                   2801: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.