Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ c958a8bd

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