Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ cb33da57

History | View | Annotate | Download (40.4 kB)

1
/* This is the Linux kernel elf-loading code, ported into user space */
2

    
3
#include <stdio.h>
4
#include <sys/types.h>
5
#include <fcntl.h>
6
#include <errno.h>
7
#include <unistd.h>
8
#include <sys/mman.h>
9
#include <stdlib.h>
10
#include <string.h>
11

    
12
#include "qemu.h"
13
#include "disas.h"
14

    
15
/* from personality.h */
16

    
17
/*
18
 * Flags for bug emulation.
19
 *
20
 * These occupy the top three bytes.
21
 */
22
enum {
23
        ADDR_NO_RANDOMIZE =         0x0040000,        /* disable randomization of VA space */
24
        FDPIC_FUNCPTRS =        0x0080000,        /* userspace function ptrs point to descriptors
25
                                                 * (signal handling)
26
                                                 */
27
        MMAP_PAGE_ZERO =        0x0100000,
28
        ADDR_COMPAT_LAYOUT =        0x0200000,
29
        READ_IMPLIES_EXEC =        0x0400000,
30
        ADDR_LIMIT_32BIT =        0x0800000,
31
        SHORT_INODE =                0x1000000,
32
        WHOLE_SECONDS =                0x2000000,
33
        STICKY_TIMEOUTS        =        0x4000000,
34
        ADDR_LIMIT_3GB =         0x8000000,
35
};
36

    
37
/*
38
 * Personality types.
39
 *
40
 * These go in the low byte.  Avoid using the top bit, it will
41
 * conflict with error returns.
42
 */
43
enum {
44
        PER_LINUX =                0x0000,
45
        PER_LINUX_32BIT =        0x0000 | ADDR_LIMIT_32BIT,
46
        PER_LINUX_FDPIC =        0x0000 | FDPIC_FUNCPTRS,
47
        PER_SVR4 =                0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
48
        PER_SVR3 =                0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
49
        PER_SCOSVR3 =                0x0003 | STICKY_TIMEOUTS |
50
                                         WHOLE_SECONDS | SHORT_INODE,
51
        PER_OSR5 =                0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
52
        PER_WYSEV386 =                0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
53
        PER_ISCR4 =                0x0005 | STICKY_TIMEOUTS,
54
        PER_BSD =                0x0006,
55
        PER_SUNOS =                0x0006 | STICKY_TIMEOUTS,
56
        PER_XENIX =                0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
57
        PER_LINUX32 =                0x0008,
58
        PER_LINUX32_3GB =        0x0008 | ADDR_LIMIT_3GB,
59
        PER_IRIX32 =                0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
60
        PER_IRIXN32 =                0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
61
        PER_IRIX64 =                0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
62
        PER_RISCOS =                0x000c,
63
        PER_SOLARIS =                0x000d | STICKY_TIMEOUTS,
64
        PER_UW7 =                0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
65
        PER_OSF4 =                0x000f,                         /* OSF/1 v4 */
66
        PER_HPUX =                0x0010,
67
        PER_MASK =                0x00ff,
68
};
69

    
70
/*
71
 * Return the base personality without flags.
72
 */
73
#define personality(pers)        (pers & PER_MASK)
74

    
75
/* this flag is uneffective under linux too, should be deleted */
76
#ifndef MAP_DENYWRITE
77
#define MAP_DENYWRITE 0
78
#endif
79

    
80
/* should probably go in elf.h */
81
#ifndef ELIBBAD
82
#define ELIBBAD 80
83
#endif
84

    
85
#ifdef TARGET_I386
86

    
87
#define ELF_PLATFORM get_elf_platform()
88

    
89
static const char *get_elf_platform(void)
90
{
91
    static char elf_platform[] = "i386";
92
    int family = (global_env->cpuid_version >> 8) & 0xff;
93
    if (family > 6)
94
        family = 6;
95
    if (family >= 3)
96
        elf_platform[1] = '0' + family;
97
    return elf_platform;
98
}
99

    
100
#define ELF_HWCAP get_elf_hwcap()
101

    
102
static uint32_t get_elf_hwcap(void)
103
{
104
  return global_env->cpuid_features;
105
}
106

    
107
#ifdef TARGET_X86_64
108
#define ELF_START_MMAP 0x2aaaaab000ULL
109
#define elf_check_arch(x) ( ((x) == ELF_ARCH) )
110

    
111
#define ELF_CLASS      ELFCLASS64
112
#define ELF_DATA       ELFDATA2LSB
113
#define ELF_ARCH       EM_X86_64
114

    
115
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
116
{
117
    regs->rax = 0;
118
    regs->rsp = infop->start_stack;
119
    regs->rip = infop->entry;
120
}
121

    
122
#else
123

    
124
#define ELF_START_MMAP 0x80000000
125

    
126
/*
127
 * This is used to ensure we don't load something for the wrong architecture.
128
 */
129
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
130

    
131
/*
132
 * These are used to set parameters in the core dumps.
133
 */
