Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ e80cfcfc

History | View | Annotate | Download (37.8 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 <sys/stat.h>
7
#include <errno.h>
8
#include <unistd.h>
9
#include <sys/mman.h>
10
#include <stdlib.h>
11
#include <string.h>
12

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

    
16
/* this flag is uneffective under linux too, should be deleted */
17
#ifndef MAP_DENYWRITE
18
#define MAP_DENYWRITE 0
19
#endif
20

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

    
26
#ifdef TARGET_I386
27

    
28
#define ELF_START_MMAP 0x80000000
29

    
30
/*
31
 * This is used to ensure we don't load something for the wrong architecture.
32
 */
33
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
34

    
35
/*
36
 * These are used to set parameters in the core dumps.
37
 */
38
#define ELF_CLASS        ELFCLASS32
39
#define ELF_DATA        ELFDATA2LSB
40
#define ELF_ARCH        EM_386
41

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

48
           A value of 0 tells we have no such handler.  */
49
#define ELF_PLAT_INIT(_r)        _r->edx = 0
50

    
51
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
52
{
53
    regs->esp = infop->start_stack;
54
    regs->eip = infop->entry;
55
}
56

    
57
#define USE_ELF_CORE_DUMP
58
#define ELF_EXEC_PAGESIZE        4096
59

    
60
#endif
61

    
62
#ifdef TARGET_ARM
63

    
64
#define ELF_START_MMAP 0x80000000
65

    
66
#define elf_check_arch(x) ( (x) == EM_ARM )
67

    
68
#define ELF_CLASS        ELFCLASS32
69
#ifdef TARGET_WORDS_BIGENDIAN
70
#define ELF_DATA        ELFDATA2MSB
71
#else
72
#define ELF_DATA        ELFDATA2LSB
73
#endif
74
#define ELF_ARCH        EM_ARM
75

    
76
#define ELF_PLAT_INIT(_r)        _r->ARM_r0 = 0
77

    
78
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
79
{
80
    target_long *stack = (void *)infop->start_stack;
81
    memset(regs, 0, sizeof(*regs));
82
    regs->ARM_cpsr = 0x10;
83
    regs->ARM_pc = infop->entry;
84
    regs->ARM_sp = infop->start_stack;
85
    regs->ARM_r2 = tswapl(stack[2]); /* envp */
86
    regs->ARM_r1 = tswapl(stack[1]); /* argv */
87
    /* XXX: it seems that r0 is zeroed after ! */
88
    //    regs->ARM_r0 = tswapl(stack[0]); /* argc */
89
}
90

    
91
#define USE_ELF_CORE_DUMP
92
#define ELF_EXEC_PAGESIZE        4096
93

    
94
#endif
95

    
96
#ifdef TARGET_SPARC
97

    
98
#define ELF_START_MMAP 0x80000000
99

    
100
#define elf_check_arch(x) ( (x) == EM_SPARC )
101

    
102
#define ELF_CLASS   ELFCLASS32
103
#define ELF_DATA    ELFDATA2MSB
104
#define ELF_ARCH    EM_SPARC
105

    
106
/*XXX*/
107
#define ELF_PLAT_INIT(_r)
108

    
109
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
110
{
111
    regs->psr = 0;
112
    regs->pc = infop->entry;
113
    regs->npc = regs->pc + 4;
114
    regs->y = 0;
115
    regs->u_regs[14] = infop->start_stack - 16 * 4;
116
}
117

    
118
#endif
119

    
120
#ifdef TARGET_PPC
121

    
122
#define ELF_START_MMAP 0x80000000
123

    
124
#define elf_check_arch(x) ( (x) == EM_PPC )
125

    
126
#define ELF_CLASS        ELFCLASS32
127
#ifdef TARGET_WORDS_BIGENDIAN
128
#define ELF_DATA        ELFDATA2MSB
129
#else
130
#define ELF_DATA        ELFDATA2LSB
131
#endif
132
#define ELF_ARCH        EM_PPC
133

    
134
/* Note that isn't exactly what regular kernel does
135
 * but this is what the ABI wants and is needed to allow
136
 * execution of PPC BSD programs.
137
 */
138
#define ELF_PLAT_INIT(_r)                                  \
139
do {                                                       \
140
    target_ulong *pos = (target_ulong *)bprm->p, tmp = 1;  \
141
    _r->gpr[3] = bprm->argc;                               \
142
    _r->gpr[4] = (unsigned long)++pos;                     \
143
    for (; tmp != 0; pos++)                                \
144
        tmp = *pos;                                        \
145
    _r->gpr[5] = (unsigned long)pos;                       \
146
} while (0)
147

    
148
/*
149
 * We need to put in some extra aux table entries to tell glibc what
150
 * the cache block size is, so it can use the dcbz instruction safely.
151
 */
152
#define AT_DCACHEBSIZE          19
153
#define AT_ICACHEBSIZE          20
154
#define AT_UCACHEBSIZE          21
155
/* A special ignored type value for PPC, for glibc compatibility.  */
156
#define AT_IGNOREPPC            22
157
/*
158
 * The requirements here are:
159
 * - keep the final alignment of sp (sp & 0xf)
160
 * - make sure the 32-bit value at the first 16 byte aligned position of
161
 *   AUXV is greater than 16 for glibc compatibility.
162
 *   AT_IGNOREPPC is used for that.
163
 * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
164
 *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
165
 */
166
#define DLINFO_ARCH_ITEMS       3
167
#define ARCH_DLINFO                                                     \
168
do {                                                                    \
169
        sp -= DLINFO_ARCH_ITEMS * 2;                                        \
170
        NEW_AUX_ENT(0, AT_DCACHEBSIZE, 0x20);                           \
171
        NEW_AUX_ENT(1, AT_ICACHEBSIZE, 0x20);                           \
172
        NEW_AUX_ENT(2, AT_UCACHEBSIZE, 0);                              \
173
        /*                                                              \
174
         * Now handle glibc compatibility.                              \
175
         */                                                             \
176
        sp -= 2*2;                                                        \
177
        NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC);                        \
178
        NEW_AUX_ENT(1, AT_IGNOREPPC, AT_IGNOREPPC);                        \
179
 } while (0)
