Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ f5155289

History | View | Annotate | Download (37.5 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
   unsigned long *pos = (unsigned long *)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
#define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
267
#define get_user(ptr) (typeof(*ptr))(*(ptr))
268

    
269
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
270
{
271
        memcpy(to, from, n);
272
}
273

    
274
static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
275
{
276
        memcpy(to, from, n);
277
}
278

    
279
extern unsigned long x86_stack_size;
280

    
281
static int load_aout_interp(void * exptr, int interp_fd);
282

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

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

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

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

    
336
static void * get_free_page(void)
337
{
338
    void *        retval;
339

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

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

    
355
static void free_page(void * pageaddr)
356
{
357
    target_munmap((unsigned long)pageaddr, host_page_size);
358
}
359

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

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

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

    
418
    ngroup = getgroups(NGROUPS, grouplist);
419
    for(i = 0; i < ngroup; i++) {
420
        if(grouplist[i] == g) {
421
            return 1;
422
        }
423
    }
424
    return 0;
425
}
426

    
427
static int count(char ** vec)
428
{
429
    int                i;
430

    
431
    for(i = 0; *vec; i++) {
432
        vec++;
433
    }
434

    
435
    return(i);
436
}
437

    
438
static int prepare_binprm(struct linux_binprm *bprm)
439
{
440
    struct stat                st;
441
    int mode;
442
    int retval, id_change;
443

    
444
    if(fstat(bprm->fd, &st) < 0) {
445
        return(-errno);
446
    }
447

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

    
456
    bprm->e_uid = geteuid();
457
    bprm->e_gid = getegid();
458
    id_change = 0;
459

    
460
    /* Set-uid? */
461
    if(mode & S_ISUID) {
462
            bprm->e_uid = st.st_uid;
463
        if(bprm->e_uid != geteuid()) {
464
            id_change = 1;
465
        }
466
    }
467

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

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

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

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

    
520
    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
521
    p += stack_base;
522

    
523
    if (bprm->loader) {
524
        bprm->loader += stack_base;
525
    }
526
    bprm->exec += stack_base;
527

    
528
    for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
529
        if (bprm->page[i]) {
530
            info->rss++;
531

    
532
            memcpy((void *)stack_base, (void *)bprm->page[i], TARGET_PAGE_SIZE);
533
            free_page((void *)bprm->page[i]);
534
        }
535
        stack_base += TARGET_PAGE_SIZE;
536
    }
537
    return p;
538
}
539

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

    
555

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

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

    
581
        nbyte = elf_bss & (host_page_size-1);
582
        if (nbyte) {
583
            nbyte = host_page_size - nbyte;
584
            fpnt = (char *) elf_bss;
585
            do {
586
                *fpnt++ = 0;
587
            } while (--nbyte);
588
        }
589
}
590

    
591
static unsigned int * create_elf_tables(char *p, int argc, int envc,
592
                                        struct elfhdr * exec,
593
                                        unsigned long load_addr,
594
                                        unsigned long load_bias,
595
                                        unsigned long interp_load_addr, int ibcs,
596
                                        struct image_info *info)
