Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ e6e5906b

History | View | Annotate | Download (35.6 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
/* this flag is uneffective under linux too, should be deleted */
16
#ifndef MAP_DENYWRITE
17
#define MAP_DENYWRITE 0
18
#endif
19

    
20
/* should probably go in elf.h */
21
#ifndef ELIBBAD
22
#define ELIBBAD 80
23
#endif
24

    
25
#ifdef TARGET_I386
26

    
27
#define ELF_PLATFORM get_elf_platform()
28

    
29
static const char *get_elf_platform(void)
30
{
31
    static char elf_platform[] = "i386";
32
    int family = (global_env->cpuid_version >> 8) & 0xff;
33
    if (family > 6)
34
        family = 6;
35
    if (family >= 3)
36
        elf_platform[1] = '0' + family;
37
    return elf_platform;
38
}
39

    
40
#define ELF_HWCAP get_elf_hwcap()
41

    
42
static uint32_t get_elf_hwcap(void)
43
{
44
  return global_env->cpuid_features;
45
}
46

    
47
#define ELF_START_MMAP 0x80000000
48

    
49
/*
50
 * This is used to ensure we don't load something for the wrong architecture.
51
 */
52
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
53

    
54
/*
55
 * These are used to set parameters in the core dumps.
56
 */
57
#define ELF_CLASS        ELFCLASS32
58
#define ELF_DATA        ELFDATA2LSB
59
#define ELF_ARCH        EM_386
60

    
61
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
62
{
63
    regs->esp = infop->start_stack;
64
    regs->eip = infop->entry;
65

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

72
       A value of 0 tells we have no such handler.  */
73
    regs->edx = 0;
74
}
75

    
76
#define USE_ELF_CORE_DUMP
77
#define ELF_EXEC_PAGESIZE        4096
78

    
79
#endif
80

    
81
#ifdef TARGET_ARM
82

    
83
#define ELF_START_MMAP 0x80000000
84

    
85
#define elf_check_arch(x) ( (x) == EM_ARM )
86

    
87
#define ELF_CLASS        ELFCLASS32
88
#ifdef TARGET_WORDS_BIGENDIAN
89
#define ELF_DATA        ELFDATA2MSB
90
#else
91
#define ELF_DATA        ELFDATA2LSB
92
#endif
93
#define ELF_ARCH        EM_ARM
94

    
95
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
96
{
97
    target_long stack = infop->start_stack;
98
    memset(regs, 0, sizeof(*regs));
99
    regs->ARM_cpsr = 0x10;
100
    if (infop->entry & 1)
101
      regs->ARM_cpsr |= CPSR_T;
102
    regs->ARM_pc = infop->entry & 0xfffffffe;
103
    regs->ARM_sp = infop->start_stack;
104
    regs->ARM_r2 = tgetl(stack + 8); /* envp */
105
    regs->ARM_r1 = tgetl(stack + 4); /* envp */
106
    /* XXX: it seems that r0 is zeroed after ! */
107
    regs->ARM_r0 = 0;
108
    /* For uClinux PIC binaries.  */
109
    regs->ARM_r10 = infop->start_data;
110
}
111

    
112
#define USE_ELF_CORE_DUMP
113
#define ELF_EXEC_PAGESIZE        4096
114

    
115
enum
116
{
117
  ARM_HWCAP_ARM_SWP       = 1 << 0,
118
  ARM_HWCAP_ARM_HALF      = 1 << 1,
119
  ARM_HWCAP_ARM_THUMB     = 1 << 2,
120
  ARM_HWCAP_ARM_26BIT     = 1 << 3,
121
  ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
122
  ARM_HWCAP_ARM_FPA       = 1 << 5,
123
  ARM_HWCAP_ARM_VFP       = 1 << 6,
124
  ARM_HWCAP_ARM_EDSP      = 1 << 7,
125
};
126

    
127
#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \
128
                    | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \
129
                    | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)
130

    
131
#endif
132

    
133
#ifdef TARGET_SPARC
134
#ifdef TARGET_SPARC64
135

    
136
#define ELF_START_MMAP 0x80000000
137

    
138
#define elf_check_arch(x) ( (x) == EM_SPARCV9 )
139

    
140
#define ELF_CLASS   ELFCLASS64
141
#define ELF_DATA    ELFDATA2MSB
142
#define ELF_ARCH    EM_SPARCV9
143

    
144
#define STACK_BIAS                2047
145

    
146
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
147
{
148
    regs->tstate = 0;
149
    regs->pc = infop->entry;
150
    regs->npc = regs->pc + 4;
151
    regs->y = 0;
152
    regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
153
}
154

    
155
#else
156
#define ELF_START_MMAP 0x80000000
157

    
158
#define elf_check_arch(x) ( (x) == EM_SPARC )
159

    
160
#define ELF_CLASS   ELFCLASS32
161
#define ELF_DATA    ELFDATA2MSB
162
#define ELF_ARCH    EM_SPARC
163

    
164
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
165
{
166
    regs->psr = 0;
167
    regs->pc = infop->entry;
168
    regs->npc = regs->pc + 4;
169
    regs->y = 0;
170
    regs->u_regs[14] = infop->start_stack - 16 * 4;
171
}
172

    
173
#endif
174
#endif
175

    
176
#ifdef TARGET_PPC
177

    
178
#define ELF_START_MMAP 0x80000000
179

    
180
#define elf_check_arch(x) ( (x) == EM_PPC )
181

    
182
#define ELF_CLASS        ELFCLASS32
183
#ifdef TARGET_WORDS_BIGENDIAN
184
#define ELF_DATA        ELFDATA2MSB
185
#else
186
#define ELF_DATA        ELFDATA2LSB
187
#endif
188
#define ELF_ARCH        EM_PPC
189

    
190
/*
191
 * We need to put in some extra aux table entries to tell glibc what
192
 * the cache block size is, so it can use the dcbz instruction safely.
193
 */