180

    
181
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
182
{
183
    _regs->msr = 1 << MSR_PR; /* Set user mode */
184
    _regs->gpr[1] = infop->start_stack;
185
    _regs->nip = infop->entry;
186
}
187

    
188
#define USE_ELF_CORE_DUMP
189
#define ELF_EXEC_PAGESIZE        4096
190

    
191
#endif
192

    
193
#include "elf.h"
194

    
195
/*
196
 * MAX_ARG_PAGES defines the number of pages allocated for arguments
197
 * and envelope for the new program. 32 should suffice, this gives
198
 * a maximum env+arg of 128kB w/4KB pages!
199
 */
200
#define MAX_ARG_PAGES 32
201

    
202
/*
203
 * This structure is used to hold the arguments that are 
204
 * used when loading binaries.
205
 */
206
struct linux_binprm {
207
        char buf[128];
208
        unsigned long page[MAX_ARG_PAGES];
209
        unsigned long p;
210
        int sh_bang;
211
        int fd;
212
        int e_uid, e_gid;
213
        int argc, envc;
214
        char * filename;        /* Name of binary */
215
        unsigned long loader, exec;
216
        int dont_iput;          /* binfmt handler has put inode */
217
};
218

    
219
struct exec
220
{
221
  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
222
  unsigned int a_text;   /* length of text, in bytes */
223
  unsigned int a_data;   /* length of data, in bytes */
224
  unsigned int a_bss;    /* length of uninitialized data area, in bytes */
225
  unsigned int a_syms;   /* length of symbol table data in file, in bytes */
226
  unsigned int a_entry;  /* start address */
227
  unsigned int a_trsize; /* length of relocation info for text, in bytes */
228
  unsigned int a_drsize; /* length of relocation info for data, in bytes */
229
};
230

    
231

    
232
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
233
#define OMAGIC 0407
234
#define NMAGIC 0410
235
#define ZMAGIC 0413
236
#define QMAGIC 0314
237

    
238
/* max code+data+bss space allocated to elf interpreter */
239
#define INTERP_MAP_SIZE (32 * 1024 * 1024)
240

    
241
/* max code+data+bss+brk space allocated to ET_DYN executables */
242
#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
243

    
244
/* from personality.h */
245

    
246
/* Flags for bug emulation. These occupy the top three bytes. */
247
#define STICKY_TIMEOUTS                0x4000000
248
#define WHOLE_SECONDS                0x2000000
249

    
250
/* Personality types. These go in the low byte. Avoid using the top bit,
251
 * it will conflict with error returns.
252
 */
