Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ c2735790

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
                pag = (char *) page[p/TARGET_PAGE_SIZE];
390
                if (!pag) {
391
                    pag = (char *)get_free_page();
392
                    page[p/TARGET_PAGE_SIZE] = (unsigned long)pag;
393
                    if (!pag)
394
                        return 0;
395
                }
396
            }
397
            if (len == 0 || offset == 0) {
398
                *(pag + offset) = get_user(tmp);
399
            }
400
            else {
401
              int bytes_to_copy = (len > offset) ? offset : len;
402
              tmp -= bytes_to_copy;
403
              p -= bytes_to_copy;
404
              offset -= bytes_to_copy;
405
              len -= bytes_to_copy;
406
              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
407
            }
408
        }
409
    }
410
    return p;
411
}
412

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

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

    
429
static int count(char ** vec)
430
{
431
    int                i;
432

    
433
    for(i = 0; *vec; i++) {
434
        vec++;
435
    }
436

    
437
    return(i);
438
}
439

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

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

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

    
458
    bprm->e_uid = geteuid();
459
    bprm->e_gid = getegid();
460
    id_change = 0;
461

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

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

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

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

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

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

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

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

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

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

    
557

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

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

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

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

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

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

    
670

    
671

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

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

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

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

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

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

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

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

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

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

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

    
804
        close(interpreter_fd);
805

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
949
    elf_bss = 0;
950
    elf_brk = 0;
951

    
952

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1205
    free(elf_phdata);
1206

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

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

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

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

    
1237
    padzero(elf_bss);
1238

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

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

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

    
1268

    
1269
    info->entry = elf_entry;
1270

    
1271
    return 0;
1272
}
1273

    
1274

    
1275

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

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

    
1298
        retval = prepare_binprm(&bprm);
1299

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

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

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

    
1326

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