Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ 2e9a5713

History | View | Annotate | Download (78.1 kB)

1 31e31b8a bellard
/* This is the Linux kernel elf-loading code, ported into user space */
2 edf8e2af Mika Westerberg
#include <sys/time.h>
3 edf8e2af Mika Westerberg
#include <sys/param.h>
4 31e31b8a bellard
5 31e31b8a bellard
#include <stdio.h>
6 31e31b8a bellard
#include <sys/types.h>
7 31e31b8a bellard
#include <fcntl.h>
8 31e31b8a bellard
#include <errno.h>
9 31e31b8a bellard
#include <unistd.h>
10 31e31b8a bellard
#include <sys/mman.h>
11 edf8e2af Mika Westerberg
#include <sys/resource.h>
12 31e31b8a bellard
#include <stdlib.h>
13 31e31b8a bellard
#include <string.h>
14 edf8e2af Mika Westerberg
#include <time.h>
15 31e31b8a bellard
16 3ef693a0 bellard
#include "qemu.h"
17 689f936f bellard
#include "disas.h"
18 31e31b8a bellard
19 e58ffeb3 malc
#ifdef _ARCH_PPC64
20 a6cc84f4 malc
#undef ARCH_DLINFO
21 a6cc84f4 malc
#undef ELF_PLATFORM
22 a6cc84f4 malc
#undef ELF_HWCAP
23 a6cc84f4 malc
#undef ELF_CLASS
24 a6cc84f4 malc
#undef ELF_DATA
25 a6cc84f4 malc
#undef ELF_ARCH
26 a6cc84f4 malc
#endif
27 a6cc84f4 malc
28 edf8e2af Mika Westerberg
#define ELF_OSABI   ELFOSABI_SYSV
29 edf8e2af Mika Westerberg
30 cb33da57 blueswir1
/* from personality.h */
31 cb33da57 blueswir1
32 cb33da57 blueswir1
/*
33 cb33da57 blueswir1
 * Flags for bug emulation.
34 cb33da57 blueswir1
 *
35 cb33da57 blueswir1
 * These occupy the top three bytes.
36 cb33da57 blueswir1
 */
37 cb33da57 blueswir1
enum {
38 cb33da57 blueswir1
        ADDR_NO_RANDOMIZE =         0x0040000,        /* disable randomization of VA space */
39 cb33da57 blueswir1
        FDPIC_FUNCPTRS =        0x0080000,        /* userspace function ptrs point to descriptors
40 cb33da57 blueswir1
                                                 * (signal handling)
41 cb33da57 blueswir1
                                                 */
42 cb33da57 blueswir1
        MMAP_PAGE_ZERO =        0x0100000,
43 cb33da57 blueswir1
        ADDR_COMPAT_LAYOUT =        0x0200000,
44 cb33da57 blueswir1
        READ_IMPLIES_EXEC =        0x0400000,
45 cb33da57 blueswir1
        ADDR_LIMIT_32BIT =        0x0800000,
46 cb33da57 blueswir1
        SHORT_INODE =                0x1000000,
47 cb33da57 blueswir1
        WHOLE_SECONDS =                0x2000000,
48 cb33da57 blueswir1
        STICKY_TIMEOUTS        =        0x4000000,
49 cb33da57 blueswir1
        ADDR_LIMIT_3GB =         0x8000000,
50 cb33da57 blueswir1
};
51 cb33da57 blueswir1
52 cb33da57 blueswir1
/*
53 cb33da57 blueswir1
 * Personality types.
54 cb33da57 blueswir1
 *
55 cb33da57 blueswir1
 * These go in the low byte.  Avoid using the top bit, it will
56 cb33da57 blueswir1
 * conflict with error returns.
57 cb33da57 blueswir1
 */
58 cb33da57 blueswir1
enum {
59 cb33da57 blueswir1
        PER_LINUX =                0x0000,
60 cb33da57 blueswir1
        PER_LINUX_32BIT =        0x0000 | ADDR_LIMIT_32BIT,
61 cb33da57 blueswir1
        PER_LINUX_FDPIC =        0x0000 | FDPIC_FUNCPTRS,
62 cb33da57 blueswir1
        PER_SVR4 =                0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
63 cb33da57 blueswir1
        PER_SVR3 =                0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
64 cb33da57 blueswir1
        PER_SCOSVR3 =                0x0003 | STICKY_TIMEOUTS |
65 cb33da57 blueswir1
                                         WHOLE_SECONDS | SHORT_INODE,
66 cb33da57 blueswir1
        PER_OSR5 =                0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
67 cb33da57 blueswir1
        PER_WYSEV386 =                0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
68 cb33da57 blueswir1
        PER_ISCR4 =                0x0005 | STICKY_TIMEOUTS,
69 cb33da57 blueswir1
        PER_BSD =                0x0006,
70 cb33da57 blueswir1
        PER_SUNOS =                0x0006 | STICKY_TIMEOUTS,
71 cb33da57 blueswir1
        PER_XENIX =                0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
72 cb33da57 blueswir1
        PER_LINUX32 =                0x0008,
73 cb33da57 blueswir1
        PER_LINUX32_3GB =        0x0008 | ADDR_LIMIT_3GB,
74 cb33da57 blueswir1
        PER_IRIX32 =                0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
75 cb33da57 blueswir1
        PER_IRIXN32 =                0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
76 cb33da57 blueswir1
        PER_IRIX64 =                0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
77 cb33da57 blueswir1
        PER_RISCOS =                0x000c,
78 cb33da57 blueswir1
        PER_SOLARIS =                0x000d | STICKY_TIMEOUTS,
79 cb33da57 blueswir1
        PER_UW7 =                0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
80 cb33da57 blueswir1
        PER_OSF4 =                0x000f,                         /* OSF/1 v4 */
81 cb33da57 blueswir1
        PER_HPUX =                0x0010,
82 cb33da57 blueswir1
        PER_MASK =                0x00ff,
83 cb33da57 blueswir1
};
84 cb33da57 blueswir1
85 cb33da57 blueswir1
/*
86 cb33da57 blueswir1
 * Return the base personality without flags.
87 cb33da57 blueswir1
 */