253
#define PER_MASK                (0x00ff)
254
#define PER_LINUX                (0x0000)
255
#define PER_SVR4                (0x0001 | STICKY_TIMEOUTS)
256
#define PER_SVR3                (0x0002 | STICKY_TIMEOUTS)
257
#define PER_SCOSVR3                (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
258
#define PER_WYSEV386                (0x0004 | STICKY_TIMEOUTS)
259
#define PER_ISCR4                (0x0005 | STICKY_TIMEOUTS)
260
#define PER_BSD                        (0x0006)
261
#define PER_XENIX                (0x0007 | STICKY_TIMEOUTS)
262

    
263
/* Necessary parameters */
264
#define NGROUPS 32
265

    
266
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
267
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
268
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
269

    
270
#define INTERPRETER_NONE 0
271
#define INTERPRETER_AOUT 1
272
#define INTERPRETER_ELF 2
273

    
274
#define DLINFO_ITEMS 11
275

    
276
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
277
{
278
        memcpy(to, from, n);
279
}
280

    
281
extern unsigned long x86_stack_size;
282

    
283
static int load_aout_interp(void * exptr, int interp_fd);
284

    
285
#ifdef BSWAP_NEEDED
286
static void bswap_ehdr(Elf32_Ehdr *ehdr)
287
{
288
    bswap16s(&ehdr->e_type);                        /* Object file type */
289
    bswap16s(&ehdr->e_machine);                /* Architecture */
290
    bswap32s(&ehdr->e_version);                /* Object file version */
291
    bswap32s(&ehdr->e_entry);                /* Entry point virtual address */
292
    bswap32s(&ehdr->e_phoff);                /* Program header table file offset */
293
    bswap32s(&ehdr->e_shoff);                /* Section header table file offset */
294
    bswap32s(&ehdr->e_flags);                /* Processor-specific flags */
295
    bswap16s(&ehdr->e_ehsize);                /* ELF header size in bytes */
296
    bswap16s(&ehdr->e_phentsize);                /* Program header table entry size */
297
    bswap16s(&ehdr->e_phnum);                /* Program header table entry count */
298
    bswap16s(&ehdr->e_shentsize);                /* Section header table entry size */
299
    bswap16s(&ehdr->e_shnum);                /* Section header table entry count */
300
    bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */
301
}
302

    
303
static void bswap_phdr(Elf32_Phdr *phdr)
304
{
305
    bswap32s(&phdr->p_type);                        /* Segment type */
306
    bswap32s(&phdr->p_offset);                /* Segment file offset */
307
    bswap32s(&phdr->p_vaddr);                /* Segment virtual address */
308
    bswap32s(&phdr->p_paddr);                /* Segment physical address */
309
    bswap32s(&phdr->p_filesz);                /* Segment size in file */
310
    bswap32s(&phdr->p_memsz);                /* Segment size in memory */
311
    bswap32s(&phdr->p_flags);                /* Segment flags */
312
    bswap32s(&phdr->p_align);                /* Segment alignment */
313
}
314

    
315
static void bswap_shdr(Elf32_Shdr *shdr)
316
{
317
    bswap32s(&shdr->sh_name);
318
    bswap32s(&shdr->sh_type);
319
    bswap32s(&shdr->sh_flags);
320
    bswap32s(&shdr->sh_addr);
321
    bswap32s(&shdr->sh_offset);
322
    bswap32s(&shdr->sh_size);
323
    bswap32s(&shdr->sh_link);
324
    bswap32s(&shdr->sh_info);
325
    bswap32s(&shdr->sh_addralign);
326
    bswap32s(&shdr->sh_entsize);
327
}
328

    
329
static void bswap_sym(Elf32_Sym *sym)
330
{
331
    bswap32s(&sym->st_name);
332
    bswap32s(&sym->st_value);
333
    bswap32s(&sym->st_size);
334
    bswap16s(&sym->st_shndx);
335
}
336
#endif
337

    
338
static void * get_free_page(void)
339
{
340
    void *        retval;
341

    
342
    /* User-space version of kernel get_free_page.  Returns a page-aligned
343
     * page-sized chunk of memory.
344
     */
345
    retval = (void *)target_mmap(0, qemu_host_page_size, PROT_READ|PROT_WRITE, 
346
                                 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
347

    
348
    if((long)retval == -1) {
349
        perror("get_free_page");
350
        exit(-1);
351
    }
352
    else {
353
        return(retval);
354
    }
355
}
356

    
357
static void free_page(void * pageaddr)
358
{
359
    target_munmap((unsigned long)pageaddr, qemu_host_page_size);
360
}
361

    
362
/*
363
 * 'copy_string()' copies argument/envelope strings from user
364
 * memory to free pages in kernel mem. These are in a format ready
365
 * to be put directly into the top of new user memory.
366
 *
367
 */
368
static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
369
                unsigned long p)
370
{
371
    char *tmp, *tmp1, *pag = NULL;
372
    int len, offset = 0;
373

    
374
    if (!p) {
375
        return 0;       /* bullet-proofing */
376
    }
377
    while (argc-- > 0) {
378
        tmp = argv[argc];
379
        if (!tmp) {
380
            fprintf(stderr, "VFS: argc is wrong");
381
            exit(-1);
382
        }
383
        tmp1 = tmp;
384
        while (*tmp++);
385
        len = tmp - tmp1;
386
        if (p < len) {  /* this shouldn't happen - 128kB */
387
                return 0;
388
        }
389
        while (len) {
390
            --p; --tmp; --len;
391
            if (--offset < 0) {
392
                offset = p % TARGET_PAGE_SIZE;
393
                pag = (char *) page[p/TARGET_PAGE_SIZE];
394
                if (!pag) {
395
                    pag = (char *)get_free_page();
396
                    page[p/TARGET_PAGE_SIZE] = (unsigned long)pag;
397
                    if (!pag)
398
                        return 0;
399
                }
400
            }
401
            if (len == 0 || offset == 0) {
402
                *(pag + offset) = *tmp;
403
            }
404
            else {
405
              int bytes_to_copy = (len > offset) ? offset : len;
406
              tmp -= bytes_to_copy;
407
              p -= bytes_to_copy;
408
              offset -= bytes_to_copy;
409
              len -= bytes_to_copy;
410
              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
411
            }
412
        }
413
    }
414
    return p;
415
}
416

    
417
static int in_group_p(gid_t g)
418
{
419
    /* return TRUE if we're in the specified group, FALSE otherwise */
420
    int                ngroup;
421
    int                i;
422
    gid_t        grouplist[NGROUPS];
423

    
424
    ngroup = getgroups(NGROUPS, grouplist);
425
    for(i = 0; i < ngroup; i++) {
426
        if(grouplist[i] == g) {
427
            return 1;
428
        }
429
    }
430
    return 0;
431
}
432

    
433
static int count(char ** vec)
434
{
435
    int                i;
436

    
437
    for(i = 0; *vec; i++) {
438
        vec++;
439
    }
440

    
441
    return(i);
442
}
443

    
444
static int prepare_binprm(struct linux_binprm *bprm)
445
{
446
    struct stat                st;
447
    int mode;
448
    int retval, id_change;
449

    
450
    if(fstat(bprm->fd, &st) < 0) {
451
        return(-errno);
452
    }
453

    
454
    mode = st.st_mode;
455
    if(!S_ISREG(mode)) {        /* Must be regular file */
456
        return(-EACCES);
457
    }
458
    if(!(mode & 0111)) {        /* Must have at least one execute bit set */
459
        return(-EACCES);
460
    }
461

    
462
    bprm->e_uid = geteuid();
463
    bprm->e_gid = getegid();
464
    id_change = 0;
465

    
466
    /* Set-uid? */
467
    if(mode & S_ISUID) {
468
            bprm->e_uid = st.st_uid;
469
        if(bprm->e_uid != geteuid()) {
470
            id_change = 1;
471
        }
472
    }
473

    
474
    /* Set-gid? */
475
    /*
476
     * If setgid is set but no group execute bit then this
477
     * is a candidate for mandatory locking, not a setgid
478
     * executable.
479
     */
480
    if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
481
        bprm->e_gid = st.st_gid;
482
        if (!in_group_p(bprm->e_gid)) {
483
                id_change = 1;
484
        }
485
    }