194
#define AT_DCACHEBSIZE          19
195
#define AT_ICACHEBSIZE          20
196
#define AT_UCACHEBSIZE          21
197
/* A special ignored type value for PPC, for glibc compatibility.  */
198
#define AT_IGNOREPPC            22
199
/*
200
 * The requirements here are:
201
 * - keep the final alignment of sp (sp & 0xf)
202
 * - make sure the 32-bit value at the first 16 byte aligned position of
203
 *   AUXV is greater than 16 for glibc compatibility.
204
 *   AT_IGNOREPPC is used for that.
205
 * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
206
 *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
207
 */
208
#define DLINFO_ARCH_ITEMS       5
209
#define ARCH_DLINFO                                                     \
210
do {                                                                    \
211
        NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \
212
        NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \
213
        NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \
214
        /*                                                              \
215
         * Now handle glibc compatibility.                              \
216
         */                                                             \
217
        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
218
        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \
219
 } while (0)
220

    
221
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
222
{
223
    target_ulong pos = infop->start_stack;
224
    target_ulong tmp;
225

    
226
    _regs->msr = 1 << MSR_PR; /* Set user mode */
227
    _regs->gpr[1] = infop->start_stack;
228
    _regs->nip = infop->entry;
229
    /* Note that isn't exactly what regular kernel does
230
     * but this is what the ABI wants and is needed to allow
231
     * execution of PPC BSD programs.
232
     */
233
    _regs->gpr[3] = tgetl(pos);
234
    pos += sizeof(target_ulong);
235
    _regs->gpr[4] = pos;
236
    for (tmp = 1; tmp != 0; pos += sizeof(target_ulong))
237
        tmp = ldl(pos);
238
    _regs->gpr[5] = pos;
239
}
240

    
241
#define USE_ELF_CORE_DUMP
242
#define ELF_EXEC_PAGESIZE        4096
243

    
244
#endif
245

    
246
#ifdef TARGET_MIPS
247

    
248
#define ELF_START_MMAP 0x80000000
249

    
250
#define elf_check_arch(x) ( (x) == EM_MIPS )
251

    
252
#define ELF_CLASS   ELFCLASS32
253
#ifdef TARGET_WORDS_BIGENDIAN
254
#define ELF_DATA        ELFDATA2MSB
255
#else
256
#define ELF_DATA        ELFDATA2LSB
257
#endif
258
#define ELF_ARCH    EM_MIPS
259

    
260
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
261
{
262
    regs->cp0_status = CP0St_UM;
263
    regs->cp0_epc = infop->entry;
264
    regs->regs[29] = infop->start_stack;
265
}
266

    
267
#endif /* TARGET_MIPS */
268

    
269
#ifdef TARGET_SH4
270

    
271
#define ELF_START_MMAP 0x80000000
272

    
273
#define elf_check_arch(x) ( (x) == EM_SH )
274

    
275
#define ELF_CLASS ELFCLASS32
276
#define ELF_DATA  ELFDATA2LSB
277
#define ELF_ARCH  EM_SH
278

    
279
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
280
{
281
  /* Check other registers XXXXX */
282
  regs->pc = infop->entry;
283
  regs->regs[15] = infop->start_stack - 16 * 4;
284
}
285

    
286
#define USE_ELF_CORE_DUMP
287
#define ELF_EXEC_PAGESIZE        4096
288

    
289
#endif
290

    
291
#ifdef TARGET_M68K
292

    
293
#define ELF_START_MMAP 0x80000000
294

    
295
#define elf_check_arch(x) ( (x) == EM_68K )
296

    
297
#define ELF_CLASS        ELFCLASS32
298
#define ELF_DATA        ELFDATA2MSB
299
#define ELF_ARCH        EM_68K
300

    
301
/* ??? Does this need to do anything?
302
#define ELF_PLAT_INIT(_r) */
303

    
304
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
305
{
306
    regs->usp = infop->start_stack;
307
    regs->sr = 0;
308
    regs->pc = infop->entry;
309
}
310

    
311
#define USE_ELF_CORE_DUMP
312
#define ELF_EXEC_PAGESIZE        8192
313

    
314
#endif
315

    
316
#ifndef ELF_PLATFORM
317
#define ELF_PLATFORM (NULL)
318
#endif
319

    
320
#ifndef ELF_HWCAP
321
#define ELF_HWCAP 0
322
#endif
323

    
324
#include "elf.h"
325

    
326
struct exec
327
{
328
  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
329
  unsigned int a_text;   /* length of text, in bytes */
330
  unsigned int a_data;   /* length of data, in bytes */
331
  unsigned int a_bss;    /* length of uninitialized data area, in bytes */
332
  unsigned int a_syms;   /* length of symbol table data in file, in bytes */
333
  unsigned int a_entry;  /* start address */
334
  unsigned int a_trsize; /* length of relocation info for text, in bytes */
335
  unsigned int a_drsize; /* length of relocation info for data, in bytes */
336
};
337

    
338

    
339
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
340
#define OMAGIC 0407
341
#define NMAGIC 0410
342
#define ZMAGIC 0413
343
#define QMAGIC 0314
344

    
345
/* max code+data+bss space allocated to elf interpreter */
346
#define INTERP_MAP_SIZE (32 * 1024 * 1024)
347

    
348
/* max code+data+bss+brk space allocated to ET_DYN executables */
349
#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
350

    
351
/* from personality.h */
352

    
353
/* Flags for bug emulation. These occupy the top three bytes. */
354
#define STICKY_TIMEOUTS                0x4000000
355
#define WHOLE_SECONDS                0x2000000
356

    
357
/* Personality types. These go in the low byte. Avoid using the top bit,
358
 * it will conflict with error returns.
359
 */
