Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ 274da6b2

History | View | Annotate | Download (37.4 kB)

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

    
3
#include <stdio.h>
4
#include <sys/types.h>
5
#include <fcntl.h>
6
#include <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
#ifdef TARGET_I386
17

    
18
#define ELF_START_MMAP 0x80000000
19

    
20
/*
21
 * This is used to ensure we don't load something for the wrong architecture.
22
 */
23
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
24

    
25
/*
26
 * These are used to set parameters in the core dumps.
27
 */
28
#define ELF_CLASS        ELFCLASS32
29
#define ELF_DATA        ELFDATA2LSB
30
#define ELF_ARCH        EM_386
31

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

38
           A value of 0 tells we have no such handler.  */
39
#define ELF_PLAT_INIT(_r)        _r->edx = 0
40

    
41
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
42
{
43
    regs->esp = infop->start_stack;
44
    regs->eip = infop->entry;
45
}
46

    
47
#define USE_ELF_CORE_DUMP
48
#define ELF_EXEC_PAGESIZE        4096
49

    
50
#endif
51

    
52
#ifdef TARGET_ARM
53

    
54
#define ELF_START_MMAP 0x80000000
55

    
56
#define elf_check_arch(x) ( (x) == EM_ARM )
57

    
58
#define ELF_CLASS        ELFCLASS32
59
#ifdef TARGET_WORDS_BIGENDIAN
60
#define ELF_DATA        ELFDATA2MSB
61
#else
62
#define ELF_DATA        ELFDATA2LSB
63
#endif
64
#define ELF_ARCH        EM_ARM
65

    
66
#define ELF_PLAT_INIT(_r)        _r->ARM_r0 = 0
67

    
68
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
69
{
70
    target_long *stack = (void *)infop->start_stack;
71
    memset(regs, 0, sizeof(*regs));
72
    regs->ARM_cpsr = 0x10;
73
    regs->ARM_pc = infop->entry;
74
    regs->ARM_sp = infop->start_stack;
75
    regs->ARM_r2 = tswapl(stack[2]); /* envp */
76
    regs->ARM_r1 = tswapl(stack[1]); /* argv */
77
    /* XXX: it seems that r0 is zeroed after ! */
78
    //    regs->ARM_r0 = tswapl(stack[0]); /* argc */
79
}
80

    
81
#define USE_ELF_CORE_DUMP
82
#define ELF_EXEC_PAGESIZE        4096
83

    
84
#endif
85

    
86
#ifdef TARGET_SPARC
87

    
88
#define ELF_START_MMAP 0x80000000
89

    
90
#define elf_check_arch(x) ( (x) == EM_SPARC )
91

    
92
#define ELF_CLASS   ELFCLASS32
93
#define ELF_DATA    ELFDATA2MSB
94
#define ELF_ARCH    EM_SPARC
95

    
96
/*XXX*/
97
#define ELF_PLAT_INIT(_r)
98

    
99
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
100
{
101
    regs->psr = 0;
102
    regs->pc = infop->entry;
103
    regs->npc = regs->pc + 4;
104
    regs->y = 0;
105
    regs->u_regs[14] = infop->start_stack - 16 * 4;
106
}
107

    
108
#endif
109

    
110
#ifdef TARGET_PPC
111

    
112
#define ELF_START_MMAP 0x80000000
113

    
114
#define elf_check_arch(x) ( (x) == EM_PPC )
115

    
116
#define ELF_CLASS        ELFCLASS32
117
#ifdef TARGET_WORDS_BIGENDIAN
118
#define ELF_DATA        ELFDATA2MSB
119
#else
120
#define ELF_DATA        ELFDATA2LSB
121
#endif
122
#define ELF_ARCH        EM_PPC
123

    
124
/* Note that isn't exactly what regular kernel does
125
 * but this is what the ABI wants and is needed to allow
126
 * execution of PPC BSD programs.
127
 */