88 cb33da57 blueswir1
#define personality(pers)        (pers & PER_MASK)
89 cb33da57 blueswir1
90 83fb7adf bellard
/* this flag is uneffective under linux too, should be deleted */
91 83fb7adf bellard
#ifndef MAP_DENYWRITE
92 83fb7adf bellard
#define MAP_DENYWRITE 0
93 83fb7adf bellard
#endif
94 83fb7adf bellard
95 83fb7adf bellard
/* should probably go in elf.h */
96 83fb7adf bellard
#ifndef ELIBBAD
97 83fb7adf bellard
#define ELIBBAD 80
98 83fb7adf bellard
#endif
99 83fb7adf bellard
100 21e807fa Nathan Froyd
typedef target_ulong        target_elf_greg_t;
101 21e807fa Nathan Froyd
#ifdef USE_UID16
102 21e807fa Nathan Froyd
typedef uint16_t        target_uid_t;
103 21e807fa Nathan Froyd
typedef uint16_t        target_gid_t;
104 21e807fa Nathan Froyd
#else
105 21e807fa Nathan Froyd
typedef uint32_t        target_uid_t;
106 21e807fa Nathan Froyd
typedef uint32_t        target_gid_t;
107 21e807fa Nathan Froyd
#endif
108 21e807fa Nathan Froyd
typedef int32_t                target_pid_t;
109 21e807fa Nathan Froyd
110 30ac07d4 bellard
#ifdef TARGET_I386
111 30ac07d4 bellard
112 15338fd7 bellard
#define ELF_PLATFORM get_elf_platform()
113 15338fd7 bellard
114 15338fd7 bellard
static const char *get_elf_platform(void)
115 15338fd7 bellard
{
116 15338fd7 bellard
    static char elf_platform[] = "i386";
117 d5975363 pbrook
    int family = (thread_env->cpuid_version >> 8) & 0xff;
118 15338fd7 bellard
    if (family > 6)
119 15338fd7 bellard
        family = 6;
120 15338fd7 bellard
    if (family >= 3)
121 15338fd7 bellard
        elf_platform[1] = '0' + family;
122 15338fd7 bellard
    return elf_platform;
123 15338fd7 bellard
}
124 15338fd7 bellard
125 15338fd7 bellard
#define ELF_HWCAP get_elf_hwcap()
126 15338fd7 bellard
127 15338fd7 bellard
static uint32_t get_elf_hwcap(void)
128 15338fd7 bellard
{
129 d5975363 pbrook
  return thread_env->cpuid_features;
130 15338fd7 bellard
}
131 15338fd7 bellard
132 84409ddb j_mayer
#ifdef TARGET_X86_64
133 84409ddb j_mayer
#define ELF_START_MMAP 0x2aaaaab000ULL
134 84409ddb j_mayer
#define elf_check_arch(x) ( ((x) == ELF_ARCH) )
135 84409ddb j_mayer
136 84409ddb j_mayer
#define ELF_CLASS      ELFCLASS64
137 84409ddb j_mayer
#define ELF_DATA       ELFDATA2LSB
138 84409ddb j_mayer
#define ELF_ARCH       EM_X86_64
139 84409ddb j_mayer
140 84409ddb j_mayer
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
141 84409ddb j_mayer
{
142 84409ddb j_mayer
    regs->rax = 0;
143 84409ddb j_mayer
    regs->rsp = infop->start_stack;
144 84409ddb j_mayer
    regs->rip = infop->entry;
145 84409ddb j_mayer
}
146 84409ddb j_mayer
147 9edc5d79 Mika Westerberg
#define ELF_NREG    27
148 c227f099 Anthony Liguori
typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
149 9edc5d79 Mika Westerberg
150 9edc5d79 Mika Westerberg
/*
151 9edc5d79 Mika Westerberg
 * Note that ELF_NREG should be 29 as there should be place for
152 9edc5d79 Mika Westerberg
 * TRAPNO and ERR "registers" as well but linux doesn't dump
153 9edc5d79 Mika Westerberg
 * those.
154 9edc5d79 Mika Westerberg
 *
155 9edc5d79 Mika Westerberg
 * See linux kernel: arch/x86/include/asm/elf.h
156 9edc5d79 Mika Westerberg
 */