360
#define PER_MASK                (0x00ff)
361
#define PER_LINUX                (0x0000)
362
#define PER_SVR4                (0x0001 | STICKY_TIMEOUTS)
363
#define PER_SVR3                (0x0002 | STICKY_TIMEOUTS)
364
#define PER_SCOSVR3                (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
365
#define PER_WYSEV386                (0x0004 | STICKY_TIMEOUTS)
366
#define PER_ISCR4                (0x0005 | STICKY_TIMEOUTS)
367
#define PER_BSD                        (0x0006)
368
#define PER_XENIX                (0x0007 | STICKY_TIMEOUTS)
369

    
370
/* Necessary parameters */
371
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
372
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
373
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
374

    
375
#define INTERPRETER_NONE 0
376
#define INTERPRETER_AOUT 1
377
#define INTERPRETER_ELF 2
378

    
379
#define DLINFO_ITEMS 12
380

    
381
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
382
{
383
        memcpy(to, from, n);
384
}
385

    
386
extern unsigned long x86_stack_size;
387

    
388
static int load_aout_interp(void * exptr, int interp_fd);
389

    
390
#ifdef BSWAP_NEEDED
391
static void bswap_ehdr(struct elfhdr *ehdr)
392
{
393
    bswap16s(&ehdr->e_type);                        /* Object file type */
394
    bswap16s(&ehdr->e_machine);                /* Architecture */
395
    bswap32s(&ehdr->e_version);                /* Object file version */
396
    bswaptls(&ehdr->e_entry);                /* Entry point virtual address */
397
    bswaptls(&ehdr->e_phoff);                /* Program header table file offset */
398
    bswaptls(&ehdr->e_shoff);                /* Section header table file offset */
399
    bswap32s(&ehdr->e_flags);                /* Processor-specific flags */
400
    bswap16s(&ehdr->e_ehsize);                /* ELF header size in bytes */
401
    bswap16s(&ehdr->e_phentsize);                /* Program header table entry size */
402
    bswap16s(&ehdr->e_phnum);                /* Program header table entry count */
403
    bswap16s(&ehdr->e_shentsize);                /* Section header table entry size */
404
    bswap16s(&ehdr->e_shnum);                /* Section header table entry count */
405
    bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */
406
}
407

    
408
static void bswap_phdr(struct elf_phdr *phdr)
409
{
410
    bswap32s(&phdr->p_type);                        /* Segment type */
411
    bswaptls(&phdr->p_offset);                /* Segment file offset */
412
    bswaptls(&phdr->p_vaddr);                /* Segment virtual address */
413
    bswaptls(&phdr->p_paddr);                /* Segment physical address */
414
    bswaptls(&phdr->p_filesz);                /* Segment size in file */
415
    bswaptls(&phdr->p_memsz);                /* Segment size in memory */
416
    bswap32s(&phdr->p_flags);                /* Segment flags */
417
    bswaptls(&phdr->p_align);                /* Segment alignment */
418
}
419

    
420
static void bswap_shdr(struct elf_shdr *shdr)
421
{
422
    bswap32s(&shdr->sh_name);
423
    bswap32s(&shdr->sh_type);
424
    bswaptls(&shdr->sh_flags);
425
    bswaptls(&shdr->sh_addr);
426
    bswaptls(&shdr->sh_offset);
427
    bswaptls(&shdr->sh_size);
428
    bswap32s(&shdr->sh_link);
429
    bswap32s(&shdr->sh_info);
430
    bswaptls(&shdr->sh_addralign);
431
    bswaptls(&shdr->sh_entsize);
432
}
433

    
434
static void bswap_sym(Elf32_Sym *sym)
435
{
436
    bswap32s(&sym->st_name);
437
    bswap32s(&sym->st_value);
438
    bswap32s(&sym->st_size);
439
    bswap16s(&sym->st_shndx);
440
}
441
#endif
442

    
443
/*
444
 * 'copy_elf_strings()' copies argument/envelope strings from user
445
 * memory to free pages in kernel mem. These are in a format ready
446
 * to be put directly into the top of new user memory.
447
 *
448
 */