128
#define ELF_PLAT_INIT(_r)                                  \
129
do {                                                       \
130
    target_ulong *pos = (target_ulong *)bprm->p, tmp = 1;  \
131
    _r->gpr[3] = bprm->argc;                               \
132
    _r->gpr[4] = (unsigned long)++pos;                     \
133
    for (; tmp != 0; pos++)                                \
134
        tmp = *pos;                                        \
135
    _r->gpr[5] = (unsigned long)pos;                       \
136
} while (0)
137

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

    
171
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
172
{
173
    _regs->msr = 1 << MSR_PR; /* Set user mode */
174
    _regs->gpr[1] = infop->start_stack;
175
    _regs->nip = infop->entry;
176
}
177

    
178
#define USE_ELF_CORE_DUMP
179
#define ELF_EXEC_PAGESIZE        4096
180

    
181
#endif
182

    
183
#include "elf.h"
184

    
185
/*
186
 * MAX_ARG_PAGES defines the number of pages allocated for arguments
187
 * and envelope for the new program. 32 should suffice, this gives
188
 * a maximum env+arg of 128kB w/4KB pages!
189
 */
190
#define MAX_ARG_PAGES 32
191

    
192
/*
193
 * This structure is used to hold the arguments that are 
194
 * used when loading binaries.
195
 */
196
struct linux_binprm {
197
        char buf[128];
198
        unsigned long page[MAX_ARG_PAGES];
199
        unsigned long p;
200
        int sh_bang;
201
        int fd;
202
        int e_uid, e_gid;
203
        int argc, envc;
204
        char * filename;        /* Name of binary */
205
        unsigned long loader, exec;
206
        int dont_iput;          /* binfmt handler has put inode */
207
};
208

    
209
struct exec
210
{
211
  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
212
  unsigned int a_text;   /* length of text, in bytes */
213
  unsigned int a_data;   /* length of data, in bytes */
214
  unsigned int a_bss;    /* length of uninitialized data area, in bytes */
215
  unsigned int a_syms;   /* length of symbol table data in file, in bytes */
216
  unsigned int a_entry;  /* start address */
217
  unsigned int a_trsize; /* length of relocation info for text, in bytes */
218
  unsigned int a_drsize; /* length of relocation info for data, in bytes */
219
};
220

    
221

    
222
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
223
#define OMAGIC 0407
224
#define NMAGIC 0410
225
#define ZMAGIC 0413
226
#define QMAGIC 0314
227

    
228
/* max code+data+bss space allocated to elf interpreter */
229
#define INTERP_MAP_SIZE (32 * 1024 * 1024)
230

    
231
/* max code+data+bss+brk space allocated to ET_DYN executables */
232
#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
233

    
234
/* from personality.h */
235

    
236
/* Flags for bug emulation. These occupy the top three bytes. */
237
#define STICKY_TIMEOUTS                0x4000000
238
#define WHOLE_SECONDS                0x2000000
239

    
240
/* Personality types. These go in the low byte. Avoid using the top bit,
241
 * it will conflict with error returns.
242
 */