486

    
487
    memset(bprm->buf, 0, sizeof(bprm->buf));
488
    retval = lseek(bprm->fd, 0L, SEEK_SET);
489
    if(retval >= 0) {
490
        retval = read(bprm->fd, bprm->buf, 128);
491
    }
492
    if(retval < 0) {
493
        perror("prepare_binprm");
494
        exit(-1);
495
        /* return(-errno); */
496
    }
497
    else {
498
        return(retval);
499
    }
500
}
501

    
502
unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
503
                                                struct image_info * info)
504
{
505
    unsigned long stack_base, size, error;
506
    int i;
507

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

    
526
    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
527
    p += stack_base;
528

    
529
    if (bprm->loader) {
530
        bprm->loader += stack_base;
531
    }
532
    bprm->exec += stack_base;
533

    
534
    for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
535
        if (bprm->page[i]) {
536
            info->rss++;
537

    
538
            memcpy((void *)stack_base, (void *)bprm->page[i], TARGET_PAGE_SIZE);
539
            free_page((void *)bprm->page[i]);
540
        }
541
        stack_base += TARGET_PAGE_SIZE;
542
    }
543
    return p;
544
}
545

    
546
static void set_brk(unsigned long start, unsigned long end)
547
{
548
        /* page-align the start and end addresses... */
549
        start = HOST_PAGE_ALIGN(start);
550
        end = HOST_PAGE_ALIGN(end);
551
        if (end <= start)
552
                return;
553
        if(target_mmap(start, end - start,
554
                       PROT_READ | PROT_WRITE | PROT_EXEC,
555
                       MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
556
            perror("cannot mmap brk");
557
            exit(-1);
558
        }
559
}
560

    
561

    
562
/* We need to explicitly zero any fractional pages after the data
563
   section (i.e. bss).  This would contain the junk from the file that
564
   should not be in memory. */
565
static void padzero(unsigned long elf_bss)
566
{
567
        unsigned long nbyte;
568
        char * fpnt;
569

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

    
587
        nbyte = elf_bss & (qemu_host_page_size-1);
588
        if (nbyte) {
589
            nbyte = qemu_host_page_size - nbyte;
590
            fpnt = (char *) elf_bss;
591
            do {
592
                *fpnt++ = 0;
593
            } while (--nbyte);
594
        }
595
}
596

    
597
static unsigned int * create_elf_tables(char *p, int argc, int envc,
598
                                        struct elfhdr * exec,
599
                                        unsigned long load_addr,
600
                                        unsigned long load_bias,
601
                                        unsigned long interp_load_addr, int ibcs,
602
                                        struct image_info *info)
603
{
604
        target_ulong *argv, *envp;
605
        target_ulong *sp, *csp;
606
        int v;
607

    
608
        /*
609
         * Force 16 byte _final_ alignment here for generality.
610
         */
611
        sp = (unsigned int *) (~15UL & (unsigned long) p);
612
        csp = sp;
613
        csp -= (DLINFO_ITEMS + 1) * 2;
614
#ifdef DLINFO_ARCH_ITEMS
615
        csp -= DLINFO_ARCH_ITEMS*2;
616
#endif
617
        csp -= envc+1;
618
        csp -= argc+1;
619
        csp -= (!ibcs ? 3 : 1);        /* argc itself */
620
        if ((unsigned long)csp & 15UL)
621
            sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
622
        
623
#define NEW_AUX_ENT(nr, id, val) \
624
          put_user (id, sp + (nr * 2)); \
625
          put_user (val, sp + (nr * 2 + 1))
626
        sp -= 2;
627
        NEW_AUX_ENT (0, AT_NULL, 0);
628

    
629
        sp -= DLINFO_ITEMS*2;
630
        NEW_AUX_ENT( 0, AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
631
        NEW_AUX_ENT( 1, AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
632
        NEW_AUX_ENT( 2, AT_PHNUM, (target_ulong)(exec->e_phnum));
633
        NEW_AUX_ENT( 3, AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
634
        NEW_AUX_ENT( 4, AT_BASE, (target_ulong)(interp_load_addr));
635
        NEW_AUX_ENT( 5, AT_FLAGS, (target_ulong)0);
636
        NEW_AUX_ENT( 6, AT_ENTRY, load_bias + exec->e_entry);
637
        NEW_AUX_ENT( 7, AT_UID, (target_ulong) getuid());
638
        NEW_AUX_ENT( 8, AT_EUID, (target_ulong) geteuid());
639
        NEW_AUX_ENT( 9, AT_GID, (target_ulong) getgid());
640
        NEW_AUX_ENT(11, AT_EGID, (target_ulong) getegid());
641
#ifdef ARCH_DLINFO
642
        /* 
643
         * ARCH_DLINFO must come last so platform specific code can enforce
644
         * special alignment requirements on the AUXV if necessary (eg. PPC).
645
         */
646
        ARCH_DLINFO;
647
#endif
648
#undef NEW_AUX_ENT
649

    
650
        sp -= envc+1;
651
        envp = sp;
652
        sp -= argc+1;
653
        argv = sp;
654
        if (!ibcs) {
655
                put_user((target_ulong)envp,--sp);
656
                put_user((target_ulong)argv,--sp);
657
        }
658
        put_user(argc,--sp);
659
        info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
660
        while (argc-->0) {
661
                put_user((target_ulong)p,argv++);
662
                do {
663
                    get_user(v, p);
664
                    p++;
665
                } while (v != 0);
666
        }
667
        put_user(0,argv);
668
        info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
669
        while (envc-->0) {
670
                put_user((target_ulong)p,envp++);
671
                do {
672
                    get_user(v, p);
673
                    p++;
674
                } while (v != 0);
675
        }
676
        put_user(0,envp);
677
        info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
678
        return sp;
679
}
680

    
681

    
682

    
683
static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
684
                                     int interpreter_fd,
685
                                     unsigned long *interp_load_addr)
686
{
687
        struct elf_phdr *elf_phdata  =  NULL;
688
        struct elf_phdr *eppnt;
689
        unsigned long load_addr = 0;
690
        int load_addr_set = 0;
691
        int retval;
692
        unsigned long last_bss, elf_bss;
693
        unsigned long error;
694
        int i;
695
        
696
        elf_bss = 0;
697
        last_bss = 0;
698
        error = 0;
699

    
700
#ifdef BSWAP_NEEDED
701
        bswap_ehdr(interp_elf_ex);
702
#endif
703
        /* First of all, some simple consistency checks */
704
        if ((interp_elf_ex->e_type != ET_EXEC && 
705
             interp_elf_ex->e_type != ET_DYN) || 
706
           !elf_check_arch(interp_elf_ex->e_machine)) {
707
                return ~0UL;
708
        }
709
        
710

    
711
        /* Now read in all of the header information */
712
        
713
        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
714
            return ~0UL;
715
        
716
        elf_phdata =  (struct elf_phdr *) 
717
                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
718

    
719
        if (!elf_phdata)
720
          return ~0UL;
721
        
722
        /*
723
         * If the size of this structure has changed, then punt, since
724
         * we will be doing the wrong thing.
725
         */
726
        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
727
            free(elf_phdata);
728
            return ~0UL;
729
        }
730

    
731
        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
732
        if(retval >= 0) {
733
            retval = read(interpreter_fd,
734
                           (char *) elf_phdata,
735
                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
736
        }
737
        if (retval < 0) {
738
                perror("load_elf_interp");
739
                exit(-1);
740
                free (elf_phdata);
741
                return retval;
742
         }
743
#ifdef BSWAP_NEEDED
744
        eppnt = elf_phdata;
745
        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
746
            bswap_phdr(eppnt);
747
        }
748
#endif
749

    
750
        if (interp_elf_ex->e_type == ET_DYN) {
751
            /* in order to avoid harcoding the interpreter load
752
               address in qemu, we allocate a big enough memory zone */
753
            error = target_mmap(0, INTERP_MAP_SIZE,
754
                                PROT_NONE, MAP_PRIVATE | MAP_ANON, 
755
                                -1, 0);
756
            if (error == -1) {
757
                perror("mmap");
758
                exit(-1);
759
            }
760
            load_addr = error;
761
            load_addr_set = 1;
762
        }
763

    
764
        eppnt = elf_phdata;
765
        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
766
          if (eppnt->p_type == PT_LOAD) {
767
            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
768
            int elf_prot = 0;
769
            unsigned long vaddr = 0;
770
            unsigned long k;
771

    
772
            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
773
            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
774
            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
775
            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
776
                    elf_type |= MAP_FIXED;
777
                    vaddr = eppnt->p_vaddr;
778
            }
779
            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
780
                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
781
                 elf_prot,
782
                 elf_type,
783
                 interpreter_fd,
784
                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
785
            
786
            if (error > -1024UL) {
787
              /* Real error */
788
              close(interpreter_fd);
789
              free(elf_phdata);
790
              return ~0UL;
791
            }
792

    
793
            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
794
              load_addr = error;
795
              load_addr_set = 1;
796
            }
797

    
798
            /*
799
             * Find the end of the file  mapping for this phdr, and keep
800
             * track of the largest address we see for this.
801
             */
802
            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
803
            if (k > elf_bss) elf_bss = k;
804

    
805
            /*
806
             * Do the same thing for the memory mapping - between
807
             * elf_bss and last_bss is the bss section.
808
             */
809
            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
810
            if (k > last_bss) last_bss = k;
811
          }
812
        
813
        /* Now use mmap to map the library into memory. */
814

    
815
        close(interpreter_fd);
816

    
817
        /*
818
         * Now fill out the bss section.  First pad the last page up
819
         * to the page boundary, and then perform a mmap to make sure
820
         * that there are zeromapped pages up to and including the last
821
         * bss page.
822
         */
823
        padzero(elf_bss);
824
        elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */
825

    
826
        /* Map the last of the bss segment */
827
        if (last_bss > elf_bss) {
828
            target_mmap(elf_bss, last_bss-elf_bss,
829
                        PROT_READ|PROT_WRITE|PROT_EXEC,
830
                        MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
831
        }
832
        free(elf_phdata);
833

    
834
        *interp_load_addr = load_addr;
835
        return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
836
}
837

    
838
/* Best attempt to load symbols from this ELF object. */
839
static void load_symbols(struct elfhdr *hdr, int fd)
840
{
841
    unsigned int i;
842
    struct elf_shdr sechdr, symtab, strtab;
843
    char *strings;
844
    struct syminfo *s;
845

    
846
    lseek(fd, hdr->e_shoff, SEEK_SET);
847
    for (i = 0; i < hdr->e_shnum; i++) {
848
        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
849
            return;
850
#ifdef BSWAP_NEEDED
851
        bswap_shdr(&sechdr);
852
#endif
853
        if (sechdr.sh_type == SHT_SYMTAB) {
854
            symtab = sechdr;
855
            lseek(fd, hdr->e_shoff
856
                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
857
            if (read(fd, &strtab, sizeof(strtab))
858
                != sizeof(strtab))
859
                return;
860
#ifdef BSWAP_NEEDED
861
            bswap_shdr(&strtab);
862
#endif
863
            goto found;
864
        }
865
    }
866
    return; /* Shouldn't happen... */
867

    
868
 found:
869
    /* Now know where the strtab and symtab are.  Snarf them. */
870
    s = malloc(sizeof(*s));
871
    s->disas_symtab = malloc(symtab.sh_size);
872
    s->disas_strtab = strings = malloc(strtab.sh_size);
873
    if (!s->disas_symtab || !s->disas_strtab)
874
        return;
875
        
876
    lseek(fd, symtab.sh_offset, SEEK_SET);
877
    if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
878
        return;
879

    
880
#ifdef BSWAP_NEEDED
881
    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
882
        bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
883
#endif
884

    
885
    lseek(fd, strtab.sh_offset, SEEK_SET);
886
    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
887
        return;
888
    s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
889
    s->next = syminfos;
890
    syminfos = s;
891
}
892

    
893
static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
894
                           struct image_info * info)
895
{
896
    struct elfhdr elf_ex;
897
    struct elfhdr interp_elf_ex;
898
    struct exec interp_ex;
899
    int interpreter_fd = -1; /* avoid warning */
900
    unsigned long load_addr, load_bias;
901
    int load_addr_set = 0;
902
    unsigned int interpreter_type = INTERPRETER_NONE;
903
    unsigned char ibcs2_interpreter;
904
    int i;
905
    unsigned long mapped_addr;
906
    struct elf_phdr * elf_ppnt;
907
    struct elf_phdr *elf_phdata;
908
    unsigned long elf_bss, k, elf_brk;
909
    int retval;
910
    char * elf_interpreter;
911
    unsigned long elf_entry, interp_load_addr = 0;
912
    int status;
913
    unsigned long start_code, end_code, end_data;
914
    unsigned long elf_stack;
915
    char passed_fileno[6];
916

    
917
    ibcs2_interpreter = 0;
918
    status = 0;
919
    load_addr = 0;
920
    load_bias = 0;
921
    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
922
#ifdef BSWAP_NEEDED
923
    bswap_ehdr(&elf_ex);
924
#endif
925

    
926
    if (elf_ex.e_ident[0] != 0x7f ||
927
        strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
928
            return  -ENOEXEC;
929
    }
930

    
931
    /* First of all, some simple consistency checks */
932
    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
933
                                       (! elf_check_arch(elf_ex.e_machine))) {
934
            return -ENOEXEC;
935
    }
936

    
937
    /* Now read in all of the header information */
938
    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
939
    if (elf_phdata == NULL) {
940
        return -ENOMEM;
941
    }
942

    
943
    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
944
    if(retval > 0) {
945
        retval = read(bprm->fd, (char *) elf_phdata, 
946
                                elf_ex.e_phentsize * elf_ex.e_phnum);
947
    }
948

    
949
    if (retval < 0) {
950
        perror("load_elf_binary");
951
        exit(-1);
952
        free (elf_phdata);
953
        return -errno;
954
    }
955

    
956
#ifdef BSWAP_NEEDED
957
    elf_ppnt = elf_phdata;
958
    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
959
        bswap_phdr(elf_ppnt);
960
    }