449
static unsigned long copy_elf_strings(int argc,char ** argv, void **page,
450
                                      unsigned long p)
451
{
452
    char *tmp, *tmp1, *pag = NULL;
453
    int len, offset = 0;
454

    
455
    if (!p) {
456
        return 0;       /* bullet-proofing */
457
    }
458
    while (argc-- > 0) {
459
        tmp = argv[argc];
460
        if (!tmp) {
461
            fprintf(stderr, "VFS: argc is wrong");
462
            exit(-1);
463
        }
464
        tmp1 = tmp;
465
        while (*tmp++);
466
        len = tmp - tmp1;
467
        if (p < len) {  /* this shouldn't happen - 128kB */
468
                return 0;
469
        }
470
        while (len) {
471
            --p; --tmp; --len;
472
            if (--offset < 0) {
473
                offset = p % TARGET_PAGE_SIZE;
474
                pag = (char *)page[p/TARGET_PAGE_SIZE];
475
                if (!pag) {
476
                    pag = (char *)malloc(TARGET_PAGE_SIZE);
477
                    page[p/TARGET_PAGE_SIZE] = pag;
478
                    if (!pag)
479
                        return 0;
480
                }
481
            }
482
            if (len == 0 || offset == 0) {
483
                *(pag + offset) = *tmp;
484
            }
485
            else {
486
              int bytes_to_copy = (len > offset) ? offset : len;
487
              tmp -= bytes_to_copy;
488
              p -= bytes_to_copy;
489
              offset -= bytes_to_copy;
490
              len -= bytes_to_copy;
491
              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
492
            }
493
        }
494
    }
495
    return p;
496
}
497

    
498
unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
499
                                              struct image_info * info)
500
{
501
    target_ulong stack_base, size, error;
502
    int i;
503

    
504
    /* Create enough stack to hold everything.  If we don't use
505
     * it for args, we'll use it for something else...
506
     */
507
    size = x86_stack_size;
508
    if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
509
        size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
510
    error = target_mmap(0, 
511
                        size + qemu_host_page_size,
512
                        PROT_READ | PROT_WRITE,
513
                        MAP_PRIVATE | MAP_ANONYMOUS,
514
                        -1, 0);
515
    if (error == -1) {
516
        perror("stk mmap");
517
        exit(-1);
518
    }
519
    /* we reserve one extra page at the top of the stack as guard */
520
    target_mprotect(error + size, qemu_host_page_size, PROT_NONE);
521

    
522
    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
523
    p += stack_base;
524

    
525
    for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
526
        if (bprm->page[i]) {
527
            info->rss++;
528

    
529
            memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
530
            free(bprm->page[i]);
531
        }
532
        stack_base += TARGET_PAGE_SIZE;
533
    }
534
    return p;