243
#define PER_MASK                (0x00ff)
244
#define PER_LINUX                (0x0000)
245
#define PER_SVR4                (0x0001 | STICKY_TIMEOUTS)
246
#define PER_SVR3                (0x0002 | STICKY_TIMEOUTS)
247
#define PER_SCOSVR3                (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
248
#define PER_WYSEV386                (0x0004 | STICKY_TIMEOUTS)
249
#define PER_ISCR4                (0x0005 | STICKY_TIMEOUTS)
250
#define PER_BSD                        (0x0006)
251
#define PER_XENIX                (0x0007 | STICKY_TIMEOUTS)
252

    
253
/* Necessary parameters */
254
#define NGROUPS 32
255

    
256
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
257
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
258
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
259

    
260
#define INTERPRETER_NONE 0
261
#define INTERPRETER_AOUT 1
262
#define INTERPRETER_ELF 2
263

    
264
#define DLINFO_ITEMS 11
265

    
266
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
267
{
268
        memcpy(to, from, n);
269
}
270

    
271
extern unsigned long x86_stack_size;
272

    
273
static int load_aout_interp(void * exptr, int interp_fd);
274

    
275
#ifdef BSWAP_NEEDED
276
static void bswap_ehdr(Elf32_Ehdr *ehdr)
277
{
278
    bswap16s(&ehdr->e_type);                        /* Object file type */
279
    bswap16s(&ehdr->e_machine);                /* Architecture */
280
    bswap32s(&ehdr->e_version);                /* Object file version */
281
    bswap32s(&ehdr->e_entry);                /* Entry point virtual address */
282
    bswap32s(&ehdr->e_phoff);                /* Program header table file offset */
283
    bswap32s(&ehdr->e_shoff);                /* Section header table file offset */
284
    bswap32s(&ehdr->e_flags);                /* Processor-specific flags */
285
    bswap16s(&ehdr->e_ehsize);                /* ELF header size in bytes */
286
    bswap16s(&ehdr->e_phentsize);                /* Program header table entry size */
287
    bswap16s(&ehdr->e_phnum);                /* Program header table entry count */
288
    bswap16s(&ehdr->e_shentsize);                /* Section header table entry size */
289
    bswap16s(&ehdr->e_shnum);                /* Section header table entry count */
290
    bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */
291
}
292

    
293
static void bswap_phdr(Elf32_Phdr *phdr)
294
{
295
    bswap32s(&phdr->p_type);                        /* Segment type */
296
    bswap32s(&phdr->p_offset);                /* Segment file offset */
297
    bswap32s(&phdr->p_vaddr);                /* Segment virtual address */
298
    bswap32s(&phdr->p_paddr);                /* Segment physical address */
299
    bswap32s(&phdr->p_filesz);                /* Segment size in file */
300
    bswap32s(&phdr->p_memsz);                /* Segment size in memory */
301
    bswap32s(&phdr->p_flags);                /* Segment flags */
302
    bswap32s(&phdr->p_align);                /* Segment alignment */
303
}
304

    
305
static void bswap_shdr(Elf32_Shdr *shdr)
306
{
307
    bswap32s(&shdr->sh_name);
308
    bswap32s(&shdr->sh_type);
309
    bswap32s(&shdr->sh_flags);
310
    bswap32s(&shdr->sh_addr);
311
    bswap32s(&shdr->sh_offset);
312
    bswap32s(&shdr->sh_size);
313
    bswap32s(&shdr->sh_link);
314
    bswap32s(&shdr->sh_info);
315
    bswap32s(&shdr->sh_addralign);
316
    bswap32s(&shdr->sh_entsize);
317
}
318

    
319
static void bswap_sym(Elf32_Sym *sym)
320
{
321
    bswap32s(&sym->st_name);
322
    bswap32s(&sym->st_value);
323
    bswap32s(&sym->st_size);
324
    bswap16s(&sym->st_shndx);
325
}
326
#endif
327

    
328
static void * get_free_page(void)
329
{
330
    void *        retval;
331

    
332
    /* User-space version of kernel get_free_page.  Returns a page-aligned
333
     * page-sized chunk of memory.
334
     */
335
    retval = (void *)target_mmap(0, host_page_size, PROT_READ|PROT_WRITE, 
336
                                 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
337

    
338
    if((long)retval == -1) {
339
        perror("get_free_page");
340
        exit(-1);
341
    }
342
    else {
343
        return(retval);
344
    }
345
}
346

    
347
static void free_page(void * pageaddr)
348
{
349
    target_munmap((unsigned long)pageaddr, host_page_size);
350
}
351

    
352
/*
353
 * 'copy_string()' copies argument/envelope strings from user
354
 * memory to free pages in kernel mem. These are in a format ready
355
 * to be put directly into the top of new user memory.
356
 *
357
 */
358
static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
359
                unsigned long p)
360
{
361
    char *tmp, *tmp1, *pag = NULL;
362
    int len, offset = 0;
363

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

    
407
static int in_group_p(gid_t g)
408
{
409
    /* return TRUE if we're in the specified group, FALSE otherwise */
410
    int                ngroup;
411
    int                i;
412
    gid_t        grouplist[NGROUPS];
413

    
414
    ngroup = getgroups(NGROUPS, grouplist);
415
    for(i = 0; i < ngroup; i++) {
416
        if(grouplist[i] == g) {
417
            return 1;
418
        }
419
    }
420
    return 0;
421
}
422

    
423
static int count(char ** vec)
424
{
425
    int                i;
426

    
427
    for(i = 0; *vec; i++) {
428
        vec++;
429
    }
430

    
431
    return(i);
432
}
433

    
434
static int prepare_binprm(struct linux_binprm *bprm)
435
{
436
    struct stat                st;
437
    int mode;
438
    int retval, id_change;
439

    
440
    if(fstat(bprm->fd, &st) < 0) {
441
        return(-errno);
442
    }
443

    
444
    mode = st.st_mode;
445
    if(!S_ISREG(mode)) {        /* Must be regular file */
446
        return(-EACCES);
447
    }
448
    if(!(mode & 0111)) {        /* Must have at least one execute bit set */
449
        return(-EACCES);
450
    }
451

    
452
    bprm->e_uid = geteuid();
453
    bprm->e_gid = getegid();
454
    id_change = 0;
455

    
456
    /* Set-uid? */
457
    if(mode & S_ISUID) {
458
            bprm->e_uid = st.st_uid;
459
        if(bprm->e_uid != geteuid()) {
460
            id_change = 1;
461
        }
462
    }
463

    
464
    /* Set-gid? */
465
    /*
466
     * If setgid is set but no group execute bit then this
467
     * is a candidate for mandatory locking, not a setgid
468
     * executable.
469
     */
470
    if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
471
        bprm->e_gid = st.st_gid;
472
        if (!in_group_p(bprm->e_gid)) {
473
                id_change = 1;
474
        }
475
    }
476

    
477
    memset(bprm->buf, 0, sizeof(bprm->buf));
478
    retval = lseek(bprm->fd, 0L, SEEK_SET);
479
    if(retval >= 0) {
480
        retval = read(bprm->fd, bprm->buf, 128);
481
    }
482
    if(retval < 0) {
483
        perror("prepare_binprm");
484
        exit(-1);
485
        /* return(-errno); */
486
    }
487
    else {
488
        return(retval);
489
    }
490
}
491

    
492
unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
493
                                                struct image_info * info)