961
#endif
962
    elf_ppnt = elf_phdata;
963

    
964
    elf_bss = 0;
965
    elf_brk = 0;
966

    
967

    
968
    elf_stack = ~0UL;
969
    elf_interpreter = NULL;
970
    start_code = ~0UL;
971
    end_code = 0;
972
    end_data = 0;
973

    
974
    for(i=0;i < elf_ex.e_phnum; i++) {
975
        if (elf_ppnt->p_type == PT_INTERP) {
976
            if ( elf_interpreter != NULL )
977
            {
978
                free (elf_phdata);
979
                free(elf_interpreter);
980
                close(bprm->fd);
981
                return -EINVAL;
982
            }
983

    
984
            /* This is the program interpreter used for
985
             * shared libraries - for now assume that this
986
             * is an a.out format binary
987
             */
988

    
989
            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
990

    
991
            if (elf_interpreter == NULL) {
992
                free (elf_phdata);
993
                close(bprm->fd);
994
                return -ENOMEM;
995
            }
996

    
997
            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
998
            if(retval >= 0) {
999
                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
1000
            }
1001
            if(retval < 0) {
1002
                 perror("load_elf_binary2");
1003
                exit(-1);
1004
            }        
1005

    
1006
            /* If the program interpreter is one of these two,
1007
               then assume an iBCS2 image. Otherwise assume
1008
               a native linux image. */
1009

    
1010
            /* JRP - Need to add X86 lib dir stuff here... */
1011

    
1012
            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
1013
                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
1014
              ibcs2_interpreter = 1;
1015
            }
1016

    
1017
#if 0
1018
            printf("Using ELF interpreter %s\n", elf_interpreter);
1019
#endif
1020
            if (retval >= 0) {
1021
                retval = open(path(elf_interpreter), O_RDONLY);
1022
                if(retval >= 0) {
1023
                    interpreter_fd = retval;
1024
                }
1025
                else {
1026
                    perror(elf_interpreter);
1027
                    exit(-1);
1028
                    /* retval = -errno; */
1029
                }
1030
            }
1031

    
1032
            if (retval >= 0) {
1033
                retval = lseek(interpreter_fd, 0, SEEK_SET);
1034
                if(retval >= 0) {
1035
                    retval = read(interpreter_fd,bprm->buf,128);
1036
                }
1037
            }
1038
            if (retval >= 0) {
1039
                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
1040
                interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
1041
            }
1042
            if (retval < 0) {
1043
                perror("load_elf_binary3");
1044
                exit(-1);
1045
                free (elf_phdata);
1046
                free(elf_interpreter);
1047
                close(bprm->fd);
1048
                return retval;
1049
            }
1050
        }