535
}
536

    
537
static void set_brk(unsigned long start, unsigned long end)
538
{
539
        /* page-align the start and end addresses... */
540
        start = HOST_PAGE_ALIGN(start);
541
        end = HOST_PAGE_ALIGN(end);
542
        if (end <= start)
543
                return;
544
        if(target_mmap(start, end - start,
545
                       PROT_READ | PROT_WRITE | PROT_EXEC,
546
                       MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
547
            perror("cannot mmap brk");
548
            exit(-1);
549
        }
550
}
551

    
552

    
553
/* We need to explicitly zero any fractional pages after the data
554
   section (i.e. bss).  This would contain the junk from the file that
555
   should not be in memory. */
556
static void padzero(unsigned long elf_bss)
557
{
558
        unsigned long nbyte;
559

    
560
        /* XXX: this is really a hack : if the real host page size is
561
           smaller than the target page size, some pages after the end
562
           of the file may not be mapped. A better fix would be to
563
           patch target_mmap(), but it is more complicated as the file
564
           size must be known */
565
        if (qemu_real_host_page_size < qemu_host_page_size) {
566
            unsigned long end_addr, end_addr1;
567
            end_addr1 = (elf_bss + qemu_real_host_page_size - 1) & 
568
                ~(qemu_real_host_page_size - 1);
569
            end_addr = HOST_PAGE_ALIGN(elf_bss);
570
            if (end_addr1 < end_addr) {
571
                mmap((void *)end_addr1, end_addr - end_addr1,
572
                     PROT_READ|PROT_WRITE|PROT_EXEC,
573
                     MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
574
            }
575
        }
576

    
577
        nbyte = elf_bss & (qemu_host_page_size-1);
578
        if (nbyte) {
579
            nbyte = qemu_host_page_size - nbyte;
580
            do {
581
                tput8(elf_bss, 0);
582
                elf_bss++;
583
            } while (--nbyte);
584
        }
585
}
586

    
587

    
588
static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
589
                                       struct elfhdr * exec,
590
                                       unsigned long load_addr,
591
                                       unsigned long load_bias,
592
                                       unsigned long interp_load_addr, int ibcs,
593
                                       struct image_info *info)
594
{
595
        target_ulong sp;
596
        int size;
597
        target_ulong u_platform;
598
        const char *k_platform;
599
        const int n = sizeof(target_ulong);
600

    
601
        sp = p;
602
        u_platform = 0;
603
        k_platform = ELF_PLATFORM;
604
        if (k_platform) {
605
            size_t len = strlen(k_platform) + 1;
606
            sp -= (len + n - 1) & ~(n - 1);
607
            u_platform = sp;
608
            memcpy_to_target(sp, k_platform, len);
609
        }
610
        /*
611
         * Force 16 byte _final_ alignment here for generality.
612
         */
613
        sp = sp &~ (target_ulong)15;
614
        size = (DLINFO_ITEMS + 1) * 2;
615
        if (k_platform)
616
          size += 2;
617
#ifdef DLINFO_ARCH_ITEMS
618
        size += DLINFO_ARCH_ITEMS * 2;
619
#endif
620
        size += envc + argc + 2;
621
        size += (!ibcs ? 3 : 1);        /* argc itself */
622
        size *= n;
623
        if (size & 15)
624
            sp -= 16 - (size & 15);
625
        
626
#define NEW_AUX_ENT(id, val) do { \
627
            sp -= n; tputl(sp, val); \
628
            sp -= n; tputl(sp, id); \
629
          } while(0)
630
        NEW_AUX_ENT (AT_NULL, 0);
631

    
632
        /* There must be exactly DLINFO_ITEMS entries here.  */
633
        NEW_AUX_ENT(AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
634
        NEW_AUX_ENT(AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
635
        NEW_AUX_ENT(AT_PHNUM, (target_ulong)(exec->e_phnum));
636
        NEW_AUX_ENT(AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
637
        NEW_AUX_ENT(AT_BASE, (target_ulong)(interp_load_addr));
638
        NEW_AUX_ENT(AT_FLAGS, (target_ulong)0);
639
        NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
640
        NEW_AUX_ENT(AT_UID, (target_ulong) getuid());
641
        NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid());
642
        NEW_AUX_ENT(AT_GID, (target_ulong) getgid());
643
        NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
644
        NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
645
        if (k_platform)
646
            NEW_AUX_ENT(AT_PLATFORM, u_platform);
647
#ifdef ARCH_DLINFO
648
        /* 
649
         * ARCH_DLINFO must come last so platform specific code can enforce
650
         * special alignment requirements on the AUXV if necessary (eg. PPC).
651
         */
652
        ARCH_DLINFO;
653
#endif
654
#undef NEW_AUX_ENT
655

    
656
        sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
657
        return sp;
658
}
659

    
660

    
661
static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
662
                                     int interpreter_fd,
663
                                     unsigned long *interp_load_addr)
664
{
665
        struct elf_phdr *elf_phdata  =  NULL;
666
        struct elf_phdr *eppnt;
667
        unsigned long load_addr = 0;
668
        int load_addr_set = 0;
669
        int retval;
670
        unsigned long last_bss, elf_bss;
671
        unsigned long error;
672
        int i;
673
        
674
        elf_bss = 0;
675
        last_bss = 0;
676
        error = 0;
677

    
678
#ifdef BSWAP_NEEDED
679
        bswap_ehdr(interp_elf_ex);
680
#endif
681
        /* First of all, some simple consistency checks */
682
        if ((interp_elf_ex->e_type != ET_EXEC && 
683
             interp_elf_ex->e_type != ET_DYN) || 
684
           !elf_check_arch(interp_elf_ex->e_machine)) {
685
                return ~0UL;
686
        }
687
        
688

    
689
        /* Now read in all of the header information */
690
        
691
        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
692
            return ~0UL;
693
        
694
        elf_phdata =  (struct elf_phdr *) 
695
                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
696

    
697
        if (!elf_phdata)
698
          return ~0UL;
699
        
700
        /*
701
         * If the size of this structure has changed, then punt, since
702
         * we will be doing the wrong thing.
703
         */
704
        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
705
            free(elf_phdata);
706
            return ~0UL;
707
        }
708

    
709
        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
710
        if(retval >= 0) {
711
            retval = read(interpreter_fd,
712
                           (char *) elf_phdata,
713
                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
714
        }
715
        if (retval < 0) {
716
                perror("load_elf_interp");
717
                exit(-1);
718
                free (elf_phdata);
719
                return retval;
720
         }
721
#ifdef BSWAP_NEEDED
722
        eppnt = elf_phdata;
723
        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
724
            bswap_phdr(eppnt);
725
        }
726
#endif
727

    
728
        if (interp_elf_ex->e_type == ET_DYN) {
729
            /* in order to avoid harcoding the interpreter load
730
               address in qemu, we allocate a big enough memory zone */
731
            error = target_mmap(0, INTERP_MAP_SIZE,
732
                                PROT_NONE, MAP_PRIVATE | MAP_ANON, 
733
                                -1, 0);
734
            if (error == -1) {
735
                perror("mmap");
736
                exit(-1);
737
            }
738
            load_addr = error;
739
            load_addr_set = 1;
740
        }
741

    
742
        eppnt = elf_phdata;
743
        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
744
          if (eppnt->p_type == PT_LOAD) {
745
            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
746
            int elf_prot = 0;
747
            unsigned long vaddr = 0;
748
            unsigned long k;
749

    
750
            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
751
            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
752
            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
753
            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
754
                    elf_type |= MAP_FIXED;
755
                    vaddr = eppnt->p_vaddr;
756
            }
757
            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
758
                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
759
                 elf_prot,
760
                 elf_type,
761
                 interpreter_fd,
762
                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
763
            
764
            if (error == -1) {
765
              /* Real error */
766
              close(interpreter_fd);
767
              free(elf_phdata);
768
              return ~0UL;
769
            }
770

    
771
            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
772
              load_addr = error;
773
              load_addr_set = 1;
774
            }