494
{
495
    unsigned long stack_base, size, error;
496
    int i;
497

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

    
516
    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
517
    p += stack_base;
518

    
519
    if (bprm->loader) {
520
        bprm->loader += stack_base;
521
    }
522
    bprm->exec += stack_base;
523

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

    
528
            memcpy((void *)stack_base, (void *)bprm->page[i], TARGET_PAGE_SIZE);
529
            free_page((void *)bprm->page[i]);
530
        }
531
        stack_base += TARGET_PAGE_SIZE;
532
    }
533
    return p;
534
}
535

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

    
551

    
552
/* We need to explicitly zero any fractional pages after the data
553
   section (i.e. bss).  This would contain the junk from the file that
554
   should not be in memory. */
555
static void padzero(unsigned long elf_bss)
556
{
557
        unsigned long nbyte;
558
        char * fpnt;
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 (real_host_page_size < host_page_size) {
566
            unsigned long end_addr, end_addr1;
567
            end_addr1 = (elf_bss + real_host_page_size - 1) & 
568
                ~(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 & (host_page_size-1);
578
        if (nbyte) {
579
            nbyte = host_page_size - nbyte;
580
            fpnt = (char *) elf_bss;
581
            do {
582
                *fpnt++ = 0;
583
            } while (--nbyte);
584
        }
585
}
586

    
587
static unsigned int * create_elf_tables(char *p, int argc, int envc,
588
                                        struct elfhdr * exec,
589
                                        unsigned long load_addr,
590
                                        unsigned long load_bias,
591
                                        unsigned long interp_load_addr, int ibcs,
592
                                        struct image_info *info)
593
{
594
        target_ulong *argv, *envp;
595
        target_ulong *sp, *csp;
596
        int v;
597

    
598
        /*
599
         * Force 16 byte _final_ alignment here for generality.
600
         */
601
        sp = (unsigned int *) (~15UL & (unsigned long) p);
602
        csp = sp;
603
        csp -= (DLINFO_ITEMS + 1) * 2;
604
#ifdef DLINFO_ARCH_ITEMS
605
        csp -= DLINFO_ARCH_ITEMS*2;
606
#endif
607
        csp -= envc+1;
608
        csp -= argc+1;
609
        csp -= (!ibcs ? 3 : 1);        /* argc itself */
610
        if ((unsigned long)csp & 15UL)
611
            sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
612
        
613
#define NEW_AUX_ENT(nr, id, val) \
614
          put_user (id, sp + (nr * 2)); \
615
          put_user (val, sp + (nr * 2 + 1))
616
        sp -= 2;
617
        NEW_AUX_ENT (0, AT_NULL, 0);
618

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

    
640
        sp -= envc+1;
641
        envp = sp;
642
        sp -= argc+1;
643
        argv = sp;
644
        if (!ibcs) {
645
                put_user((target_ulong)envp,--sp);
646
                put_user((target_ulong)argv,--sp);
647
        }
648
        put_user(argc,--sp);
649
        info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
650
        while (argc-->0) {
651
                put_user((target_ulong)p,argv++);
652
                do {
653
                    get_user(v, p);
654
                    p++;
655
                } while (v != 0);
656
        }
657
        put_user(0,argv);
658
        info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
659
        while (envc-->0) {
660
                put_user((target_ulong)p,envp++);
661
                do {
662
                    get_user(v, p);
663
                    p++;
664
                } while (v != 0);
665
        }
666
        put_user(0,envp);
667
        info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
668
        return sp;
669
}
670

    
671

    
672

    
673
static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
674
                                     int interpreter_fd,
675
                                     unsigned long *interp_load_addr)
676
{
677
        struct elf_phdr *elf_phdata  =  NULL;
678
        struct elf_phdr *eppnt;
679
        unsigned long load_addr = 0;
680
        int load_addr_set = 0;
681
        int retval;
682
        unsigned long last_bss, elf_bss;
683
        unsigned long error;
684
        int i;
685
        
686
        elf_bss = 0;
687
        last_bss = 0;
688
        error = 0;
689

    
690
#ifdef BSWAP_NEEDED
691
        bswap_ehdr(interp_elf_ex);
692
#endif
693
        /* First of all, some simple consistency checks */
694
        if ((interp_elf_ex->e_type != ET_EXEC && 
695
             interp_elf_ex->e_type != ET_DYN) || 
696
           !elf_check_arch(interp_elf_ex->e_machine)) {
697
                return ~0UL;
698
        }
699
        
700

    
701
        /* Now read in all of the header information */
702
        
703
        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
704
            return ~0UL;
705
        
706
        elf_phdata =  (struct elf_phdr *) 
707
                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
708

    
709
        if (!elf_phdata)
710
          return ~0UL;
711
        
712
        /*
713
         * If the size of this structure has changed, then punt, since
714
         * we will be doing the wrong thing.
715
         */
716
        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
717
            free(elf_phdata);
718
            return ~0UL;
719
        }
720

    
721
        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
722
        if(retval >= 0) {
723
            retval = read(interpreter_fd,
724
                           (char *) elf_phdata,
725
                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
726
        }
727
        if (retval < 0) {
728
                perror("load_elf_interp");
729
                exit(-1);
730
                free (elf_phdata);
731
                return retval;
732
         }
733
#ifdef BSWAP_NEEDED
734
        eppnt = elf_phdata;
735
        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
736
            bswap_phdr(eppnt);
737
        }
738
#endif
739

    
740
        if (interp_elf_ex->e_type == ET_DYN) {
741
            /* in order to avoid harcoding the interpreter load
742
               address in qemu, we allocate a big enough memory zone */
743
            error = target_mmap(0, INTERP_MAP_SIZE,
744
                                PROT_NONE, MAP_PRIVATE | MAP_ANON, 
745
                                -1, 0);
746
            if (error == -1) {
747
                perror("mmap");
748
                exit(-1);
749
            }
750
            load_addr = error;
751
            load_addr_set = 1;
752
        }
753

    
754
        eppnt = elf_phdata;
755
        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
756
          if (eppnt->p_type == PT_LOAD) {
757
            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
758
            int elf_prot = 0;
759
            unsigned long vaddr = 0;
760
            unsigned long k;
761

    
762
            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
763
            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
764
            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
765
            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
766
                    elf_type |= MAP_FIXED;
767
                    vaddr = eppnt->p_vaddr;
768
            }
769
            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
770
                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
771
                 elf_prot,
772
                 elf_type,
773
                 interpreter_fd,
774
                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
775
            
776
            if (error > -1024UL) {
777
              /* Real error */
778
              close(interpreter_fd);
779
              free(elf_phdata);
780
              return ~0UL;
781
            }
782

    
783
            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
784
              load_addr = error;
785
              load_addr_set = 1;
786
            }
