Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ 124964b5

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