775

    
776
            /*
777
             * Find the end of the file  mapping for this phdr, and keep
778
             * track of the largest address we see for this.
779
             */
780
            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
781
            if (k > elf_bss) elf_bss = k;
782

    
783
            /*
784
             * Do the same thing for the memory mapping - between
785
             * elf_bss and last_bss is the bss section.
786
             */
787
            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
788
            if (k > last_bss) last_bss = k;
789
          }
790
        
791
        /* Now use mmap to map the library into memory. */
792

    
793
        close(interpreter_fd);
794

    
795
        /*
796
         * Now fill out the bss section.  First pad the last page up
797
         * to the page boundary, and then perform a mmap to make sure
798
         * that there are zeromapped pages up to and including the last
799
         * bss page.
800
         */
801
        padzero(elf_bss);
802
        elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
803

    
804
        /* Map the last of the bss segment */
805
        if (last_bss > elf_bss) {
806
            target_mmap(elf_bss, last_bss-elf_bss,
807
                        PROT_READ|PROT_WRITE|PROT_EXEC,
808
                        MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
809
        }
810
        free(elf_phdata);
811

    
812
        *interp_load_addr = load_addr;
813
        return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
814
}
815

    
816
/* Best attempt to load symbols from this ELF object. */
817
static void load_symbols(struct elfhdr *hdr, int fd)
818
{
819
    unsigned int i;
820
    struct elf_shdr sechdr, symtab, strtab;
821
    char *strings;
822
    struct syminfo *s;
823

    
824
    lseek(fd, hdr->e_shoff, SEEK_SET);
825
    for (i = 0; i < hdr->e_shnum; i++) {
826
        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
827
            return;
828
#ifdef BSWAP_NEEDED
829
        bswap_shdr(&sechdr);
830
#endif
831
        if (sechdr.sh_type == SHT_SYMTAB) {
832
            symtab = sechdr;
833
            lseek(fd, hdr->e_shoff
834
                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
835
            if (read(fd, &strtab, sizeof(strtab))
836
                != sizeof(strtab))
837
                return;
838
#ifdef BSWAP_NEEDED
839
            bswap_shdr(&strtab);
840
#endif
841
            goto found;
842
        }
843
    }
844
    return; /* Shouldn't happen... */
845

    
846
 found:
847
    /* Now know where the strtab and symtab are.  Snarf them. */
848
    s = malloc(sizeof(*s));
849
    s->disas_symtab = malloc(symtab.sh_size);
850
    s->disas_strtab = strings = malloc(strtab.sh_size);
851
    if (!s->disas_symtab || !s->disas_strtab)
852
        return;
853
        
854
    lseek(fd, symtab.sh_offset, SEEK_SET);
855
    if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
856
        return;
857

    
858
#ifdef BSWAP_NEEDED
859
    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
860
        bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
861
#endif
862

    
863
    lseek(fd, strtab.sh_offset, SEEK_SET);
864
    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
865
        return;
866
    s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
867
    s->next = syminfos;
868
    syminfos = s;
869
}
870

    
871
int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
872
                    struct image_info * info)
873
{
874
    struct elfhdr elf_ex;
875
    struct elfhdr interp_elf_ex;
876
    struct exec interp_ex;
877
    int interpreter_fd = -1; /* avoid warning */
878
    unsigned long load_addr, load_bias;
879
    int load_addr_set = 0;
880
    unsigned int interpreter_type = INTERPRETER_NONE;
881
    unsigned char ibcs2_interpreter;
882
    int i;
883
    unsigned long mapped_addr;
884
    struct elf_phdr * elf_ppnt;
885
    struct elf_phdr *elf_phdata;
886
    unsigned long elf_bss, k, elf_brk;
887
    int retval;
888
    char * elf_interpreter;
889
    unsigned long elf_entry, interp_load_addr = 0;
890
    int status;
891
    unsigned long start_code, end_code, end_data;
892
    unsigned long elf_stack;
893
    char passed_fileno[6];
894

    
895
    ibcs2_interpreter = 0;
896
    status = 0;
897
    load_addr = 0;
898
    load_bias = 0;
899
    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
900
#ifdef BSWAP_NEEDED
901
    bswap_ehdr(&elf_ex);
902
#endif
903

    
904
    /* First of all, some simple consistency checks */
905
    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
906
                                       (! elf_check_arch(elf_ex.e_machine))) {
907
            return -ENOEXEC;
908
    }
909

    
910
    bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
911
    bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
912
    bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
913
    if (!bprm->p) {
914
        retval = -E2BIG;
915
    }
916

    
917
    /* Now read in all of the header information */
918
    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
919
    if (elf_phdata == NULL) {
920
        return -ENOMEM;
921
    }
922

    
923
    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
924
    if(retval > 0) {
925
        retval = read(bprm->fd, (char *) elf_phdata, 
926
                                elf_ex.e_phentsize * elf_ex.e_phnum);
927
    }