787

    
788
            /*
789
             * Find the end of the file  mapping for this phdr, and keep
790
             * track of the largest address we see for this.
791
             */
792
            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
793
            if (k > elf_bss) elf_bss = k;
794

    
795
            /*
796
             * Do the same thing for the memory mapping - between
797
             * elf_bss and last_bss is the bss section.
798
             */
799
            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
800
            if (k > last_bss) last_bss = k;
801
          }
802
        
803
        /* Now use mmap to map the library into memory. */
804

    
805
        close(interpreter_fd);
806

    
807
        /*
808
         * Now fill out the bss section.  First pad the last page up
809
         * to the page boundary, and then perform a mmap to make sure
810
         * that there are zeromapped pages up to and including the last
811
         * bss page.
812
         */
813
        padzero(elf_bss);
814
        elf_bss = TARGET_ELF_PAGESTART(elf_bss + host_page_size - 1); /* What we have mapped so far */
815

    
816
        /* Map the last of the bss segment */
817
        if (last_bss > elf_bss) {
818
            target_mmap(elf_bss, last_bss-elf_bss,
819
                        PROT_READ|PROT_WRITE|PROT_EXEC,
820
                        MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
821
        }
822
        free(elf_phdata);
823

    
824
        *interp_load_addr = load_addr;
825
        return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
826
}
827

    
828
/* Best attempt to load symbols from this ELF object. */
829
static void load_symbols(struct elfhdr *hdr, int fd)
830
{
831
    unsigned int i;
832
    struct elf_shdr sechdr, symtab, strtab;
833
    char *strings;
834

    
835
    lseek(fd, hdr->e_shoff, SEEK_SET);
836
    for (i = 0; i < hdr->e_shnum; i++) {
837
        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
838
            return;
839
#ifdef BSWAP_NEEDED
840
        bswap_shdr(&sechdr);
841
#endif
842
        if (sechdr.sh_type == SHT_SYMTAB) {
843
            symtab = sechdr;
844
            lseek(fd, hdr->e_shoff
845
                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
846
            if (read(fd, &strtab, sizeof(strtab))
847
                != sizeof(strtab))
848
                return;
849
#ifdef BSWAP_NEEDED
850
            bswap_shdr(&strtab);
851
#endif
852
            goto found;
853
        }
854
    }
855
    return; /* Shouldn't happen... */
856

    
857
 found:
858
    /* Now know where the strtab and symtab are.  Snarf them. */
859
    disas_symtab = malloc(symtab.sh_size);
860
    disas_strtab = strings = malloc(strtab.sh_size);
861
    if (!disas_symtab || !disas_strtab)
862
        return;
863
        
864
    lseek(fd, symtab.sh_offset, SEEK_SET);
865
    if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
866
        return;
867

    
868
#ifdef BSWAP_NEEDED
869
    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
870
        bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
871
#endif
872

    
873
    lseek(fd, strtab.sh_offset, SEEK_SET);
874
    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
875
        return;
876
    disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
877
}
878

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

    
903
    ibcs2_interpreter = 0;
904
    status = 0;
905
    load_addr = 0;
906
    load_bias = 0;
907
    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
908
#ifdef BSWAP_NEEDED
909
    bswap_ehdr(&elf_ex);
910
#endif
911

    
912
    if (elf_ex.e_ident[0] != 0x7f ||
913
        strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
914
            return  -ENOEXEC;
915
    }
916

    
917
    /* First of all, some simple consistency checks */
918
    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
919
                                       (! elf_check_arch(elf_ex.e_machine))) {
920
            return -ENOEXEC;
921
    }
