Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ b53d44e5

History | View | Annotate | Download (75 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 30ac07d4 bellard
#ifdef TARGET_I386
101 30ac07d4 bellard
102 15338fd7 bellard
#define ELF_PLATFORM get_elf_platform()
103 15338fd7 bellard
104 15338fd7 bellard
static const char *get_elf_platform(void)
105 15338fd7 bellard
{
106 15338fd7 bellard
    static char elf_platform[] = "i386";
107 d5975363 pbrook
    int family = (thread_env->cpuid_version >> 8) & 0xff;
108 15338fd7 bellard
    if (family > 6)
109 15338fd7 bellard
        family = 6;
110 15338fd7 bellard
    if (family >= 3)
111 15338fd7 bellard
        elf_platform[1] = '0' + family;
112 15338fd7 bellard
    return elf_platform;
113 15338fd7 bellard
}
114 15338fd7 bellard
115 15338fd7 bellard
#define ELF_HWCAP get_elf_hwcap()
116 15338fd7 bellard
117 15338fd7 bellard
static uint32_t get_elf_hwcap(void)
118 15338fd7 bellard
{
119 d5975363 pbrook
  return thread_env->cpuid_features;
120 15338fd7 bellard
}
121 15338fd7 bellard
122 84409ddb j_mayer
#ifdef TARGET_X86_64
123 84409ddb j_mayer
#define ELF_START_MMAP 0x2aaaaab000ULL
124 84409ddb j_mayer
#define elf_check_arch(x) ( ((x) == ELF_ARCH) )
125 84409ddb j_mayer
126 84409ddb j_mayer
#define ELF_CLASS      ELFCLASS64
127 84409ddb j_mayer
#define ELF_DATA       ELFDATA2LSB
128 84409ddb j_mayer
#define ELF_ARCH       EM_X86_64
129 84409ddb j_mayer
130 84409ddb j_mayer
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
131 84409ddb j_mayer
{
132 84409ddb j_mayer
    regs->rax = 0;
133 84409ddb j_mayer
    regs->rsp = infop->start_stack;
134 84409ddb j_mayer
    regs->rip = infop->entry;
135 84409ddb j_mayer
}
136 84409ddb j_mayer
137 c227f099 Anthony Liguori
typedef target_ulong    target_elf_greg_t;
138 c227f099 Anthony Liguori
typedef uint32_t        target_uid_t;
139 c227f099 Anthony Liguori
typedef uint32_t        target_gid_t;
140 c227f099 Anthony Liguori
typedef int32_t         target_pid_t;
141 9edc5d79 Mika Westerberg
142 9edc5d79 Mika Westerberg
#define ELF_NREG    27
143 c227f099 Anthony Liguori
typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
144 9edc5d79 Mika Westerberg
145 9edc5d79 Mika Westerberg
/*
146 9edc5d79 Mika Westerberg
 * Note that ELF_NREG should be 29 as there should be place for
147 9edc5d79 Mika Westerberg
 * TRAPNO and ERR "registers" as well but linux doesn't dump
148 9edc5d79 Mika Westerberg
 * those.
149 9edc5d79 Mika Westerberg
 *
150 9edc5d79 Mika Westerberg
 * See linux kernel: arch/x86/include/asm/elf.h
151 9edc5d79 Mika Westerberg
 */
152 c227f099 Anthony Liguori
static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
153 9edc5d79 Mika Westerberg
{
154 9edc5d79 Mika Westerberg
    (*regs)[0] = env->regs[15];
155 9edc5d79 Mika Westerberg
    (*regs)[1] = env->regs[14];
156 9edc5d79 Mika Westerberg
    (*regs)[2] = env->regs[13];
157 9edc5d79 Mika Westerberg
    (*regs)[3] = env->regs[12];
158 9edc5d79 Mika Westerberg
    (*regs)[4] = env->regs[R_EBP];
159 9edc5d79 Mika Westerberg
    (*regs)[5] = env->regs[R_EBX];
160 9edc5d79 Mika Westerberg
    (*regs)[6] = env->regs[11];
161 9edc5d79 Mika Westerberg
    (*regs)[7] = env->regs[10];
162 9edc5d79 Mika Westerberg
    (*regs)[8] = env->regs[9];
163 9edc5d79 Mika Westerberg
    (*regs)[9] = env->regs[8];
164 9edc5d79 Mika Westerberg
    (*regs)[10] = env->regs[R_EAX];
165 9edc5d79 Mika Westerberg
    (*regs)[11] = env->regs[R_ECX];
166 9edc5d79 Mika Westerberg
    (*regs)[12] = env->regs[R_EDX];
167 9edc5d79 Mika Westerberg
    (*regs)[13] = env->regs[R_ESI];
168 9edc5d79 Mika Westerberg
    (*regs)[14] = env->regs[R_EDI];
169 9edc5d79 Mika Westerberg
    (*regs)[15] = env->regs[R_EAX]; /* XXX */
170 9edc5d79 Mika Westerberg
    (*regs)[16] = env->eip;
171 9edc5d79 Mika Westerberg
    (*regs)[17] = env->segs[R_CS].selector & 0xffff;
172 9edc5d79 Mika Westerberg
    (*regs)[18] = env->eflags;
173 9edc5d79 Mika Westerberg
    (*regs)[19] = env->regs[R_ESP];
174 9edc5d79 Mika Westerberg
    (*regs)[20] = env->segs[R_SS].selector & 0xffff;
175 9edc5d79 Mika Westerberg
    (*regs)[21] = env->segs[R_FS].selector & 0xffff;
176 9edc5d79 Mika Westerberg
    (*regs)[22] = env->segs[R_GS].selector & 0xffff;
177 9edc5d79 Mika Westerberg
    (*regs)[23] = env->segs[R_DS].selector & 0xffff;
178 9edc5d79 Mika Westerberg
    (*regs)[24] = env->segs[R_ES].selector & 0xffff;
179 9edc5d79 Mika Westerberg
    (*regs)[25] = env->segs[R_FS].selector & 0xffff;
180 9edc5d79 Mika Westerberg
    (*regs)[26] = env->segs[R_GS].selector & 0xffff;
181 9edc5d79 Mika Westerberg
}
182 9edc5d79 Mika Westerberg
183 84409ddb j_mayer
#else
184 84409ddb j_mayer
185 30ac07d4 bellard
#define ELF_START_MMAP 0x80000000
186 30ac07d4 bellard
187 30ac07d4 bellard
/*
188 30ac07d4 bellard
 * This is used to ensure we don't load something for the wrong architecture.
189 30ac07d4 bellard
 */
190 30ac07d4 bellard
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
191 30ac07d4 bellard
192 30ac07d4 bellard
/*
193 30ac07d4 bellard
 * These are used to set parameters in the core dumps.
194 30ac07d4 bellard
 */
195 30ac07d4 bellard
#define ELF_CLASS        ELFCLASS32
196 30ac07d4 bellard
#define ELF_DATA        ELFDATA2LSB
197 30ac07d4 bellard
#define ELF_ARCH        EM_386
198 30ac07d4 bellard
199 b346ff46 bellard
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
200 b346ff46 bellard
{
201 b346ff46 bellard
    regs->esp = infop->start_stack;
202 b346ff46 bellard
    regs->eip = infop->entry;
203 e5fe0c52 pbrook
204 e5fe0c52 pbrook
    /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
205 e5fe0c52 pbrook
       starts %edx contains a pointer to a function which might be
206 e5fe0c52 pbrook
       registered using `atexit'.  This provides a mean for the
207 e5fe0c52 pbrook
       dynamic linker to call DT_FINI functions for shared libraries
208 e5fe0c52 pbrook
       that have been loaded before the code runs.
209 e5fe0c52 pbrook

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