928

    
929
    if (retval < 0) {
930
        perror("load_elf_binary");
931
        exit(-1);
932
        free (elf_phdata);
933
        return -errno;
934
    }
935

    
936
#ifdef BSWAP_NEEDED
937
    elf_ppnt = elf_phdata;
938
    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
939
        bswap_phdr(elf_ppnt);
940
    }
941
#endif
942
    elf_ppnt = elf_phdata;
943

    
944
    elf_bss = 0;
945
    elf_brk = 0;
946

    
947

    
948
    elf_stack = ~0UL;
949
    elf_interpreter = NULL;
950
    start_code = ~0UL;
951
    end_code = 0;
952
    end_data = 0;
953

    
954
    for(i=0;i < elf_ex.e_phnum; i++) {
955
        if (elf_ppnt->p_type == PT_INTERP) {
956
            if ( elf_interpreter != NULL )
957
            {
958
                free (elf_phdata);
959
                free(elf_interpreter);
960
                close(bprm->fd);
961
                return -EINVAL;
962
            }
963

    
964
            /* This is the program interpreter used for
965
             * shared libraries - for now assume that this
966
             * is an a.out format binary
967
             */
968

    
969
            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
970

    
971
            if (elf_interpreter == NULL) {
972
                free (elf_phdata);
973
                close(bprm->fd);
974
                return -ENOMEM;
975
            }
976

    
977
            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
978
            if(retval >= 0) {
979
                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
980
            }
981
            if(retval < 0) {
982
                 perror("load_elf_binary2");
983
                exit(-1);
984
            }        
985

    
986
            /* If the program interpreter is one of these two,
987
               then assume an iBCS2 image. Otherwise assume
988
               a native linux image. */
989

    
990
            /* JRP - Need to add X86 lib dir stuff here... */
991

    
992
            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
993
                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
994
              ibcs2_interpreter = 1;
995
            }
996

    
997
#if 0
998
            printf("Using ELF interpreter %s\n", elf_interpreter);
999
#endif
1000
            if (retval >= 0) {
1001
                retval = open(path(elf_interpreter), O_RDONLY);
1002
                if(retval >= 0) {
1003
                    interpreter_fd = retval;
1004
                }
1005
                else {
1006
                    perror(elf_interpreter);
1007
                    exit(-1);
1008
                    /* retval = -errno; */
1009
                }
1010
            }
1011

    
1012
            if (retval >= 0) {
1013
                retval = lseek(interpreter_fd, 0, SEEK_SET);
1014
                if(retval >= 0) {
1015
                    retval = read(interpreter_fd,bprm->buf,128);
1016
                }
1017
            }
1018
            if (retval >= 0) {
1019
                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
1020
                interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
1021
            }
1022
            if (retval < 0) {
1023
                perror("load_elf_binary3");
1024
                exit(-1);
1025
                free (elf_phdata);
1026
                free(elf_interpreter);
1027
                close(bprm->fd);
1028
                return retval;
1029
            }
1030
        }
1031
        elf_ppnt++;
1032
    }
1033

    
1034
    /* Some simple consistency checks for the interpreter */
1035
    if (elf_interpreter){
1036
        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1037

    
1038
        /* Now figure out which format our binary is */
1039
        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
1040
                    (N_MAGIC(interp_ex) != QMAGIC)) {
1041
          interpreter_type = INTERPRETER_ELF;
1042
        }
1043

    
1044
        if (interp_elf_ex.e_ident[0] != 0x7f ||
1045
                    strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1046
            interpreter_type &= ~INTERPRETER_ELF;
1047
        }
1048

    
1049
        if (!interpreter_type) {
1050
            free(elf_interpreter);
1051
            free(elf_phdata);
1052
            close(bprm->fd);
1053
            return -ELIBBAD;
1054
        }
1055
    }
1056

    
1057
    /* OK, we are done with that, now set up the arg stuff,
1058
       and then start this sucker up */
1059

    
1060
    {
1061
        char * passed_p;
1062

    
1063
        if (interpreter_type == INTERPRETER_AOUT) {
1064
            snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
1065
            passed_p = passed_fileno;
1066

    
1067
            if (elf_interpreter) {
1068
                bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p);
1069
                bprm->argc++;
1070
            }
1071
        }
1072
        if (!bprm->p) {
1073
            if (elf_interpreter) {
1074
                free(elf_interpreter);
1075
            }
1076
            free (elf_phdata);
1077
            close(bprm->fd);
1078
            return -E2BIG;
1079
        }
1080
    }
1081

    
1082
    /* OK, This is the point of no return */
1083
    info->end_data = 0;
1084
    info->end_code = 0;
1085
    info->start_mmap = (unsigned long)ELF_START_MMAP;
1086
    info->mmap = 0;
1087
    elf_entry = (unsigned long) elf_ex.e_entry;
1088

    
1089
    /* Do this so that we can load the interpreter, if need be.  We will
1090
       change some of these later */
1091
    info->rss = 0;
1092
    bprm->p = setup_arg_pages(bprm->p, bprm, info);
1093
    info->start_stack = bprm->p;
1094

    
1095
    /* Now we do a little grungy work by mmaping the ELF image into
1096
     * the correct location in memory.  At this point, we assume that
1097
     * the image should be loaded at fixed address, not at a variable
1098
     * address.
1099
     */