922

    
923
    /* Now read in all of the header information */
924
    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
925
    if (elf_phdata == NULL) {
926
        return -ENOMEM;
927
    }
928

    
929
    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
930
    if(retval > 0) {
931
        retval = read(bprm->fd, (char *) elf_phdata, 
932
                                elf_ex.e_phentsize * elf_ex.e_phnum);
933
    }
934

    
935
    if (retval < 0) {
936
        perror("load_elf_binary");
937
        exit(-1);
938
        free (elf_phdata);
939
        return -errno;
940
    }
941

    
942
#ifdef BSWAP_NEEDED
943
    elf_ppnt = elf_phdata;
944
    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
945
        bswap_phdr(elf_ppnt);
946
    }
947
#endif
948
    elf_ppnt = elf_phdata;
949

    
950
    elf_bss = 0;
951
    elf_brk = 0;
952

    
953

    
954
    elf_stack = ~0UL;
955
    elf_interpreter = NULL;
956
    start_code = ~0UL;
957
    end_code = 0;
958
    end_data = 0;
959

    
960
    for(i=0;i < elf_ex.e_phnum; i++) {
961
        if (elf_ppnt->p_type == PT_INTERP) {
962
            if ( elf_interpreter != NULL )
963
            {
964
                free (elf_phdata);
965
                free(elf_interpreter);
966
                close(bprm->fd);
967
                return -EINVAL;
968
            }
969

    
970
            /* This is the program interpreter used for
971
             * shared libraries - for now assume that this
972
             * is an a.out format binary
973
             */
974

    
975
            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
976

    
977
            if (elf_interpreter == NULL) {
978
                free (elf_phdata);
979
                close(bprm->fd);
980
                return -ENOMEM;
981
            }
982

    
983
            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
984
            if(retval >= 0) {
985
                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
986
            }
987
            if(retval < 0) {
988
                 perror("load_elf_binary2");
989
                exit(-1);
990
            }        
991

    
992
            /* If the program interpreter is one of these two,
993
               then assume an iBCS2 image. Otherwise assume
994
               a native linux image. */
995

    
996
            /* JRP - Need to add X86 lib dir stuff here... */
997

    
998
            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
999
                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
1000
              ibcs2_interpreter = 1;
1001
            }
1002

    
1003
#if 0
1004
            printf("Using ELF interpreter %s\n", elf_interpreter);
1005
#endif
1006
            if (retval >= 0) {
1007
                retval = open(path(elf_interpreter), O_RDONLY);
1008
                if(retval >= 0) {
1009
                    interpreter_fd = retval;
1010
                }
1011
                else {
1012
                    perror(elf_interpreter);
1013
                    exit(-1);
1014
                    /* retval = -errno; */
1015
                }
1016
            }
1017

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

    
1040
    /* Some simple consistency checks for the interpreter */
1041
    if (elf_interpreter){
1042
        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1043

    
1044
        /* Now figure out which format our binary is */
1045
        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
1046
                    (N_MAGIC(interp_ex) != QMAGIC)) {
1047
          interpreter_type = INTERPRETER_ELF;
1048
        }
1049

    
1050
        if (interp_elf_ex.e_ident[0] != 0x7f ||
1051
                    strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
1052
            interpreter_type &= ~INTERPRETER_ELF;
1053
        }
1054

    
1055
        if (!interpreter_type) {
1056
            free(elf_interpreter);
1057
            free(elf_phdata);
1058
            close(bprm->fd);
1059
            return -ELIBBAD;
1060
        }
1061
    }