1051
        elf_ppnt++;
1052
    }
1053

    
1054
    /* Some simple consistency checks for the interpreter */
1055
    if (elf_interpreter){
1056
        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1057

    
1058
        /* Now figure out which format our binary is */
1059
        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
1060
                    (N_MAGIC(interp_ex) != QMAGIC)) {
1061
          interpreter_type = INTERPRETER_ELF;
1062
        }
1063

    
1064
        if (interp_elf_ex.e_ident[0] != 0x7f ||
1065
                    strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1066
            interpreter_type &= ~INTERPRETER_ELF;
1067
        }
1068

    
1069
        if (!interpreter_type) {
1070
            free(elf_interpreter);
1071
            free(elf_phdata);
1072
            close(bprm->fd);
1073
            return -ELIBBAD;
1074
        }
1075
    }
1076

    
1077
    /* OK, we are done with that, now set up the arg stuff,
1078
       and then start this sucker up */
1079

    
1080
    if (!bprm->sh_bang) {
1081
        char * passed_p;
1082

    
1083
        if (interpreter_type == INTERPRETER_AOUT) {
1084
            snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd);
1085
            passed_p = passed_fileno;
1086

    
1087
            if (elf_interpreter) {
1088
                bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
1089
                bprm->argc++;
1090
            }
1091
        }