597
{
598
        target_ulong *argv, *envp;
599
        target_ulong *sp, *csp;
600
        
601
        /*
602
         * Force 16 byte _final_ alignment here for generality.
603
         */
604
        sp = (unsigned int *) (~15UL & (unsigned long) p);
605
        csp = sp;
606
        csp -= (DLINFO_ITEMS + 1) * 2;
607
#ifdef DLINFO_ARCH_ITEMS
608
        csp -= DLINFO_ARCH_ITEMS*2;
609
#endif
610
        csp -= envc+1;
611
        csp -= argc+1;
612
        csp -= (!ibcs ? 3 : 1);        /* argc itself */
613
        if ((unsigned long)csp & 15UL)
614
            sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
615
        
616
#define NEW_AUX_ENT(nr, id, val) \
617
          put_user (tswapl(id), sp + (nr * 2)); \
618
          put_user (tswapl(val), sp + (nr * 2 + 1))
619
        sp -= 2;
620
        NEW_AUX_ENT (0, AT_NULL, 0);
621

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

    
643
        sp -= envc+1;
644
        envp = sp;
645
        sp -= argc+1;
646
        argv = sp;
647
        if (!ibcs) {
648
                put_user(tswapl((target_ulong)envp),--sp);
649
                put_user(tswapl((target_ulong)argv),--sp);
650
        }
651
        put_user(tswapl(argc),--sp);
652
        info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
653
        while (argc-->0) {
654
                put_user(tswapl((target_ulong)p),argv++);
655
                while (get_user(p++)) /* nothing */ ;
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(tswapl((target_ulong)p),envp++);
661
                while (get_user(p++)) /* nothing */ ;
662
        }
663
        put_user(0,envp);
664
        info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
665
        return sp;
666
}
667

    
668

    
669

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

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

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

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

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

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

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

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

    
780
            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
781
              load_addr = error;
782
              load_addr_set = 1;
783
            }
784

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

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

    
802
        close(interpreter_fd);
803

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

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

    
821
        *interp_load_addr = load_addr;
822
        return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
823
}
824

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

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

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

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

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

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

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

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

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

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

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

    
932
    if (retval < 0) {
933
        perror("load_elf_binary");
934
        exit(-1);
935
        free (elf_phdata);
936
        return -errno;
937
    }
938

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

    
947
    elf_bss = 0;
948
    elf_brk = 0;
949

    
950

    
951
    elf_stack = ~0UL;
952
    elf_interpreter = NULL;
953
    start_code = ~0UL;
954
    end_code = 0;
955
    end_data = 0;
956

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

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

    
972
            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
973

    
974
            if (elf_interpreter == NULL) {
975
                free (elf_phdata);
976
                close(bprm->fd);
977
                return -ENOMEM;
978
            }
979

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

    
989
            /* If the program interpreter is one of these two,
990
               then assume an iBCS2 image. Otherwise assume
991
               a native linux image. */
992

    
993
            /* JRP - Need to add X86 lib dir stuff here... */
994

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

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

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

    
1037
    /* Some simple consistency checks for the interpreter */
1038
    if (elf_interpreter){
1039
        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
1040

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

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

    
1052
        if (!interpreter_type) {
1053
            free(elf_interpreter);
1054
            free(elf_phdata);
1055
            close(bprm->fd);
1056
            return -ELIBBAD;
1057
        }
1058
    }
1059

    
1060
    /* OK, we are done with that, now set up the arg stuff,
1061
       and then start this sucker up */
1062

    
1063
    if (!bprm->sh_bang) {
1064
        char * passed_p;
1065

    
1066
        if (interpreter_type == INTERPRETER_AOUT) {
1067
            sprintf(passed_fileno, "%d", bprm->fd);
1068
            passed_p = passed_fileno;
1069

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

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

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

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

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

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

    
1175
    elf_entry += load_bias;
1176
    elf_bss += load_bias;
1177
    elf_brk += load_bias;
1178
    start_code += load_bias;
1179
    end_code += load_bias;
1180
    //    start_data += load_bias;
1181
    end_data += load_bias;
1182

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

    
1192
        close(interpreter_fd);
1193
        free(elf_interpreter);
1194

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

    
1203
    free(elf_phdata);
1204

    
1205
    if (loglevel)
1206
        load_symbols(&elf_ex, bprm->fd);
1207

    
1208
    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1209
    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1210

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

    
1231
    /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1232
       sections */
1233
    set_brk(elf_bss, elf_brk);
1234

    
1235
    padzero(elf_bss);
1236

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

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

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

    
1266

    
1267
    info->entry = elf_entry;
1268

    
1269
    return 0;
1270
}
1271

    
1272

    
1273

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

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

    
1301
        retval = prepare_binprm(&bprm);
1302

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

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

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

    
1329

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