1062

    
1063
    /* OK, we are done with that, now set up the arg stuff,
1064
       and then start this sucker up */
1065

    
1066
    if (!bprm->sh_bang) {
1067
        char * passed_p;
1068

    
1069
        if (interpreter_type == INTERPRETER_AOUT) {
1070
            sprintf(passed_fileno, "%d", bprm->fd);
1071
            passed_p = passed_fileno;
1072

    
1073
            if (elf_interpreter) {
1074
                bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
1075
                bprm->argc++;
1076
            }
1077
        }
1078
        if (!bprm->p) {
1079
            if (elf_interpreter) {
1080
                free(elf_interpreter);
1081
            }
1082
            free (elf_phdata);
1083
            close(bprm->fd);
1084
            return -E2BIG;
1085
        }
1086
    }
1087

    
1088
    /* OK, This is the point of no return */
1089
    info->end_data = 0;
1090
    info->end_code = 0;
1091
    info->start_mmap = (unsigned long)ELF_START_MMAP;
1092
    info->mmap = 0;
1093
    elf_entry = (unsigned long) elf_ex.e_entry;
1094

    
1095
    /* Do this so that we can load the interpreter, if need be.  We will
1096
       change some of these later */
1097
    info->rss = 0;
1098
    bprm->p = setup_arg_pages(bprm->p, bprm, info);
1099
    info->start_stack = bprm->p;
1100

    
1101
    /* Now we do a little grungy work by mmaping the ELF image into
1102
     * the correct location in memory.  At this point, we assume that
1103
     * the image should be loaded at fixed address, not at a variable
1104
     * address.
1105
     */
1106

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

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

    
1178
    elf_entry += load_bias;
1179
    elf_bss += load_bias;
1180
    elf_brk += load_bias;
1181
    start_code += load_bias;
1182
    end_code += load_bias;
1183
    //    start_data += load_bias;
1184
    end_data += load_bias;
1185

    
1186
    if (elf_interpreter) {
1187
        if (interpreter_type & 1) {
1188
            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1189
        }
1190
        else if (interpreter_type & 2) {
1191
            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1192
                                            &interp_load_addr);
1193
        }
1194

    
1195
        close(interpreter_fd);
1196
        free(elf_interpreter);
1197

    
1198
        if (elf_entry == ~0UL) {
1199
            printf("Unable to load interpreter\n");
1200
            free(elf_phdata);
1201
            exit(-1);
1202
            return 0;
1203
        }