134
#define ELF_CLASS        ELFCLASS32
135
#define ELF_DATA        ELFDATA2LSB
136
#define ELF_ARCH        EM_386
137

    
138
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
139
{
140
    regs->esp = infop->start_stack;
141
    regs->eip = infop->entry;
142

    
143
    /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
144
       starts %edx contains a pointer to a function which might be
145
       registered using `atexit'.  This provides a mean for the
146
       dynamic linker to call DT_FINI functions for shared libraries
147
       that have been loaded before the code runs.
148

149
       A value of 0 tells we have no such handler.  */
150
    regs->edx = 0;
151
}
152
#endif
153

    
154
#define USE_ELF_CORE_DUMP
155
#define ELF_EXEC_PAGESIZE        4096
156

    
157
#endif
158

    
159
#ifdef TARGET_ARM
160

    
161
#define ELF_START_MMAP 0x80000000
162

    
163
#define elf_check_arch(x) ( (x) == EM_ARM )
164

    
165
#define ELF_CLASS        ELFCLASS32
166
#ifdef TARGET_WORDS_BIGENDIAN
167
#define ELF_DATA        ELFDATA2MSB
168
#else
169
#define ELF_DATA        ELFDATA2LSB
170
#endif
171
#define ELF_ARCH        EM_ARM
172

    
173
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
174
{
175
    target_long stack = infop->start_stack;
176
    memset(regs, 0, sizeof(*regs));
177
    regs->ARM_cpsr = 0x10;
178
    if (infop->entry & 1)
179
      regs->ARM_cpsr |= CPSR_T;
180
    regs->ARM_pc = infop->entry & 0xfffffffe;
181
    regs->ARM_sp = infop->start_stack;
182
    regs->ARM_r2 = tgetl(stack + 8); /* envp */
183
    regs->ARM_r1 = tgetl(stack + 4); /* envp */
184
    /* XXX: it seems that r0 is zeroed after ! */
185
    regs->ARM_r0 = 0;
186
    /* For uClinux PIC binaries.  */
187
    /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
188
    regs->ARM_r10 = infop->start_data;
189
}
190

    
191
#define USE_ELF_CORE_DUMP
192
#define ELF_EXEC_PAGESIZE        4096
193

    
194
enum
195
{
196
  ARM_HWCAP_ARM_SWP       = 1 << 0,
197
  ARM_HWCAP_ARM_HALF      = 1 << 1,
198
  ARM_HWCAP_ARM_THUMB     = 1 << 2,
199
  ARM_HWCAP_ARM_26BIT     = 1 << 3,
200
  ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
201
  ARM_HWCAP_ARM_FPA       = 1 << 5,
202
  ARM_HWCAP_ARM_VFP       = 1 << 6,
203
  ARM_HWCAP_ARM_EDSP      = 1 << 7,
204
};
205

    
206
#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \
207
                    | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \
208
                    | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
209

    
210
#endif
211

    
212
#ifdef TARGET_SPARC
213
#ifdef TARGET_SPARC64
214

    
215
#define ELF_START_MMAP 0x80000000
216

    
217
#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
218

    
219
#define ELF_CLASS   ELFCLASS64
220
#define ELF_DATA    ELFDATA2MSB
221
#define ELF_ARCH    EM_SPARCV9
222

    
223
#define STACK_BIAS                2047
224

    
225
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
226
{
227
    regs->tstate = 0;
228
    regs->pc = infop->entry;
229
    regs->npc = regs->pc + 4;
230
    regs->y = 0;
231
    if (personality(infop->personality) == PER_LINUX32)
232
        regs->u_regs[14] = infop->start_stack - 16 * 4;
233
    else
234
        regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
235
}
236

    
237
#else
238
#define ELF_START_MMAP 0x80000000
239

    
240
#define elf_check_arch(x) ( (x) == EM_SPARC )
241

    
242
#define ELF_CLASS   ELFCLASS32
243
#define ELF_DATA    ELFDATA2MSB
244
#define ELF_ARCH    EM_SPARC
245

    
246
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
247
{
248
    regs->psr = 0;
249
    regs->pc = infop->entry;
250
    regs->npc = regs->pc + 4;
251
    regs->y = 0;
252
    regs->u_regs[14] = infop->start_stack - 16 * 4;
253
}
254

    
255
#endif
256
#endif
257

    
258
#ifdef TARGET_PPC
259

    
260
#define ELF_START_MMAP 0x80000000
261

    
262
#ifdef TARGET_PPC64
263

    
264
#define elf_check_arch(x) ( (x) == EM_PPC64 )
265

    
266
#define ELF_CLASS        ELFCLASS64
267

    
268
#else
269

    
270
#define elf_check_arch(x) ( (x) == EM_PPC )
271

    
272
#define ELF_CLASS        ELFCLASS32
273

    
274
#endif
275

    
276
#ifdef TARGET_WORDS_BIGENDIAN
277
#define ELF_DATA        ELFDATA2MSB
278
#else
279
#define ELF_DATA        ELFDATA2LSB
280
#endif
281
#define ELF_ARCH        EM_PPC
282

    
283
/*
284
 * We need to put in some extra aux table entries to tell glibc what
285
 * the cache block size is, so it can use the dcbz instruction safely.
286
 */
287
#define AT_DCACHEBSIZE          19
288
#define AT_ICACHEBSIZE          20
289
#define AT_UCACHEBSIZE          21
290
/* A special ignored type value for PPC, for glibc compatibility.  */
291
#define AT_IGNOREPPC            22
292
/*
293
 * The requirements here are:
294
 * - keep the final alignment of sp (sp & 0xf)
295
 * - make sure the 32-bit value at the first 16 byte aligned position of
296
 *   AUXV is greater than 16 for glibc compatibility.
297
 *   AT_IGNOREPPC is used for that.
298
 * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
299
 *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
300
 */
301
#define DLINFO_ARCH_ITEMS       5
302
#define ARCH_DLINFO                                                     \
303
do {                                                                    \
304
        NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \
305
        NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \
306
        NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \
307
        /*                                                              \
308
         * Now handle glibc compatibility.                              \
309
         */                                                             \
310
        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
311
        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
312
 } while (0)
313

    
314
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
315
{
316
    target_ulong pos = infop->start_stack;
317
    target_ulong tmp;
318
#ifdef TARGET_PPC64
319
    target_ulong entry, toc;
320
#endif
321

    
322
    _regs->msr = 1 << MSR_PR; /* Set user mode */
323
    _regs->gpr[1] = infop->start_stack;
324
#ifdef TARGET_PPC64
325
    entry = ldq_raw(infop->entry) + infop->load_addr;
326
    toc = ldq_raw(infop->entry + 8) + infop->load_addr;
327
    _regs->gpr[2] = toc;
328
    infop->entry = entry;
329
#endif
330
    _regs->nip = infop->entry;
331
    /* Note that isn't exactly what regular kernel does
332
     * but this is what the ABI wants and is needed to allow
333
     * execution of PPC BSD programs.
334
     */
335
    _regs->gpr[3] = tgetl(pos);
336
    pos += sizeof(target_ulong);
337
    _regs->gpr[4] = pos;
338
    for (tmp = 1; tmp != 0; pos += sizeof(target_ulong))
339
        tmp = ldl(pos);
340
    _regs->gpr[5] = pos;
341
}
342

    
343
#define USE_ELF_CORE_DUMP
344
#define ELF_EXEC_PAGESIZE        4096
345

    
346
#endif
347

    
348
#ifdef TARGET_MIPS
349

    
350
#define ELF_START_MMAP 0x80000000
351

    
352
#define elf_check_arch(x) ( (x) == EM_MIPS )
353

    
354
#ifdef TARGET_MIPS64
355
#define ELF_CLASS   ELFCLASS64
356
#else
357
#define ELF_CLASS   ELFCLASS32
358
#endif
359
#ifdef TARGET_WORDS_BIGENDIAN
360
#define ELF_DATA        ELFDATA2MSB
361
#else
362
#define ELF_DATA        ELFDATA2LSB
363
#endif
364
#define ELF_ARCH    EM_MIPS
365

    
366
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
367
{
368
    regs->cp0_status = CP0St_UM;
369
    regs->cp0_epc = infop->entry;
370
    regs->regs[29] = infop->start_stack;
371
}
372

    
373
#define USE_ELF_CORE_DUMP
374
#define ELF_EXEC_PAGESIZE        4096
375

    
376
#endif /* TARGET_MIPS */
377

    
378
#ifdef TARGET_SH4
379

    
380
#define ELF_START_MMAP 0x80000000
381

    
382
#define elf_check_arch(x) ( (x) == EM_SH )
383

    
384
#define ELF_CLASS ELFCLASS32
385
#define ELF_DATA  ELFDATA2LSB
386
#define ELF_ARCH  EM_SH
387

    
388
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
389
{
390
  /* Check other registers XXXXX */
391
  regs->pc = infop->entry;
392
  regs->regs[15] = infop->start_stack;
393
}
394

    
395
#define USE_ELF_CORE_DUMP
396
#define ELF_EXEC_PAGESIZE        4096
397

    
398
#endif
399

    
400
#ifdef TARGET_CRIS
401

    
402
#define ELF_START_MMAP 0x80000000
403

    
404
#define elf_check_arch(x) ( (x) == EM_CRIS )
405

    
406
#define ELF_CLASS ELFCLASS32
407
#define ELF_DATA  ELFDATA2LSB
408
#define ELF_ARCH  EM_CRIS
409

    
410
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
411
{
412
  regs->erp = infop->entry;
413
}
414

    
415
#define USE_ELF_CORE_DUMP
416
#define ELF_EXEC_PAGESIZE        8192
417

    
418
#endif
419

    
420
#ifdef TARGET_M68K
421

    
422
#define ELF_START_MMAP 0x80000000
423

    
424
#define elf_check_arch(x) ( (x) == EM_68K )
425

    
426
#define ELF_CLASS        ELFCLASS32
427
#define ELF_DATA        ELFDATA2MSB
428
#define ELF_ARCH        EM_68K
429

    
430
/* ??? Does this need to do anything?
431
#define ELF_PLAT_INIT(_r) */
432

    
433
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
434
{
435
    regs->usp = infop->start_stack;
436
    regs->sr = 0;
437
    regs->pc = infop->entry;
438
}
439

    
440
#define USE_ELF_CORE_DUMP
441
#define ELF_EXEC_PAGESIZE        8192
442

    
443
#endif
444

    
445
#ifdef TARGET_ALPHA
446

    
447
#define ELF_START_MMAP (0x30000000000ULL)
448

    
449
#define elf_check_arch(x) ( (x) == ELF_ARCH )
450

    
451
#define ELF_CLASS      ELFCLASS64
452
#define ELF_DATA       ELFDATA2MSB
453
#define ELF_ARCH       EM_ALPHA
454

    
455
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
456
{
457
    regs->pc = infop->entry;
458
    regs->ps = 8;
459
    regs->usp = infop->start_stack;
460
    regs->unique = infop->start_data; /* ? */
461
    printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",
462
           regs->unique, infop->start_data);
463
}
464

    
465
#define USE_ELF_CORE_DUMP
466
#define ELF_EXEC_PAGESIZE        8192
467

    
468
#endif /* TARGET_ALPHA */
469

    
470
#ifndef ELF_PLATFORM
471
#define ELF_PLATFORM (NULL)
472
#endif
473

    
474
#ifndef ELF_HWCAP
475
#define ELF_HWCAP 0
476
#endif
477

    
478
#ifdef OVERRIDE_ELF_CLASS
479
#undef ELF_CLASS
480
#define ELF_CLASS OVERRIDE_ELF_CLASS
481
#undef bswaptls
482
#define bswaptls(ptr) bswap32s(ptr)
483
#endif
484

    
485
#include "elf.h"
486

    
487
struct exec
488
{
489
  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
490
  unsigned int a_text;   /* length of text, in bytes */
491
  unsigned int a_data;   /* length of data, in bytes */
492
  unsigned int a_bss;    /* length of uninitialized data area, in bytes */
493
  unsigned int a_syms;   /* length of symbol table data in file, in bytes */
494
  unsigned int a_entry;  /* start address */
495
  unsigned int a_trsize; /* length of relocation info for text, in bytes */
496
  unsigned int a_drsize; /* length of relocation info for data, in bytes */
497
};
498

    
499

    
500
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
501
#define OMAGIC 0407
502
#define NMAGIC 0410
503
#define ZMAGIC 0413
504
#define QMAGIC 0314
505

    
506
/* max code+data+bss space allocated to elf interpreter */
507
#define INTERP_MAP_SIZE (32 * 1024 * 1024)
508

    
509
/* max code+data+bss+brk space allocated to ET_DYN executables */
510
#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
511

    
512
/* Necessary parameters */
513
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
514
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
515
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
516

    
517
#define INTERPRETER_NONE 0
518
#define INTERPRETER_AOUT 1
519
#define INTERPRETER_ELF 2
520

    
521
#define DLINFO_ITEMS 12
522

    
523
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
524
{
525
        memcpy(to, from, n);
526
}
527

    
528
extern unsigned long x86_stack_size;
529

    
530
static int load_aout_interp(void * exptr, int interp_fd);
531

    
532
#ifdef BSWAP_NEEDED
533
static void bswap_ehdr(struct elfhdr *ehdr)
534
{
535
    bswap16s(&ehdr->e_type);                        /* Object file type */
536
    bswap16s(&ehdr->e_machine);                /* Architecture */
537
    bswap32s(&ehdr->e_version);                /* Object file version */
538
    bswaptls(&ehdr->e_entry);                /* Entry point virtual address */
539
    bswaptls(&ehdr->e_phoff);                /* Program header table file offset */
540
    bswaptls(&ehdr->e_shoff);                /* Section header table file offset */
541
    bswap32s(&ehdr->e_flags);                /* Processor-specific flags */
542
    bswap16s(&ehdr->e_ehsize);                /* ELF header size in bytes */
543
    bswap16s(&ehdr->e_phentsize);                /* Program header table entry size */
544
    bswap16s(&ehdr->e_phnum);                /* Program header table entry count */
545
    bswap16s(&ehdr->e_shentsize);                /* Section header table entry size */
546
    bswap16s(&ehdr->e_shnum);                /* Section header table entry count */
547
    bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */
548
}
549

    
550
static void bswap_phdr(struct elf_phdr *phdr)
551
{
552
    bswap32s(&phdr->p_type);                        /* Segment type */
553
    bswaptls(&phdr->p_offset);                /* Segment file offset */
554
    bswaptls(&phdr->p_vaddr);                /* Segment virtual address */
555
    bswaptls(&phdr->p_paddr);                /* Segment physical address */
556
    bswaptls(&phdr->p_filesz);                /* Segment size in file */
557
    bswaptls(&phdr->p_memsz);                /* Segment size in memory */
558
    bswap32s(&phdr->p_flags);                /* Segment flags */
559
    bswaptls(&phdr->p_align);                /* Segment alignment */
560
}
561

    
562
static void bswap_shdr(struct elf_shdr *shdr)
563
{
564
    bswap32s(&shdr->sh_name);
565
    bswap32s(&shdr->sh_type);
566
    bswaptls(&shdr->sh_flags);
567
    bswaptls(&shdr->sh_addr);
568
    bswaptls(&shdr->sh_offset);
569
    bswaptls(&shdr->sh_size);
570
    bswap32s(&shdr->sh_link);
571
    bswap32s(&shdr->sh_info);
572
    bswaptls(&shdr->sh_addralign);
573
    bswaptls(&shdr->sh_entsize);
574
}
575

    
576
static void bswap_sym(struct elf_sym *sym)
577
{
578
    bswap32s(&sym->st_name);
579
    bswaptls(&sym->st_value);
580
    bswaptls(&sym->st_size);
581
    bswap16s(&sym->st_shndx);
582
}
583
#endif
584

    
585
/*
586
 * 'copy_elf_strings()' copies argument/envelope strings from user
587
 * memory to free pages in kernel mem. These are in a format ready
588
 * to be put directly into the top of new user memory.
589
 *
590
 */
591
static target_ulong copy_elf_strings(int argc,char ** argv, void **page,
592
                                     target_ulong p)
593
{
594
    char *tmp, *tmp1, *pag = NULL;
595
    int len, offset = 0;
596

    
597
    if (!p) {
598
        return 0;       /* bullet-proofing */
599
    }
600
    while (argc-- > 0) {
601
        tmp = argv[argc];
602
        if (!tmp) {
603
            fprintf(stderr, "VFS: argc is wrong");
604
            exit(-1);
605
        }
606
        tmp1 = tmp;
607
        while (*tmp++);
608
        len = tmp - tmp1;
609
        if (p < len) {  /* this shouldn't happen - 128kB */
610
                return 0;
611
        }
612
        while (len) {
613
            --p; --tmp; --len;
614
            if (--offset < 0) {
615
                offset = p % TARGET_PAGE_SIZE;
616
                pag = (char *)page[p/TARGET_PAGE_SIZE];
617
                if (!pag) {
618
                    pag = (char *)malloc(TARGET_PAGE_SIZE);
619
                    memset(pag, 0, TARGET_PAGE_SIZE);
620
                    page[p/TARGET_PAGE_SIZE] = pag;
621
                    if (!pag)
622
                        return 0;
623
                }
624
            }
625
            if (len == 0 || offset == 0) {
626
                *(pag + offset) = *tmp;
627
            }
628
            else {
629
              int bytes_to_copy = (len > offset) ? offset : len;
630
              tmp -= bytes_to_copy;
631
              p -= bytes_to_copy;
632
              offset -= bytes_to_copy;
633
              len -= bytes_to_copy;
634
              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
635
            }
636
        }
637
    }
638
    return p;
639
}
640

    
641
static target_ulong setup_arg_pages(target_ulong p, struct linux_binprm *bprm,
642
                                    struct image_info *info)
643
{
644
    target_ulong stack_base, size, error;
645
    int i;
646

    
647
    /* Create enough stack to hold everything.  If we don't use
648
     * it for args, we'll use it for something else...
649
     */
650
    size = x86_stack_size;
651
    if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
652
        size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
653
    error = target_mmap(0,
654
                        size + qemu_host_page_size,
655
                        PROT_READ | PROT_WRITE,
656
                        MAP_PRIVATE | MAP_ANONYMOUS,
657
                        -1, 0);
658
    if (error == -1) {
659
        perror("stk mmap");
660
        exit(-1);
661
    }
662
    /* we reserve one extra page at the top of the stack as guard */
663
    target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
664

    
665
    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
666
    p += stack_base;
667

    
668
    for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
669
        if (bprm->page[i]) {
670
            info->rss++;
671

    
672
            memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
673
            free(bprm->page[i]);
674
        }
675
        stack_base += TARGET_PAGE_SIZE;
676
    }
677
    return p;
678
}
679

    
680
static void set_brk(target_ulong start, target_ulong end)
681
{
682
        /* page-align the start and end addresses... */
683
        start = HOST_PAGE_ALIGN(start);
684
        end = HOST_PAGE_ALIGN(end);
685
        if (end <= start)
686
                return;
687
        if(target_mmap(start, end - start,
688
                       PROT_READ | PROT_WRITE | PROT_EXEC,
689
                       MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
690
            perror("cannot mmap brk");
691
            exit(-1);
692
        }
693
}
694

    
695

    
696
/* We need to explicitly zero any fractional pages after the data
697
   section (i.e. bss).  This would contain the junk from the file that
698
   should not be in memory. */
699
static void padzero(target_ulong elf_bss, target_ulong last_bss)
700
{
701
        target_ulong nbyte;
702

    
703
        if (elf_bss >= last_bss)
704
                return;
705

    
706
        /* XXX: this is really a hack : if the real host page size is
707
           smaller than the target page size, some pages after the end
708
           of the file may not be mapped. A better fix would be to
709
           patch target_mmap(), but it is more complicated as the file
710
           size must be known */
711
        if (qemu_real_host_page_size < qemu_host_page_size) {
712
            target_ulong end_addr, end_addr1;
713
            end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
714
                ~(qemu_real_host_page_size - 1);
715
            end_addr = HOST_PAGE_ALIGN(elf_bss);
716
            if (end_addr1 < end_addr) {
717
                mmap((void *)g2h(end_addr1), end_addr - end_addr1,
718
                     PROT_READ|PROT_WRITE|PROT_EXEC,
719
                     MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
720
            }
721
        }
722

    
723
        nbyte = elf_bss & (qemu_host_page_size-1);
724
        if (nbyte) {
725
            nbyte = qemu_host_page_size - nbyte;
726
            do {
727
                tput8(elf_bss, 0);
728
                elf_bss++;
729
            } while (--nbyte);
730
        }
731
}
732

    
733

    
734
static target_ulong create_elf_tables(target_ulong p, int argc, int envc,
735
                                      struct elfhdr * exec,
736
                                      target_ulong load_addr,
737
                                      target_ulong load_bias,
738
                                      target_ulong interp_load_addr, int ibcs,
739
                                      struct image_info *info)
740
{
741
        target_ulong sp;
742
        int size;
743
        target_ulong u_platform;
744
        const char *k_platform;
745
        const int n = sizeof(elf_addr_t);
746

    
747
        sp = p;
748
        u_platform = 0;
749
        k_platform = ELF_PLATFORM;
750
        if (k_platform) {
751
            size_t len = strlen(k_platform) + 1;
752
            sp -= (len + n - 1) & ~(n - 1);
753
            u_platform = sp;
754
            memcpy_to_target(sp, k_platform, len);
755
        }
756
        /*
757
         * Force 16 byte _final_ alignment here for generality.
758
         */
759
        sp = sp &~ (target_ulong)15;
760
        size = (DLINFO_ITEMS + 1) * 2;
761
        if (k_platform)
762
          size += 2;
763
#ifdef DLINFO_ARCH_ITEMS
764
        size += DLINFO_ARCH_ITEMS * 2;
765
#endif
766
        size += envc + argc + 2;
767
        size += (!ibcs ? 3 : 1);        /* argc itself */
768
        size *= n;
769
        if (size & 15)
770
            sp -= 16 - (size & 15);
771

    
772
        /* This is correct because Linux defines
773
         * elf_addr_t as Elf32_Off / Elf64_Off
774
         */
775
#if ELF_CLASS == ELFCLASS32
776
#define NEW_AUX_ENT(id, val) do { \
777
            sp -= n; tput32(sp, val); \
778
            sp -= n; tput32(sp, id); \
779
          } while(0)
780
#else
781
#define NEW_AUX_ENT(id, val) do { \
782
            sp -= n; tput64(sp, val); \
783
            sp -= n; tput64(sp, id); \
784
          } while(0)
785
#endif
786
        NEW_AUX_ENT (AT_NULL, 0);
787

    
788
        /* There must be exactly DLINFO_ITEMS entries here.  */
789
        NEW_AUX_ENT(AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
790
        NEW_AUX_ENT(AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
791
        NEW_AUX_ENT(AT_PHNUM, (target_ulong)(exec->e_phnum));
792
        NEW_AUX_ENT(AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
793
        NEW_AUX_ENT(AT_BASE, (target_ulong)(interp_load_addr));
794
        NEW_AUX_ENT(AT_FLAGS, (target_ulong)0);
795
        NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
796
        NEW_AUX_ENT(AT_UID, (target_ulong) getuid());
797
        NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid());
798
        NEW_AUX_ENT(AT_GID, (target_ulong) getgid());
799
        NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
800
        NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
801
        if (k_platform)
802
            NEW_AUX_ENT(AT_PLATFORM, u_platform);
803
#ifdef ARCH_DLINFO
804
        /*
805
         * ARCH_DLINFO must come last so platform specific code can enforce
806
         * special alignment requirements on the AUXV if necessary (eg. PPC).
807
         */
808
        ARCH_DLINFO;
809
#endif
810
#undef NEW_AUX_ENT
811

    
812
        sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
813
        return sp;
814
}
815

    
816

    
817
static target_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
818
                                    int interpreter_fd,
819
                                    target_ulong *interp_load_addr)
820
{
821
        struct elf_phdr *elf_phdata  =  NULL;
822
        struct elf_phdr *eppnt;
823
        target_ulong load_addr = 0;
824
        int load_addr_set = 0;
825
        int retval;
826
        target_ulong last_bss, elf_bss;
827
        target_ulong error;
828
        int i;
829

    
830
        elf_bss = 0;
831
        last_bss = 0;
832
        error = 0;
833

    
834
#ifdef BSWAP_NEEDED
835
        bswap_ehdr(interp_elf_ex);
836
#endif
837
        /* First of all, some simple consistency checks */
838
        if ((interp_elf_ex->e_type != ET_EXEC &&
839
             interp_elf_ex->e_type != ET_DYN) ||
840
           !elf_check_arch(interp_elf_ex->e_machine)) {
841
                return ~((target_ulong)0UL);
842
        }
843

    
844

    
845
        /* Now read in all of the header information */
846

    
847
        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
848
            return ~(target_ulong)0UL;
849

    
850
        elf_phdata =  (struct elf_phdr *)
851
                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
852

    
853
        if (!elf_phdata)
854
          return ~((target_ulong)0UL);
855

    
856
        /*
857
         * If the size of this structure has changed, then punt, since
858
         * we will be doing the wrong thing.
859
         */
860
        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
861
            free(elf_phdata);
862
            return ~((target_ulong)0UL);
863
        }
864

    
865
        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
866
        if(retval >= 0) {
867
            retval = read(interpreter_fd,
868
                           (char *) elf_phdata,
869
                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
870
        }
871
        if (retval < 0) {
872
                perror("load_elf_interp");
873
                exit(-1);
874
                free (elf_phdata);
875
                return retval;
876
         }
877
#ifdef BSWAP_NEEDED
878
        eppnt = elf_phdata;
879
        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
880
            bswap_phdr(eppnt);
881
        }
882
#endif
883

    
884
        if (interp_elf_ex->e_type == ET_DYN) {
885
            /* in order to avoid hardcoding the interpreter load
886
               address in qemu, we allocate a big enough memory zone */
887
            error = target_mmap(0, INTERP_MAP_SIZE,
888
                                PROT_NONE, MAP_PRIVATE | MAP_ANON,
889
                                -1, 0);
890
            if (error == -1) {
891
                perror("mmap");
892
                exit(-1);
893
            }
894
            load_addr = error;
895
            load_addr_set = 1;
896
        }
897

    
898
        eppnt = elf_phdata;
899
        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
900
          if (eppnt->p_type == PT_LOAD) {
901
            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
902
            int elf_prot = 0;
903
            target_ulong vaddr = 0;
904
            target_ulong k;
905

    
906
            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
907
            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
908
            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
909
            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
910
                    elf_type |= MAP_FIXED;
911
                    vaddr = eppnt->p_vaddr;
912
            }
913
            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
914
                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
915
                 elf_prot,
916
                 elf_type,
917
                 interpreter_fd,
918
                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
919

    
920
            if (error == -1) {
921
              /* Real error */
922
              close(interpreter_fd);
923
              free(elf_phdata);
924
              return ~((target_ulong)0UL);
925
            }
926

    
927
            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
928
              load_addr = error;
929
              load_addr_set = 1;
930
            }
931

    
932
            /*
933
             * Find the end of the file  mapping for this phdr, and keep
934
             * track of the largest address we see for this.
935
             */
936
            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
937
            if (k > elf_bss) elf_bss = k;
938

    
939
            /*
940
             * Do the same thing for the memory mapping - between
941
             * elf_bss and last_bss is the bss section.
942
             */
943
            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
944
            if (k > last_bss) last_bss = k;
945
          }
946

    
947
        /* Now use mmap to map the library into memory. */
948

    
949
        close(interpreter_fd);
950

    
951
        /*
952
         * Now fill out the bss section.  First pad the last page up
953
         * to the page boundary, and then perform a mmap to make sure
954
         * that there are zeromapped pages up to and including the last
955
         * bss page.
956
         */
957
        padzero(elf_bss, last_bss);
958
        elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
959

    
960
        /* Map the last of the bss segment */
961
        if (last_bss > elf_bss) {
962
            target_mmap(elf_bss, last_bss-elf_bss,
963
                        PROT_READ|PROT_WRITE|PROT_EXEC,
964
                        MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
965
        }
966
        free(elf_phdata);
967

    
968
        *interp_load_addr = load_addr;
969
        return ((target_ulong) interp_elf_ex->e_entry) + load_addr;
970
}
971

    
972
/* Best attempt to load symbols from this ELF object. */
973
static void load_symbols(struct elfhdr *hdr, int fd)
974
{
975
    unsigned int i;
976
    struct elf_shdr sechdr, symtab, strtab;
977
    char *strings;
978
    struct syminfo *s;
979
#if (ELF_CLASS == ELFCLASS64)
980
    // Disas uses 32 bit symbols
981
    struct elf32_sym *syms32 = NULL;
982
    struct elf_sym *sym;
983
#endif
984

    
985
    lseek(fd, hdr->e_shoff, SEEK_SET);
986
    for (i = 0; i < hdr->e_shnum; i++) {
987
        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
988
            return;
989
#ifdef BSWAP_NEEDED
990
        bswap_shdr(&sechdr);
991
#endif
992
        if (sechdr.sh_type == SHT_SYMTAB) {
993
            symtab = sechdr;
994
            lseek(fd, hdr->e_shoff
995
                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
996
            if (read(fd, &strtab, sizeof(strtab))
997
                != sizeof(strtab))
998
                return;
999
#ifdef BSWAP_NEEDED
1000
            bswap_shdr(&strtab);
1001
#endif
1002
            goto found;
1003
        }
1004
    }
1005
    return; /* Shouldn't happen... */
1006

    
1007
 found:
1008
    /* Now know where the strtab and symtab are.  Snarf them. */
1009
    s = malloc(sizeof(*s));
1010
    s->disas_symtab = malloc(symtab.sh_size);
1011
#if (ELF_CLASS == ELFCLASS64)
1012
    syms32 = malloc(symtab.sh_size / sizeof(struct elf_sym)
1013
                    * sizeof(struct elf32_sym));
1014
#endif
1015
    s->disas_strtab = strings = malloc(strtab.sh_size);
1016
    if (!s->disas_symtab || !s->disas_strtab)
1017
        return;
1018

    
1019
    lseek(fd, symtab.sh_offset, SEEK_SET);
1020
    if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
1021
        return;
1022

    
1023
    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) {
1024
#ifdef BSWAP_NEEDED
1025
        bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
1026
#endif
1027
#if (ELF_CLASS == ELFCLASS64)
1028
        sym = s->disas_symtab + sizeof(struct elf_sym)*i;
1029
        syms32[i].st_name = sym->st_name;
1030
        syms32[i].st_info = sym->st_info;
1031
        syms32[i].st_other = sym->st_other;
1032
        syms32[i].st_shndx = sym->st_shndx;
1033
        syms32[i].st_value = sym->st_value & 0xffffffff;
1034
        syms32[i].st_size = sym->st_size & 0xffffffff;
1035
#endif
1036
    }
1037

    
1038
#if (ELF_CLASS == ELFCLASS64)
1039
    free(s->disas_symtab);
1040
    s->disas_symtab = syms32;
1041
#endif
1042
    lseek(fd, strtab.sh_offset, SEEK_SET);
1043
    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
1044
        return;
1045
    s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
1046
    s->next = syminfos;
1047
    syminfos = s;
1048
}
1049

    
1050
int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1051
                    struct image_info * info)
1052
{
1053
    struct elfhdr elf_ex;
1054
    struct elfhdr interp_elf_ex;
1055
    struct exec interp_ex;
1056
    int interpreter_fd = -1; /* avoid warning */
1057
    target_ulong load_addr, load_bias;
1058
    int load_addr_set = 0;
1059
    unsigned int interpreter_type = INTERPRETER_NONE;
1060
    unsigned char ibcs2_interpreter;
1061
    int i;
1062
    target_ulong mapped_addr;
1063
    struct elf_phdr * elf_ppnt;
1064
    struct elf_phdr *elf_phdata;
1065
    target_ulong elf_bss, k, elf_brk;
1066
    int retval;
1067
    char * elf_interpreter;
1068
    target_ulong elf_entry, interp_load_addr = 0;
1069
    int status;
1070
    target_ulong start_code, end_code, start_data, end_data;
1071
    target_ulong reloc_func_desc = 0;
1072
    target_ulong elf_stack;
1073
    char passed_fileno[6];
1074

    
1075
    ibcs2_interpreter = 0;
1076
    status = 0;
1077
    load_addr = 0;
1078
    load_bias = 0;
1079
    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
1080
#ifdef BSWAP_NEEDED
1081
    bswap_ehdr(&elf_ex);
1082
#endif
1083

    
1084
    /* First of all, some simple consistency checks */
1085
    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
1086
                                       (! elf_check_arch(elf_ex.e_machine))) {
1087
            return -ENOEXEC;
1088
    }
1089

    
1090
    bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
1091
    bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
1092
    bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
1093
    if (!bprm->p) {
1094
        retval = -E2BIG;
1095
    }
1096

    
1097
    /* Now read in all of the header information */
1098
    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
1099
    if (elf_phdata == NULL) {
1100
        return -ENOMEM;
1101
    }
1102

    
1103
    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
1104
    if(retval > 0) {
1105
        retval = read(bprm->fd, (char *) elf_phdata,
1106
                                elf_ex.e_phentsize * elf_ex.e_phnum);
1107
    }
1108

    
1109
    if (retval < 0) {
1110
        perror("load_elf_binary");
1111
        exit(-1);
1112
        free (elf_phdata);
1113
        return -errno;
1114
    }
1115

    
1116
#ifdef BSWAP_NEEDED
1117
    elf_ppnt = elf_phdata;
1118
    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
1119
        bswap_phdr(elf_ppnt);
1120
    }
1121
#endif
1122
    elf_ppnt = elf_phdata;
1123

    
1124
    elf_bss = 0;
1125
    elf_brk = 0;
1126

    
1127

    
1128
    elf_stack = ~((target_ulong)0UL);
1129
    elf_interpreter = NULL;
1130
    start_code = ~((target_ulong)0UL);
1131
    end_code = 0;
1132
    start_data = 0;
1133
    end_data = 0;
1134

    
1135
    for(i=0;i < elf_ex.e_phnum; i++) {
1136
        if (elf_ppnt->p_type == PT_INTERP) {
1137
            if ( elf_interpreter != NULL )
1138
            {
1139
                free (elf_phdata);
1140
                free(elf_interpreter);
1141
                close(bprm->fd);
1142
                return -EINVAL;
1143
            }
1144

    
1145
            /* This is the program interpreter used for
1146
             * shared libraries - for now assume that this
1147
             * is an a.out format binary
1148
             */
1149

    
1150
            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
1151

    
1152
            if (elf_interpreter == NULL) {
1153
                free (elf_phdata);
1154
                close(bprm->fd);
1155
                return -ENOMEM;
1156
            }
1157

    
1158
            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
1159
            if(retval >= 0) {
1160
                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
1161
            }
1162
            if(retval < 0) {
1163
                 perror("load_elf_binary2");
1164
                exit(-1);
1165
            }
1166

    
1167
            /* If the program interpreter is one of these two,
1168
               then assume an iBCS2 image. Otherwise assume
1169
               a native linux image. */
1170

    
1171
            /* JRP - Need to add X86 lib dir stuff here... */
1172

    
1173
            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
1174
                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
1175
              ibcs2_interpreter = 1;
1176
            }
1177

    
1178
#if 0
1179
            printf("Using ELF interpreter %s\n", elf_interpreter);
1180
#endif
1181
            if (retval >= 0) {
1182
                retval = open(path(elf_interpreter), O_RDONLY);
1183
                if(retval >= 0) {
1184
                    interpreter_fd = retval;
1185
                }
1186
                else {
1187
                    perror(elf_interpreter);
1188
                    exit(-1);
1189
                    /* retval = -errno; */
1190
                }
1191
            }
1192

    
1193
            if (retval >= 0) {
1194
                retval = lseek(interpreter_fd, 0, SEEK_SET);
1195
                if(retval >= 0) {
1196
                    retval = read(interpreter_fd,bprm->buf,128);
1197
                }
1198
            }
1199
            if (retval >= 0) {
1200
                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
1201
                interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
1202
            }
1203
            if (retval < 0) {
1204
                perror("load_elf_binary3");
1205
                exit(-1);
1206
                free (elf_phdata);
1207
                free(elf_interpreter);
1208
                close(bprm->fd);
1209
                return retval;
1210
            }
1211
        }
1212
        elf_ppnt++;
1213
    }
1214

    
1215
    /* Some simple consistency checks for the interpreter */
1216
    if (elf_interpreter){
1217
        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1218

    
1219
        /* Now figure out which format our binary is */
1220
        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
1221
                    (N_MAGIC(interp_ex) != QMAGIC)) {
1222
          interpreter_type = INTERPRETER_ELF;
1223
        }
1224

    
1225
        if (interp_elf_ex.e_ident[0] != 0x7f ||
1226
                    strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1227
            interpreter_type &= ~INTERPRETER_ELF;
1228
        }
1229

    
1230
        if (!interpreter_type) {
1231
            free(elf_interpreter);
1232
            free(elf_phdata);
1233
            close(bprm->fd);
1234
            return -ELIBBAD;
1235
        }
1236
    }
1237

    
1238
    /* OK, we are done with that, now set up the arg stuff,
1239
       and then start this sucker up */
1240

    
1241
    {
1242
        char * passed_p;
1243

    
1244
        if (interpreter_type == INTERPRETER_AOUT) {
1245
            snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
1246
            passed_p = passed_fileno;
1247

    
1248
            if (elf_interpreter) {
1249
                bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);
1250
                bprm->argc++;
1251
            }
1252
        }
1253
        if (!bprm->p) {
1254
            if (elf_interpreter) {
1255
                free(elf_interpreter);
1256
            }
1257
            free (elf_phdata);
1258
            close(bprm->fd);
1259
            return -E2BIG;
1260
        }
1261
    }
1262

    
1263
    /* OK, This is the point of no return */
1264
    info->end_data = 0;
1265
    info->end_code = 0;
1266
    info->start_mmap = (target_ulong)ELF_START_MMAP;
1267
    info->mmap = 0;
1268
    elf_entry = (target_ulong) elf_ex.e_entry;
1269

    
1270
    /* Do this so that we can load the interpreter, if need be.  We will
1271
       change some of these later */
1272
    info->rss = 0;
1273
    bprm->p = setup_arg_pages(bprm->p, bprm, info);
1274
    info->start_stack = bprm->p;
1275

    
1276
    /* Now we do a little grungy work by mmaping the ELF image into
1277
     * the correct location in memory.  At this point, we assume that
1278
     * the image should be loaded at fixed address, not at a variable
1279
     * address.
1280
     */
1281

    
1282
    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1283
        int elf_prot = 0;
1284
        int elf_flags = 0;
1285
        target_ulong error;
1286

    
1287
        if (elf_ppnt->p_type != PT_LOAD)
1288
            continue;
1289

    
1290
        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
1291
        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
1292
        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
1293
        elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
1294
        if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1295
            elf_flags |= MAP_FIXED;
1296
        } else if (elf_ex.e_type == ET_DYN) {
1297
            /* Try and get dynamic programs out of the way of the default mmap
1298
               base, as well as whatever program they might try to exec.  This
1299
               is because the brk will follow the loader, and is not movable.  */
1300
            /* NOTE: for qemu, we do a big mmap to get enough space
1301
               without hardcoding any address */
1302
            error = target_mmap(0, ET_DYN_MAP_SIZE,
1303
                                PROT_NONE, MAP_PRIVATE | MAP_ANON,
1304
                                -1, 0);
1305
            if (error == -1) {
1306
                perror("mmap");
1307
                exit(-1);
1308
            }
1309
            load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
1310
        }
1311

    
1312
        error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
1313
                            (elf_ppnt->p_filesz +
1314
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
1315
                            elf_prot,
1316
                            (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
1317
                            bprm->fd,
1318
                            (elf_ppnt->p_offset -
1319
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
1320
        if (error == -1) {
1321
            perror("mmap");
1322
            exit(-1);
1323
        }
1324

    
1325
#ifdef LOW_ELF_STACK
1326
        if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1327
            elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
1328
#endif
1329

    
1330
        if (!load_addr_set) {
1331
            load_addr_set = 1;
1332
            load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1333
            if (elf_ex.e_type == ET_DYN) {
1334
                load_bias += error -
1335
                    TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
1336
                load_addr += load_bias;
1337
                reloc_func_desc = load_bias;
1338
            }
1339
        }
1340
        k = elf_ppnt->p_vaddr;
1341
        if (k < start_code)
1342
            start_code = k;
1343
        if (start_data < k)
1344
            start_data = k;
1345
        k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1346
        if (k > elf_bss)
1347
            elf_bss = k;
1348
        if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
1349
            end_code = k;
1350
        if (end_data < k)
1351
            end_data = k;
1352
        k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1353
        if (k > elf_brk) elf_brk = k;
1354
    }
1355

    
1356
    elf_entry += load_bias;
1357
    elf_bss += load_bias;
1358
    elf_brk += load_bias;
1359
    start_code += load_bias;
1360
    end_code += load_bias;
1361
    start_data += load_bias;
1362
    end_data += load_bias;
1363

    
1364
    if (elf_interpreter) {
1365
        if (interpreter_type & 1) {
1366
            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1367
        }
1368
        else if (interpreter_type & 2) {
1369
            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1370
                                            &interp_load_addr);
1371
        }
1372
        reloc_func_desc = interp_load_addr;
1373

    
1374
        close(interpreter_fd);
1375
        free(elf_interpreter);
1376

    
1377
        if (elf_entry == ~((target_ulong)0UL)) {
1378
            printf("Unable to load interpreter\n");
1379
            free(elf_phdata);
1380
            exit(-1);
1381
            return 0;
1382
        }
1383
    }
1384

    
1385
    free(elf_phdata);
1386

    
1387
    if (loglevel)
1388
        load_symbols(&elf_ex, bprm->fd);
1389

    
1390
    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1391
    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1392

    
1393
#ifdef LOW_ELF_STACK
1394
    info->start_stack = bprm->p = elf_stack - 4;
1395
#endif
1396
    bprm->p = create_elf_tables(bprm->p,
1397
                    bprm->argc,
1398
                    bprm->envc,
1399
                    &elf_ex,
1400
                    load_addr, load_bias,
1401
                    interp_load_addr,
1402
                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1403
                    info);
1404
    info->load_addr = reloc_func_desc;
1405
    info->start_brk = info->brk = elf_brk;
1406
    info->end_code = end_code;
1407
    info->start_code = start_code;
1408
    info->start_data = start_data;
1409
    info->end_data = end_data;
1410
    info->start_stack = bprm->p;
1411

    
1412
    /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1413
       sections */
1414
    set_brk(elf_bss, elf_brk);
1415

    
1416
    padzero(elf_bss, elf_brk);
1417

    
1418
#if 0
1419
    printf("(start_brk) %x\n" , info->start_brk);
1420
    printf("(end_code) %x\n" , info->end_code);
1421
    printf("(start_code) %x\n" , info->start_code);
1422
    printf("(end_data) %x\n" , info->end_data);
1423
    printf("(start_stack) %x\n" , info->start_stack);
1424
    printf("(brk) %x\n" , info->brk);
1425
#endif
1426

    
1427
    if ( info->personality == PER_SVR4 )
1428
    {
1429
            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1430
               and some applications "depend" upon this behavior.
1431
               Since we do not have the power to recompile these, we
1432
               emulate the SVr4 behavior.  Sigh.  */
1433
            mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
1434
                                      MAP_FIXED | MAP_PRIVATE, -1, 0);
1435
    }
1436

    
1437
    info->entry = elf_entry;
1438

    
1439
    return 0;
1440
}
1441

    
1442
static int load_aout_interp(void * exptr, int interp_fd)
1443
{
1444
    printf("a.out interpreter not yet supported\n");
1445
    return(0);
1446
}
1447

    
1448
void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
1449
{
1450
    init_thread(regs, infop);
1451
}