1100

    
1101
    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1102
        int elf_prot = 0;
1103
        int elf_flags = 0;
1104
        unsigned long error;
1105
        
1106
        if (elf_ppnt->p_type != PT_LOAD)
1107
            continue;
1108
        
1109
        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
1110
        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
1111
        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
1112
        elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
1113
        if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1114
            elf_flags |= MAP_FIXED;
1115
        } else if (elf_ex.e_type == ET_DYN) {
1116
            /* Try and get dynamic programs out of the way of the default mmap
1117
               base, as well as whatever program they might try to exec.  This
1118
               is because the brk will follow the loader, and is not movable.  */
1119
            /* NOTE: for qemu, we do a big mmap to get enough space
1120
               without harcoding any address */
1121
            error = target_mmap(0, ET_DYN_MAP_SIZE,
1122
                                PROT_NONE, MAP_PRIVATE | MAP_ANON, 
1123
                                -1, 0);
1124
            if (error == -1) {
1125
                perror("mmap");
1126
                exit(-1);
1127
            }
1128
            load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
1129
        }
1130
        
1131
        error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
1132
                            (elf_ppnt->p_filesz +
1133
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
1134
                            elf_prot,
1135
                            (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
1136
                            bprm->fd,
1137
                            (elf_ppnt->p_offset - 
1138
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
1139
        if (error == -1) {
1140
            perror("mmap");
1141
            exit(-1);
1142
        }
1143

    
1144
#ifdef LOW_ELF_STACK
1145
        if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1146
            elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
1147
#endif
1148
        
1149
        if (!load_addr_set) {
1150
            load_addr_set = 1;
1151
            load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1152
            if (elf_ex.e_type == ET_DYN) {
1153
                load_bias += error -
1154
                    TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
1155
                load_addr += load_bias;
1156
            }
1157
        }
1158
        k = elf_ppnt->p_vaddr;
1159
        if (k < start_code) 
1160
            start_code = k;
1161
        k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1162
        if (k > elf_bss) 
1163
            elf_bss = k;
1164
        if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
1165
            end_code = k;
1166
        if (end_data < k) 
1167
            end_data = k;
1168
        k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1169
        if (k > elf_brk) elf_brk = k;
1170
    }
1171

    
1172
    elf_entry += load_bias;
1173
    elf_bss += load_bias;
1174
    elf_brk += load_bias;
1175
    start_code += load_bias;
1176
    end_code += load_bias;
1177
    //    start_data += load_bias;
1178
    end_data += load_bias;
1179

    
1180
    if (elf_interpreter) {
1181
        if (interpreter_type & 1) {
1182
            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1183
        }
1184
        else if (interpreter_type & 2) {
1185
            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1186
                                            &interp_load_addr);
1187
        }
1188

    
1189
        close(interpreter_fd);
1190
        free(elf_interpreter);
1191

    
1192
        if (elf_entry == ~0UL) {
1193
            printf("Unable to load interpreter\n");
1194
            free(elf_phdata);
1195
            exit(-1);
1196
            return 0;
1197
        }
1198
    }
1199

    
1200
    free(elf_phdata);
1201

    
1202
    if (loglevel)
1203
        load_symbols(&elf_ex, bprm->fd);
1204

    
1205
    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1206
    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1207

    
1208
#ifdef LOW_ELF_STACK
1209
    info->start_stack = bprm->p = elf_stack - 4;
1210
#endif
1211
    bprm->p = create_elf_tables(bprm->p,
1212
                    bprm->argc,
1213
                    bprm->envc,
1214
                    &elf_ex,
1215
                    load_addr, load_bias,
1216
                    interp_load_addr,
1217
                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1218
                    info);
1219
    info->start_brk = info->brk = elf_brk;
1220
    info->end_code = end_code;
1221
    info->start_code = start_code;
1222
    info->start_data = end_code;
1223
    info->end_data = end_data;
1224
    info->start_stack = bprm->p;
1225

    
1226
    /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1227
       sections */
1228
    set_brk(elf_bss, elf_brk);
1229

    
1230
    padzero(elf_bss);
1231

    
1232
#if 0
1233
    printf("(start_brk) %x\n" , info->start_brk);
1234
    printf("(end_code) %x\n" , info->end_code);
1235
    printf("(start_code) %x\n" , info->start_code);
1236
    printf("(end_data) %x\n" , info->end_data);
1237
    printf("(start_stack) %x\n" , info->start_stack);
1238
    printf("(brk) %x\n" , info->brk);
1239
#endif
1240

    
1241
    if ( info->personality == PER_SVR4 )
1242
    {
1243
            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1244
               and some applications "depend" upon this behavior.
1245
               Since we do not have the power to recompile these, we
1246
               emulate the SVr4 behavior.  Sigh.  */
1247
            mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
1248
                                      MAP_FIXED | MAP_PRIVATE, -1, 0);
1249
    }
1250

    
1251
    info->entry = elf_entry;
1252

    
1253
    return 0;
1254
}
1255

    
1256
static int load_aout_interp(void * exptr, int interp_fd)
1257
{
1258
    printf("a.out interpreter not yet supported\n");
1259
    return(0);
1260
}
1261

    
1262
void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
1263
{
1264
    init_thread(regs, infop);
1265
}