157 c227f099 Anthony Liguori
static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
158 9edc5d79 Mika Westerberg
{
159 9edc5d79 Mika Westerberg
    (*regs)[0] = env->regs[15];
160 9edc5d79 Mika Westerberg
    (*regs)[1] = env->regs[14];
161 9edc5d79 Mika Westerberg
    (*regs)[2] = env->regs[13];
162 9edc5d79 Mika Westerberg
    (*regs)[3] = env->regs[12];
163 9edc5d79 Mika Westerberg
    (*regs)[4] = env->regs[R_EBP];
164 9edc5d79 Mika Westerberg
    (*regs)[5] = env->regs[R_EBX];
165 9edc5d79 Mika Westerberg
    (*regs)[6] = env->regs[11];
166 9edc5d79 Mika Westerberg
    (*regs)[7] = env->regs[10];
167 9edc5d79 Mika Westerberg
    (*regs)[8] = env->regs[9];
168 9edc5d79 Mika Westerberg
    (*regs)[9] = env->regs[8];
169 9edc5d79 Mika Westerberg
    (*regs)[10] = env->regs[R_EAX];
170 9edc5d79 Mika Westerberg
    (*regs)[11] = env->regs[R_ECX];
171 9edc5d79 Mika Westerberg
    (*regs)[12] = env->regs[R_EDX];
172 9edc5d79 Mika Westerberg
    (*regs)[13] = env->regs[R_ESI];
173 9edc5d79 Mika Westerberg
    (*regs)[14] = env->regs[R_EDI];
174 9edc5d79 Mika Westerberg
    (*regs)[15] = env->regs[R_EAX]; /* XXX */
175 9edc5d79 Mika Westerberg
    (*regs)[16] = env->eip;
176 9edc5d79 Mika Westerberg
    (*regs)[17] = env->segs[R_CS].selector & 0xffff;
177 9edc5d79 Mika Westerberg
    (*regs)[18] = env->eflags;
178 9edc5d79 Mika Westerberg
    (*regs)[19] = env->regs[R_ESP];
179 9edc5d79 Mika Westerberg
    (*regs)[20] = env->segs[R_SS].selector & 0xffff;
180 9edc5d79 Mika Westerberg
    (*regs)[21] = env->segs[R_FS].selector & 0xffff;
181 9edc5d79 Mika Westerberg
    (*regs)[22] = env->segs[R_GS].selector & 0xffff;
182 9edc5d79 Mika Westerberg
    (*regs)[23] = env->segs[R_DS].selector & 0xffff;
183 9edc5d79 Mika Westerberg
    (*regs)[24] = env->segs[R_ES].selector & 0xffff;
184 9edc5d79 Mika Westerberg
    (*regs)[25] = env->segs[R_FS].selector & 0xffff;
185 9edc5d79 Mika Westerberg
    (*regs)[26] = env->segs[R_GS].selector & 0xffff;
186 9edc5d79 Mika Westerberg
}
187 9edc5d79 Mika Westerberg
188 84409ddb j_mayer
#else
189 84409ddb j_mayer
190 30ac07d4 bellard
#define ELF_START_MMAP 0x80000000
191 30ac07d4 bellard
192 30ac07d4 bellard
/*
193 30ac07d4 bellard
 * This is used to ensure we don't load something for the wrong architecture.
194 30ac07d4 bellard
 */
195 30ac07d4 bellard
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
196 30ac07d4 bellard
197 30ac07d4 bellard
/*
198 30ac07d4 bellard
 * These are used to set parameters in the core dumps.
199 30ac07d4 bellard
 */
200 30ac07d4 bellard
#define ELF_CLASS        ELFCLASS32
201 30ac07d4 bellard
#define ELF_DATA        ELFDATA2LSB
202 30ac07d4 bellard
#define ELF_ARCH        EM_386
203 30ac07d4 bellard
204 b346ff46 bellard
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
205 b346ff46 bellard
{
206 b346ff46 bellard
    regs->esp = infop->start_stack;
207 b346ff46 bellard
    regs->eip = infop->entry;
208 e5fe0c52 pbrook
209 e5fe0c52 pbrook
    /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
210 e5fe0c52 pbrook
       starts %edx contains a pointer to a function which might be
211 e5fe0c52 pbrook
       registered using `atexit'.  This provides a mean for the
212 e5fe0c52 pbrook
       dynamic linker to call DT_FINI functions for shared libraries
213 e5fe0c52 pbrook
       that have been loaded before the code runs.
214 e5fe0c52 pbrook

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