1204
    }
1205

    
1206
    free(elf_phdata);
1207

    
1208
    if (loglevel)
1209
        load_symbols(&elf_ex, bprm->fd);
1210

    
1211
    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1212
    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1213

    
1214
#ifdef LOW_ELF_STACK
1215
    info->start_stack = bprm->p = elf_stack - 4;
1216
#endif
1217
    bprm->p = (unsigned long)
1218
      create_elf_tables((char *)bprm->p,
1219
                    bprm->argc,
1220
                    bprm->envc,
1221
                    &elf_ex,
1222
                    load_addr, load_bias,
1223
                    interp_load_addr,
1224
                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1225
                    info);
1226
    if (interpreter_type == INTERPRETER_AOUT)
1227
      info->arg_start += strlen(passed_fileno) + 1;
1228
    info->start_brk = info->brk = elf_brk;
1229
    info->end_code = end_code;
1230
    info->start_code = start_code;
1231
    info->end_data = end_data;
1232
    info->start_stack = bprm->p;
1233

    
1234
    /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1235
       sections */
1236
    set_brk(elf_bss, elf_brk);
1237

    
1238
    padzero(elf_bss);
1239

    
1240
#if 0
1241
    printf("(start_brk) %x\n" , info->start_brk);
1242
    printf("(end_code) %x\n" , info->end_code);
1243
    printf("(start_code) %x\n" , info->start_code);
1244
    printf("(end_data) %x\n" , info->end_data);
1245
    printf("(start_stack) %x\n" , info->start_stack);
1246
    printf("(brk) %x\n" , info->brk);
1247
#endif
1248

    
1249
    if ( info->personality == PER_SVR4 )
1250
    {
1251
            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1252
               and some applications "depend" upon this behavior.
1253
               Since we do not have the power to recompile these, we
1254
               emulate the SVr4 behavior.  Sigh.  */
1255
            mapped_addr = target_mmap(0, host_page_size, PROT_READ | PROT_EXEC,
1256
                                      MAP_FIXED | MAP_PRIVATE, -1, 0);
1257
    }
1258

    
1259
#ifdef ELF_PLAT_INIT
1260
    /*
1261
     * The ABI may specify that certain registers be set up in special
1262
     * ways (on i386 %edx is the address of a DT_FINI function, for
1263
     * example.  This macro performs whatever initialization to
1264
     * the regs structure is required.
1265
     */
1266
    ELF_PLAT_INIT(regs);
1267
#endif
1268

    
1269

    
1270
    info->entry = elf_entry;
1271

    
1272
    return 0;
1273
}
1274

    
1275

    
1276

    
1277
int elf_exec(const char * filename, char ** argv, char ** envp, 
1278
             struct target_pt_regs * regs, struct image_info *infop)
1279
{
1280
        struct linux_binprm bprm;
1281
        int retval;
1282
        int i;
1283

    
1284
        bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1285
        for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
1286
                bprm.page[i] = 0;
1287
        retval = open(filename, O_RDONLY);
1288
        if (retval < 0)
1289
            return retval;
1290
        bprm.fd = retval;
1291
        bprm.filename = (char *)filename;
1292
        bprm.sh_bang = 0;
1293
        bprm.loader = 0;
1294
        bprm.exec = 0;
1295
        bprm.dont_iput = 0;
1296
        bprm.argc = count(argv);
1297
        bprm.envc = count(envp);
1298

    
1299
        retval = prepare_binprm(&bprm);
1300

    
1301
        if(retval>=0) {
1302
            bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1303
            bprm.exec = bprm.p;
1304
            bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1305
            bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1306
            if (!bprm.p) {
1307
                retval = -E2BIG;
1308
            }
1309
        }
1310

    
1311
        if(retval>=0) {
1312
            retval = load_elf_binary(&bprm,regs,infop);
1313
        }
1314
        if(retval>=0) {
1315
            /* success.  Initialize important registers */
1316
            init_thread(regs, infop);
1317
            return retval;
1318
        }
1319

    
1320
        /* Something went wrong, return the inode and free the argument pages*/
1321
        for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1322
            free_page((void *)bprm.page[i]);
1323
        }
1324
        return(retval);
1325
}
1326

    
1327

    
1328
static int load_aout_interp(void * exptr, int interp_fd)
1329
{
1330
    printf("a.out interpreter not yet supported\n");
1331
    return(0);
1332
}
1333