1092
        if (!bprm->p) {
1093
            if (elf_interpreter) {
1094
                free(elf_interpreter);
1095
            }
1096
            free (elf_phdata);
1097
            close(bprm->fd);
1098
            return -E2BIG;
1099
        }
1100
    }
1101

    
1102
    /* OK, This is the point of no return */
1103
    info->end_data = 0;
1104
    info->end_code = 0;
1105
    info->start_mmap = (unsigned long)ELF_START_MMAP;
1106
    info->mmap = 0;
1107
    elf_entry = (unsigned long) elf_ex.e_entry;
1108

    
1109
    /* Do this so that we can load the interpreter, if need be.  We will
1110
       change some of these later */
1111
    info->rss = 0;
1112
    bprm->p = setup_arg_pages(bprm->p, bprm, info);
1113
    info->start_stack = bprm->p;
1114

    
1115
    /* Now we do a little grungy work by mmaping the ELF image into
1116
     * the correct location in memory.  At this point, we assume that
1117
     * the image should be loaded at fixed address, not at a variable
1118
     * address.
1119
     */
1120

    
1121
    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1122
        int elf_prot = 0;
1123
        int elf_flags = 0;
1124
        unsigned long error;
1125
        
1126
        if (elf_ppnt->p_type != PT_LOAD)
1127
            continue;
1128
        
1129
        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
1130
        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
1131
        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
1132
        elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
1133
        if (elf_ex.e_type == ET_EXEC || load_addr_set) {
1134
            elf_flags |= MAP_FIXED;
1135
        } else if (elf_ex.e_type == ET_DYN) {
1136
            /* Try and get dynamic programs out of the way of the default mmap
1137
               base, as well as whatever program they might try to exec.  This
1138
               is because the brk will follow the loader, and is not movable.  */
1139
            /* NOTE: for qemu, we do a big mmap to get enough space
1140
               without harcoding any address */
1141
            error = target_mmap(0, ET_DYN_MAP_SIZE,
1142
                                PROT_NONE, MAP_PRIVATE | MAP_ANON, 
1143
                                -1, 0);
1144
            if (error == -1) {
1145
                perror("mmap");
1146
                exit(-1);
1147
            }
1148
            load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
1149
        }
1150
        
1151
        error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
1152
                            (elf_ppnt->p_filesz +
1153
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
1154
                            elf_prot,
1155
                            (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
1156
                            bprm->fd,
1157
                            (elf_ppnt->p_offset - 
1158
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
1159
        if (error == -1) {
1160
            perror("mmap");
1161
            exit(-1);
1162
        }
1163

    
1164
#ifdef LOW_ELF_STACK
1165
        if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1166
            elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
1167
#endif
1168
        
1169
        if (!load_addr_set) {
1170
            load_addr_set = 1;
1171
            load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1172
            if (elf_ex.e_type == ET_DYN) {
1173
                load_bias += error -
1174
                    TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
1175
                load_addr += load_bias;
1176
            }
1177
        }
1178
        k = elf_ppnt->p_vaddr;
1179
        if (k < start_code) 
1180
            start_code = k;
1181
        k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1182
        if (k > elf_bss) 
1183
            elf_bss = k;
1184
        if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
1185
            end_code = k;
1186
        if (end_data < k) 
1187
            end_data = k;
1188
        k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1189
        if (k > elf_brk) elf_brk = k;
1190
    }
1191

    
1192
    elf_entry += load_bias;
1193
    elf_bss += load_bias;
1194
    elf_brk += load_bias;
1195
    start_code += load_bias;
1196
    end_code += load_bias;
1197
    //    start_data += load_bias;
1198
    end_data += load_bias;
1199

    
1200
    if (elf_interpreter) {
1201
        if (interpreter_type & 1) {
1202
            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1203
        }
1204
        else if (interpreter_type & 2) {
1205
            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1206
                                            &interp_load_addr);
1207
        }
1208

    
1209
        close(interpreter_fd);
1210
        free(elf_interpreter);
1211

    
1212
        if (elf_entry == ~0UL) {
1213
            printf("Unable to load interpreter\n");
1214
            free(elf_phdata);
1215
            exit(-1);
1216
            return 0;
1217
        }
1218
    }
1219

    
1220
    free(elf_phdata);
1221

    
1222
    if (loglevel)
1223
        load_symbols(&elf_ex, bprm->fd);
1224

    
1225
    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1226
    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1227

    
1228
#ifdef LOW_ELF_STACK
1229
    info->start_stack = bprm->p = elf_stack - 4;
1230
#endif
1231
    bprm->p = (unsigned long)
1232
      create_elf_tables((char *)bprm->p,
1233
                    bprm->argc,
1234
                    bprm->envc,
1235
                    &elf_ex,
1236
                    load_addr, load_bias,
1237
                    interp_load_addr,
1238
                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1239
                    info);
1240
    if (interpreter_type == INTERPRETER_AOUT)
1241
      info->arg_start += strlen(passed_fileno) + 1;
1242
    info->start_brk = info->brk = elf_brk;
1243
    info->end_code = end_code;
1244
    info->start_code = start_code;
1245
    info->end_data = end_data;
1246
    info->start_stack = bprm->p;
1247

    
1248
    /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1249
       sections */
1250
    set_brk(elf_bss, elf_brk);
1251

    
1252
    padzero(elf_bss);
1253

    
1254
#if 0
1255
    printf("(start_brk) %x\n" , info->start_brk);
1256
    printf("(end_code) %x\n" , info->end_code);
1257
    printf("(start_code) %x\n" , info->start_code);
1258
    printf("(end_data) %x\n" , info->end_data);
1259
    printf("(start_stack) %x\n" , info->start_stack);
1260
    printf("(brk) %x\n" , info->brk);
1261
#endif
1262

    
1263
    if ( info->personality == PER_SVR4 )
1264
    {
1265
            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1266
               and some applications "depend" upon this behavior.
1267
               Since we do not have the power to recompile these, we
1268
               emulate the SVr4 behavior.  Sigh.  */
1269
            mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
1270
                                      MAP_FIXED | MAP_PRIVATE, -1, 0);
1271
    }
1272

    
1273
#ifdef ELF_PLAT_INIT
1274
    /*
1275
     * The ABI may specify that certain registers be set up in special
1276
     * ways (on i386 %edx is the address of a DT_FINI function, for
1277
     * example.  This macro performs whatever initialization to
1278
     * the regs structure is required.
1279
     */
1280
    ELF_PLAT_INIT(regs);
1281
#endif
1282

    
1283

    
1284
    info->entry = elf_entry;
1285

    
1286
    return 0;
1287
}
1288

    
1289

    
1290

    
1291
int elf_exec(const char * filename, char ** argv, char ** envp, 
1292
             struct target_pt_regs * regs, struct image_info *infop)
1293
{
1294
        struct linux_binprm bprm;
1295
        int retval;
1296
        int i;
1297

    
1298
        bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1299
        for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
1300
                bprm.page[i] = 0;
1301
        retval = open(filename, O_RDONLY);
1302
        if (retval < 0)
1303
            return retval;
1304
        bprm.fd = retval;
1305
        bprm.filename = (char *)filename;
1306
        bprm.sh_bang = 0;
1307
        bprm.loader = 0;
1308
        bprm.exec = 0;
1309
        bprm.dont_iput = 0;
1310
        bprm.argc = count(argv);
1311
        bprm.envc = count(envp);
1312

    
1313
        retval = prepare_binprm(&bprm);
1314

    
1315
        if(retval>=0) {
1316
            bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1317
            bprm.exec = bprm.p;
1318
            bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1319
            bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1320
            if (!bprm.p) {
1321
                retval = -E2BIG;
1322
            }
1323
        }
1324

    
1325
        if(retval>=0) {
1326
            retval = load_elf_binary(&bprm,regs,infop);
1327
        }
1328
        if(retval>=0) {
1329
            /* success.  Initialize important registers */
1330
            init_thread(regs, infop);
1331
            return retval;
1332
        }
1333

    
1334
        /* Something went wrong, return the inode and free the argument pages*/
1335
        for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1336
            free_page((void *)bprm.page[i]);
1337
        }
1338
        return(retval);
1339
}
1340

    
1341

    
1342
static int load_aout_interp(void * exptr, int interp_fd)
1343
{
1344
    printf("a.out interpreter not yet supported\n");
1345
    return(0);
1346
}
1347