Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ a69d83b6

History | View | Annotate | Download (33 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
typedef uint32_t  elf_greg_t;
21

    
22
#define ELF_NGREG (sizeof (struct target_pt_regs) / sizeof(elf_greg_t))
23
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
24

    
25
typedef struct user_i387_struct elf_fpregset_t;
26

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

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

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

45
           A value of 0 tells we have no such handler.  */
46
#define ELF_PLAT_INIT(_r)        _r->edx = 0
47

    
48
#define USE_ELF_CORE_DUMP
49
#define ELF_EXEC_PAGESIZE        4096
50

    
51
#endif
52

    
53
#include "elf.h"
54

    
55
/*
56
 * MAX_ARG_PAGES defines the number of pages allocated for arguments
57
 * and envelope for the new program. 32 should suffice, this gives
58
 * a maximum env+arg of 128kB w/4KB pages!
59
 */
60
#define MAX_ARG_PAGES 32
61

    
62
/*
63
 * This structure is used to hold the arguments that are 
64
 * used when loading binaries.
65
 */
66
struct linux_binprm {
67
        char buf[128];
68
        unsigned long page[MAX_ARG_PAGES];
69
        unsigned long p;
70
        int sh_bang;
71
        int fd;
72
        int e_uid, e_gid;
73
        int argc, envc;
74
        char * filename;        /* Name of binary */
75
        unsigned long loader, exec;
76
        int dont_iput;          /* binfmt handler has put inode */
77
};
78

    
79
struct exec
80
{
81
  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */
82
  unsigned int a_text;   /* length of text, in bytes */
83
  unsigned int a_data;   /* length of data, in bytes */
84
  unsigned int a_bss;    /* length of uninitialized data area, in bytes */
85
  unsigned int a_syms;   /* length of symbol table data in file, in bytes */
86
  unsigned int a_entry;  /* start address */
87
  unsigned int a_trsize; /* length of relocation info for text, in bytes */
88
  unsigned int a_drsize; /* length of relocation info for data, in bytes */
89
};
90

    
91

    
92
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
93
#define OMAGIC 0407
94
#define NMAGIC 0410
95
#define ZMAGIC 0413
96
#define QMAGIC 0314
97

    
98
#define X86_STACK_TOP 0x7d000000
99

    
100
/* max code+data+bss space allocated to elf interpreter */
101
#define INTERP_MAP_SIZE (32 * 1024 * 1024)
102

    
103
/* max code+data+bss+brk space allocated to ET_DYN executables */
104
#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
105

    
106
/* from personality.h */
107

    
108
/* Flags for bug emulation. These occupy the top three bytes. */
109
#define STICKY_TIMEOUTS                0x4000000
110
#define WHOLE_SECONDS                0x2000000
111

    
112
/* Personality types. These go in the low byte. Avoid using the top bit,
113
 * it will conflict with error returns.
114
 */
115
#define PER_MASK                (0x00ff)
116
#define PER_LINUX                (0x0000)
117
#define PER_SVR4                (0x0001 | STICKY_TIMEOUTS)
118
#define PER_SVR3                (0x0002 | STICKY_TIMEOUTS)
119
#define PER_SCOSVR3                (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
120
#define PER_WYSEV386                (0x0004 | STICKY_TIMEOUTS)
121
#define PER_ISCR4                (0x0005 | STICKY_TIMEOUTS)
122
#define PER_BSD                        (0x0006)
123
#define PER_XENIX                (0x0007 | STICKY_TIMEOUTS)
124

    
125
/* Necessary parameters */
126
#define        ALPHA_PAGE_SIZE 4096
127
#define        X86_PAGE_SIZE 4096
128

    
129
#define ALPHA_PAGE_MASK (~(ALPHA_PAGE_SIZE-1))
130
#define X86_PAGE_MASK (~(X86_PAGE_SIZE-1))
131

    
132
#define ALPHA_PAGE_ALIGN(addr) ((((addr)+ALPHA_PAGE_SIZE)-1)&ALPHA_PAGE_MASK)
133
#define X86_PAGE_ALIGN(addr) ((((addr)+X86_PAGE_SIZE)-1)&X86_PAGE_MASK)
134

    
135
#define NGROUPS 32
136

    
137
#define X86_ELF_EXEC_PAGESIZE X86_PAGE_SIZE
138
#define X86_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(X86_ELF_EXEC_PAGESIZE-1))
139
#define X86_ELF_PAGEOFFSET(_v) ((_v) & (X86_ELF_EXEC_PAGESIZE-1))
140

    
141
#define ALPHA_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ALPHA_PAGE_SIZE-1))
142
#define ALPHA_ELF_PAGEOFFSET(_v) ((_v) & (ALPHA_PAGE_SIZE-1))
143

    
144
#define INTERPRETER_NONE 0
145
#define INTERPRETER_AOUT 1
146
#define INTERPRETER_ELF 2
147

    
148
#define DLINFO_ITEMS 12
149

    
150
#define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
151
#define get_user(ptr) (typeof(*ptr))(*(ptr))
152

    
153
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
154
{
155
        memcpy(to, from, n);
156
}
157

    
158
static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
159
{
160
        memcpy(to, from, n);
161
}
162

    
163
//extern void * mmap4k();
164
#define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f)
165

    
166
extern unsigned long x86_stack_size;
167

    
168
static int load_aout_interp(void * exptr, int interp_fd);
169

    
170
#ifdef BSWAP_NEEDED
171
static void bswap_ehdr(Elf32_Ehdr *ehdr)
172
{
173
    bswap16s(&ehdr->e_type);                        /* Object file type */
174
    bswap16s(&ehdr->e_machine);                /* Architecture */
175
    bswap32s(&ehdr->e_version);                /* Object file version */
176
    bswap32s(&ehdr->e_entry);                /* Entry point virtual address */
177
    bswap32s(&ehdr->e_phoff);                /* Program header table file offset */
178
    bswap32s(&ehdr->e_shoff);                /* Section header table file offset */
179
    bswap32s(&ehdr->e_flags);                /* Processor-specific flags */
180
    bswap16s(&ehdr->e_ehsize);                /* ELF header size in bytes */
181
    bswap16s(&ehdr->e_phentsize);                /* Program header table entry size */
182
    bswap16s(&ehdr->e_phnum);                /* Program header table entry count */
183
    bswap16s(&ehdr->e_shentsize);                /* Section header table entry size */
184
    bswap16s(&ehdr->e_shnum);                /* Section header table entry count */
185
    bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */
186
}
187

    
188
static void bswap_phdr(Elf32_Phdr *phdr)
189
{
190
    bswap32s(&phdr->p_type);                        /* Segment type */
191
    bswap32s(&phdr->p_offset);                /* Segment file offset */
192
    bswap32s(&phdr->p_vaddr);                /* Segment virtual address */
193
    bswap32s(&phdr->p_paddr);                /* Segment physical address */
194
    bswap32s(&phdr->p_filesz);                /* Segment size in file */
195
    bswap32s(&phdr->p_memsz);                /* Segment size in memory */
196
    bswap32s(&phdr->p_flags);                /* Segment flags */
197
    bswap32s(&phdr->p_align);                /* Segment alignment */
198
}
199

    
200
static void bswap_shdr(Elf32_Shdr *shdr)
201
{
202
    bswap32s(&shdr->sh_name);
203
    bswap32s(&shdr->sh_type);
204
    bswap32s(&shdr->sh_flags);
205
    bswap32s(&shdr->sh_addr);
206
    bswap32s(&shdr->sh_offset);
207
    bswap32s(&shdr->sh_size);
208
    bswap32s(&shdr->sh_link);
209
    bswap32s(&shdr->sh_info);
210
    bswap32s(&shdr->sh_addralign);
211
    bswap32s(&shdr->sh_entsize);
212
}
213

    
214
static void bswap_sym(Elf32_Sym *sym)
215
{
216
    bswap32s(&sym->st_name);
217
    bswap32s(&sym->st_value);
218
    bswap32s(&sym->st_size);
219
    bswap16s(&sym->st_shndx);
220
}
221
#endif
222

    
223
static void * get_free_page(void)
224
{
225
    void *        retval;
226

    
227
    /* User-space version of kernel get_free_page.  Returns a page-aligned
228
     * page-sized chunk of memory.
229
     */
230
    retval = mmap4k(0, ALPHA_PAGE_SIZE, PROT_READ|PROT_WRITE, 
231
                        MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
232

    
233
    if((long)retval == -1) {
234
        perror("get_free_page");
235
        exit(-1);
236
    }
237
    else {
238
        return(retval);
239
    }
240
}
241

    
242
static void free_page(void * pageaddr)
243
{
244
    (void)munmap(pageaddr, ALPHA_PAGE_SIZE);
245
}
246

    
247
/*
248
 * 'copy_string()' copies argument/envelope strings from user
249
 * memory to free pages in kernel mem. These are in a format ready
250
 * to be put directly into the top of new user memory.
251
 *
252
 */
253
static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
254
                unsigned long p)
255
{
256
    char *tmp, *tmp1, *pag = NULL;
257
    int len, offset = 0;
258

    
259
    if (!p) {
260
        return 0;       /* bullet-proofing */
261
    }
262
    while (argc-- > 0) {
263
        if (!(tmp1 = tmp = get_user(argv+argc))) {
264
            fprintf(stderr, "VFS: argc is wrong");
265
            exit(-1);
266
        }
267
        while (get_user(tmp++));
268
        len = tmp - tmp1;
269
        if (p < len) {  /* this shouldn't happen - 128kB */
270
                return 0;
271
        }
272
        while (len) {
273
            --p; --tmp; --len;
274
            if (--offset < 0) {
275
                offset = p % X86_PAGE_SIZE;
276
                if (!(pag = (char *) page[p/X86_PAGE_SIZE]) &&
277
                    !(pag = (char *) page[p/X86_PAGE_SIZE] =
278
                      (unsigned long *) get_free_page())) {
279
                        return 0;
280
                }
281
            }
282
            if (len == 0 || offset == 0) {
283
                *(pag + offset) = get_user(tmp);
284
            }
285
            else {
286
              int bytes_to_copy = (len > offset) ? offset : len;
287
              tmp -= bytes_to_copy;
288
              p -= bytes_to_copy;
289
              offset -= bytes_to_copy;
290
              len -= bytes_to_copy;
291
              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
292
            }
293
        }
294
    }
295
    return p;
296
}
297

    
298
static int in_group_p(gid_t g)
299
{
300
    /* return TRUE if we're in the specified group, FALSE otherwise */
301
    int                ngroup;
302
    int                i;
303
    gid_t        grouplist[NGROUPS];
304

    
305
    ngroup = getgroups(NGROUPS, grouplist);
306
    for(i = 0; i < ngroup; i++) {
307
        if(grouplist[i] == g) {
308
            return 1;
309
        }
310
    }
311
    return 0;
312
}
313

    
314
static int count(char ** vec)
315
{
316
    int                i;
317

    
318
    for(i = 0; *vec; i++) {
319
        vec++;
320
    }
321

    
322
    return(i);
323
}
324

    
325
static int prepare_binprm(struct linux_binprm *bprm)
326
{
327
    struct stat                st;
328
    int mode;
329
    int retval, id_change;
330

    
331
    if(fstat(bprm->fd, &st) < 0) {
332
        return(-errno);
333
    }
334

    
335
    mode = st.st_mode;
336
    if(!S_ISREG(mode)) {        /* Must be regular file */
337
        return(-EACCES);
338
    }
339
    if(!(mode & 0111)) {        /* Must have at least one execute bit set */
340
        return(-EACCES);
341
    }
342

    
343
    bprm->e_uid = geteuid();
344
    bprm->e_gid = getegid();
345
    id_change = 0;
346

    
347
    /* Set-uid? */
348
    if(mode & S_ISUID) {
349
            bprm->e_uid = st.st_uid;
350
        if(bprm->e_uid != geteuid()) {
351
            id_change = 1;
352
        }
353
    }
354

    
355
    /* Set-gid? */
356
    /*
357
     * If setgid is set but no group execute bit then this
358
     * is a candidate for mandatory locking, not a setgid
359
     * executable.
360
     */
361
    if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
362
        bprm->e_gid = st.st_gid;
363
        if (!in_group_p(bprm->e_gid)) {
364
                id_change = 1;
365
        }
366
    }
367

    
368
    memset(bprm->buf, 0, sizeof(bprm->buf));
369
    retval = lseek(bprm->fd, 0L, SEEK_SET);
370
    if(retval >= 0) {
371
        retval = read(bprm->fd, bprm->buf, 128);
372
    }
373
    if(retval < 0) {
374
        perror("prepare_binprm");
375
        exit(-1);
376
        /* return(-errno); */
377
    }
378
    else {
379
        return(retval);
380
    }
381
}
382

    
383
unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
384
                                                struct image_info * info)
385
{
386
    unsigned long stack_base, size, error;
387
    int i;
388

    
389
    /* Create enough stack to hold everything.  If we don't use
390
     * it for args, we'll use it for something else...
391
     */
392
    size = x86_stack_size;
393
    if (size < MAX_ARG_PAGES*X86_PAGE_SIZE)
394
        size = MAX_ARG_PAGES*X86_PAGE_SIZE;
395
    error = (unsigned long)mmap4k(NULL, 
396
                                  size + X86_PAGE_SIZE,
397
                                  PROT_READ | PROT_WRITE,
398
                                  MAP_PRIVATE | MAP_ANONYMOUS,
399
                                  -1, 0);
400
    if (error == -1) {
401
        perror("stk mmap");
402
        exit(-1);
403
    }
404
    /* we reserve one extra page at the top of the stack as guard */
405
    mprotect((void *)(error + size), X86_PAGE_SIZE, PROT_NONE);
406

    
407
    stack_base = error + size - MAX_ARG_PAGES*X86_PAGE_SIZE;
408
    p += stack_base;
409

    
410
    if (bprm->loader) {
411
        bprm->loader += stack_base;
412
    }
413
    bprm->exec += stack_base;
414

    
415
    for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
416
        if (bprm->page[i]) {
417
            info->rss++;
418

    
419
            memcpy((void *)stack_base, (void *)bprm->page[i], X86_PAGE_SIZE);
420
            free_page((void *)bprm->page[i]);
421
        }
422
        stack_base += X86_PAGE_SIZE;
423
    }
424
    return p;
425
}
426

    
427
static void set_brk(unsigned long start, unsigned long end)
428
{
429
        /* page-align the start and end addresses... */
430
        start = ALPHA_PAGE_ALIGN(start);
431
        end = ALPHA_PAGE_ALIGN(end);
432
        if (end <= start)
433
                return;
434
        if((long)mmap4k(start, end - start,
435
                PROT_READ | PROT_WRITE | PROT_EXEC,
436
                MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
437
            perror("cannot mmap brk");
438
            exit(-1);
439
        }
440
}
441

    
442

    
443
/* We need to explicitly zero any fractional pages
444
   after the data section (i.e. bss).  This would
445
   contain the junk from the file that should not
446
   be in memory */
447

    
448

    
449
static void padzero(unsigned long elf_bss)
450
{
451
        unsigned long nbyte;
452
        char * fpnt;
453

    
454
        nbyte = elf_bss & (ALPHA_PAGE_SIZE-1);        /* was X86_PAGE_SIZE - JRP */
455
        if (nbyte) {
456
            nbyte = ALPHA_PAGE_SIZE - nbyte;
457
            fpnt = (char *) elf_bss;
458
            do {
459
                *fpnt++ = 0;
460
            } while (--nbyte);
461
        }
462
}
463

    
464
static unsigned int * create_elf_tables(char *p, int argc, int envc,
465
                                        struct elfhdr * exec,
466
                                        unsigned long load_addr,
467
                                        unsigned long load_bias,
468
                                        unsigned long interp_load_addr, int ibcs,
469
                                        struct image_info *info)
470
{
471
        target_ulong *argv, *envp, *dlinfo;
472
        target_ulong *sp;
473

    
474
        /*
475
         * Force 16 byte alignment here for generality.
476
         */
477
        sp = (unsigned int *) (~15UL & (unsigned long) p);
478
        sp -= exec ? DLINFO_ITEMS*2 : 2;
479
        dlinfo = sp;
480
        sp -= envc+1;
481
        envp = sp;
482
        sp -= argc+1;
483
        argv = sp;
484
        if (!ibcs) {
485
                put_user(tswapl((target_ulong)envp),--sp);
486
                put_user(tswapl((target_ulong)argv),--sp);
487
        }
488

    
489
#define NEW_AUX_ENT(id, val) \
490
          put_user (tswapl(id), dlinfo++); \
491
          put_user (tswapl(val), dlinfo++)
492

    
493
        if (exec) { /* Put this here for an ELF program interpreter */
494
          NEW_AUX_ENT (AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
495
          NEW_AUX_ENT (AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
496
          NEW_AUX_ENT (AT_PHNUM, (target_ulong)(exec->e_phnum));
497
          NEW_AUX_ENT (AT_PAGESZ, (target_ulong)(ALPHA_PAGE_SIZE));
498
          NEW_AUX_ENT (AT_BASE, (target_ulong)(interp_load_addr));
499
          NEW_AUX_ENT (AT_FLAGS, (target_ulong)0);
500
          NEW_AUX_ENT (AT_ENTRY, load_bias + exec->e_entry);
501
          NEW_AUX_ENT (AT_UID, (target_ulong) getuid());
502
          NEW_AUX_ENT (AT_EUID, (target_ulong) geteuid());
503
          NEW_AUX_ENT (AT_GID, (target_ulong) getgid());
504
          NEW_AUX_ENT (AT_EGID, (target_ulong) getegid());
505
        }
506
        NEW_AUX_ENT (AT_NULL, 0);
507
#undef NEW_AUX_ENT
508
        put_user(tswapl(argc),--sp);
509
        info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
510
        while (argc-->0) {
511
                put_user(tswapl((target_ulong)p),argv++);
512
                while (get_user(p++)) /* nothing */ ;
513
        }
514
        put_user(0,argv);
515
        info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
516
        while (envc-->0) {
517
                put_user(tswapl((target_ulong)p),envp++);
518
                while (get_user(p++)) /* nothing */ ;
519
        }
520
        put_user(0,envp);
521
        info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
522
        return sp;
523
}
524

    
525

    
526

    
527
static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
528
                                     int interpreter_fd,
529
                                     unsigned long *interp_load_addr)
530
{
531
        struct elf_phdr *elf_phdata  =  NULL;
532
        struct elf_phdr *eppnt;
533
        unsigned long load_addr = 0;
534
        int load_addr_set = 0;
535
        int retval;
536
        unsigned long last_bss, elf_bss;
537
        unsigned long error;
538
        int i;
539
        
540
        elf_bss = 0;
541
        last_bss = 0;
542
        error = 0;
543

    
544
#ifdef BSWAP_NEEDED
545
        bswap_ehdr(interp_elf_ex);
546
#endif
547
        /* First of all, some simple consistency checks */
548
        if ((interp_elf_ex->e_type != ET_EXEC && 
549
             interp_elf_ex->e_type != ET_DYN) || 
550
           !elf_check_arch(interp_elf_ex->e_machine)) {
551
                return ~0UL;
552
        }
553
        
554

    
555
        /* Now read in all of the header information */
556
        
557
        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > X86_PAGE_SIZE)
558
            return ~0UL;
559
        
560
        elf_phdata =  (struct elf_phdr *) 
561
                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
562

    
563
        if (!elf_phdata)
564
          return ~0UL;
565
        
566
        /*
567
         * If the size of this structure has changed, then punt, since
568
         * we will be doing the wrong thing.
569
         */
570
        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
571
            free(elf_phdata);
572
            return ~0UL;
573
        }
574

    
575
        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
576
        if(retval >= 0) {
577
            retval = read(interpreter_fd,
578
                           (char *) elf_phdata,
579
                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
580
        }
581
        if (retval < 0) {
582
                perror("load_elf_interp");
583
                exit(-1);
584
                free (elf_phdata);
585
                return retval;
586
         }
587
#ifdef BSWAP_NEEDED
588
        eppnt = elf_phdata;
589
        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
590
            bswap_phdr(eppnt);
591
        }
592
#endif
593

    
594
        if (interp_elf_ex->e_type == ET_DYN) {
595
            /* in order to avoid harcoding the interpreter load
596
               address in qemu, we allocate a big enough memory zone */
597
            error = (unsigned long)mmap4k(NULL, INTERP_MAP_SIZE,
598
                                          PROT_NONE, MAP_PRIVATE | MAP_ANON, 
599
                                          -1, 0);
600
            if (error == -1) {
601
                perror("mmap");
602
                exit(-1);
603
            }
604
            load_addr = error;
605
            load_addr_set = 1;
606
        }
607

    
608
        eppnt = elf_phdata;
609
        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
610
          if (eppnt->p_type == PT_LOAD) {
611
            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
612
            int elf_prot = 0;
613
            unsigned long vaddr = 0;
614
            unsigned long k;
615

    
616
            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
617
            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
618
            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
619
            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
620
                    elf_type |= MAP_FIXED;
621
                    vaddr = eppnt->p_vaddr;
622
            }
623
            error = (unsigned long)mmap4k(load_addr+X86_ELF_PAGESTART(vaddr),
624
                 eppnt->p_filesz + X86_ELF_PAGEOFFSET(eppnt->p_vaddr),
625
                 elf_prot,
626
                 elf_type,
627
                 interpreter_fd,
628
                 eppnt->p_offset - X86_ELF_PAGEOFFSET(eppnt->p_vaddr));
629
            
630
            if (error > -1024UL) {
631
              /* Real error */
632
              close(interpreter_fd);
633
              free(elf_phdata);
634
              return ~0UL;
635
            }
636

    
637
            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
638
              load_addr = error;
639
              load_addr_set = 1;
640
            }
641

    
642
            /*
643
             * Find the end of the file  mapping for this phdr, and keep
644
             * track of the largest address we see for this.
645
             */
646
            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
647
            if (k > elf_bss) elf_bss = k;
648

    
649
            /*
650
             * Do the same thing for the memory mapping - between
651
             * elf_bss and last_bss is the bss section.
652
             */
653
            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
654
            if (k > last_bss) last_bss = k;
655
          }
656
        
657
        /* Now use mmap to map the library into memory. */
658

    
659
        close(interpreter_fd);
660

    
661
        /*
662
         * Now fill out the bss section.  First pad the last page up
663
         * to the page boundary, and then perform a mmap to make sure
664
         * that there are zeromapped pages up to and including the last
665
         * bss page.
666
         */
667
        padzero(elf_bss);
668
        elf_bss = X86_ELF_PAGESTART(elf_bss + ALPHA_PAGE_SIZE - 1); /* What we have mapped so far */
669

    
670
        /* Map the last of the bss segment */
671
        if (last_bss > elf_bss) {
672
          mmap4k(elf_bss, last_bss-elf_bss,
673
                  PROT_READ|PROT_WRITE|PROT_EXEC,
674
                  MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
675
        }
676
        free(elf_phdata);
677

    
678
        *interp_load_addr = load_addr;
679
        return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
680
}
681

    
682
/* Best attempt to load symbols from this ELF object. */
683
static void load_symbols(struct elfhdr *hdr, int fd)
684
{
685
    unsigned int i;
686
    struct elf_shdr sechdr, symtab, strtab;
687
    char *strings;
688

    
689
    lseek(fd, hdr->e_shoff, SEEK_SET);
690
    for (i = 0; i < hdr->e_shnum; i++) {
691
        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
692
            return;
693
#ifdef BSWAP_NEEDED
694
        bswap_shdr(&sechdr);
695
#endif
696
        if (sechdr.sh_type == SHT_SYMTAB) {
697
            symtab = sechdr;
698
            lseek(fd, hdr->e_shoff
699
                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
700
            if (read(fd, &strtab, sizeof(strtab))
701
                != sizeof(strtab))
702
                return;
703
#ifdef BSWAP_NEEDED
704
            bswap_shdr(&strtab);
705
#endif
706
            goto found;
707
        }
708
    }
709
    return; /* Shouldn't happen... */
710

    
711
 found:
712
    /* Now know where the strtab and symtab are.  Snarf them. */
713
    disas_symtab = malloc(symtab.sh_size);
714
    disas_strtab = strings = malloc(strtab.sh_size);
715
    if (!disas_symtab || !disas_strtab)
716
        return;
717
        
718
    lseek(fd, symtab.sh_offset, SEEK_SET);
719
    if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
720
        return;
721

    
722
#ifdef BSWAP_NEEDED
723
    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
724
        bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
725
#endif
726

    
727
    lseek(fd, strtab.sh_offset, SEEK_SET);
728
    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
729
        return;
730
    disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
731
}
732

    
733
static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
734
                           struct image_info * info)
735
{
736
    struct elfhdr elf_ex;
737
    struct elfhdr interp_elf_ex;
738
    struct exec interp_ex;
739
    int interpreter_fd = -1; /* avoid warning */
740
    unsigned long load_addr, load_bias;
741
    int load_addr_set = 0;
742
    unsigned int interpreter_type = INTERPRETER_NONE;
743
    unsigned char ibcs2_interpreter;
744
    int i;
745
    void * mapped_addr;
746
    struct elf_phdr * elf_ppnt;
747
    struct elf_phdr *elf_phdata;
748
    unsigned long elf_bss, k, elf_brk;
749
    int retval;
750
    char * elf_interpreter;
751
    unsigned long elf_entry, interp_load_addr = 0;
752
    int status;
753
    unsigned long start_code, end_code, end_data;
754
    unsigned long elf_stack;
755
    char passed_fileno[6];
756

    
757
    ibcs2_interpreter = 0;
758
    status = 0;
759
    load_addr = 0;
760
    load_bias = 0;
761
    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
762
#ifdef BSWAP_NEEDED
763
    bswap_ehdr(&elf_ex);
764
#endif
765

    
766
    if (elf_ex.e_ident[0] != 0x7f ||
767
        strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
768
            return  -ENOEXEC;
769
    }
770

    
771
    /* First of all, some simple consistency checks */
772
    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
773
                                       (! elf_check_arch(elf_ex.e_machine))) {
774
            return -ENOEXEC;
775
    }
776

    
777
    /* Now read in all of the header information */
778

    
779
    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
780
    if (elf_phdata == NULL) {
781
        return -ENOMEM;
782
    }
783

    
784
    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
785
    if(retval > 0) {
786
        retval = read(bprm->fd, (char *) elf_phdata, 
787
                                elf_ex.e_phentsize * elf_ex.e_phnum);
788
    }
789

    
790
    if (retval < 0) {
791
        perror("load_elf_binary");
792
        exit(-1);
793
        free (elf_phdata);
794
        return -errno;
795
    }
796

    
797
#ifdef BSWAP_NEEDED
798
    elf_ppnt = elf_phdata;
799
    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
800
        bswap_phdr(elf_ppnt);
801
    }
802
#endif
803
    elf_ppnt = elf_phdata;
804

    
805
    elf_bss = 0;
806
    elf_brk = 0;
807

    
808

    
809
    elf_stack = ~0UL;
810
    elf_interpreter = NULL;
811
    start_code = ~0UL;
812
    end_code = 0;
813
    end_data = 0;
814

    
815
    for(i=0;i < elf_ex.e_phnum; i++) {
816
        if (elf_ppnt->p_type == PT_INTERP) {
817
            if ( elf_interpreter != NULL )
818
            {
819
                free (elf_phdata);
820
                free(elf_interpreter);
821
                close(bprm->fd);
822
                return -EINVAL;
823
            }
824

    
825
            /* This is the program interpreter used for
826
             * shared libraries - for now assume that this
827
             * is an a.out format binary
828
             */
829

    
830
            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
831

    
832
            if (elf_interpreter == NULL) {
833
                free (elf_phdata);
834
                close(bprm->fd);
835
                return -ENOMEM;
836
            }
837

    
838
            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
839
            if(retval >= 0) {
840
                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
841
            }
842
            if(retval < 0) {
843
                 perror("load_elf_binary2");
844
                exit(-1);
845
            }        
846

    
847
            /* If the program interpreter is one of these two,
848
               then assume an iBCS2 image. Otherwise assume
849
               a native linux image. */
850

    
851
            /* JRP - Need to add X86 lib dir stuff here... */
852

    
853
            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
854
                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
855
              ibcs2_interpreter = 1;
856
            }
857

    
858
#if 0
859
            printf("Using ELF interpreter %s\n", elf_interpreter);
860
#endif
861
            if (retval >= 0) {
862
                retval = open(path(elf_interpreter), O_RDONLY);
863
                if(retval >= 0) {
864
                    interpreter_fd = retval;
865
                }
866
                else {
867
                    perror(elf_interpreter);
868
                    exit(-1);
869
                    /* retval = -errno; */
870
                }
871
            }
872

    
873
            if (retval >= 0) {
874
                retval = lseek(interpreter_fd, 0, SEEK_SET);
875
                if(retval >= 0) {
876
                    retval = read(interpreter_fd,bprm->buf,128);
877
                }
878
            }
879
            if (retval >= 0) {
880
                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
881
                interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
882
            }
883
            if (retval < 0) {
884
                perror("load_elf_binary3");
885
                exit(-1);
886
                free (elf_phdata);
887
                free(elf_interpreter);
888
                close(bprm->fd);
889
                return retval;
890
            }
891
        }
892
        elf_ppnt++;
893
    }
894

    
895
    /* Some simple consistency checks for the interpreter */
896
    if (elf_interpreter){
897
        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
898

    
899
        /* Now figure out which format our binary is */
900
        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
901
                    (N_MAGIC(interp_ex) != QMAGIC)) {
902
          interpreter_type = INTERPRETER_ELF;
903
        }
904

    
905
        if (interp_elf_ex.e_ident[0] != 0x7f ||
906
                    strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
907
            interpreter_type &= ~INTERPRETER_ELF;
908
        }
909

    
910
        if (!interpreter_type) {
911
            free(elf_interpreter);
912
            free(elf_phdata);
913
            close(bprm->fd);
914
            return -ELIBBAD;
915
        }
916
    }
917

    
918
    /* OK, we are done with that, now set up the arg stuff,
919
       and then start this sucker up */
920

    
921
    if (!bprm->sh_bang) {
922
        char * passed_p;
923

    
924
        if (interpreter_type == INTERPRETER_AOUT) {
925
            sprintf(passed_fileno, "%d", bprm->fd);
926
            passed_p = passed_fileno;
927

    
928
            if (elf_interpreter) {
929
                bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
930
                bprm->argc++;
931
            }
932
        }
933
        if (!bprm->p) {
934
            if (elf_interpreter) {
935
                free(elf_interpreter);
936
            }
937
            free (elf_phdata);
938
            close(bprm->fd);
939
            return -E2BIG;
940
        }
941
    }
942

    
943
    /* OK, This is the point of no return */
944
    info->end_data = 0;
945
    info->end_code = 0;
946
    info->start_mmap = (unsigned long)ELF_START_MMAP;
947
    info->mmap = 0;
948
    elf_entry = (unsigned long) elf_ex.e_entry;
949

    
950
    /* Do this so that we can load the interpreter, if need be.  We will
951
       change some of these later */
952
    info->rss = 0;
953
    bprm->p = setup_arg_pages(bprm->p, bprm, info);
954
    info->start_stack = bprm->p;
955

    
956
    /* Now we do a little grungy work by mmaping the ELF image into
957
     * the correct location in memory.  At this point, we assume that
958
     * the image should be loaded at fixed address, not at a variable
959
     * address.
960
     */
961

    
962
    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
963
        int elf_prot = 0;
964
        int elf_flags = 0;
965
        unsigned long error;
966
        
967
        if (elf_ppnt->p_type != PT_LOAD)
968
            continue;
969
        
970
        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
971
        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
972
        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
973
        elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
974
        if (elf_ex.e_type == ET_EXEC || load_addr_set) {
975
            elf_flags |= MAP_FIXED;
976
        } else if (elf_ex.e_type == ET_DYN) {
977
            /* Try and get dynamic programs out of the way of the default mmap
978
               base, as well as whatever program they might try to exec.  This
979
               is because the brk will follow the loader, and is not movable.  */
980
            /* NOTE: for qemu, we do a big mmap to get enough space
981
               without harcoding any address */
982
            error = (unsigned long)mmap4k(NULL, ET_DYN_MAP_SIZE,
983
                                          PROT_NONE, MAP_PRIVATE | MAP_ANON, 
984
                                          -1, 0);
985
            if (error == -1) {
986
                perror("mmap");
987
                exit(-1);
988
            }
989
            load_bias = X86_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
990
        }
991
        
992
        error = (unsigned long)mmap4k(
993
                                      X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
994
                                      (elf_ppnt->p_filesz +
995
                                       X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
996
                                      elf_prot,
997
                                      (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
998
                                      bprm->fd,
999
                                      (elf_ppnt->p_offset - 
1000
                                       X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
1001
        if (error == -1) {
1002
            perror("mmap");
1003
            exit(-1);
1004
        }
1005

    
1006
#ifdef LOW_ELF_STACK
1007
        if (X86_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
1008
            elf_stack = X86_ELF_PAGESTART(elf_ppnt->p_vaddr);
1009
#endif
1010
        
1011
        if (!load_addr_set) {
1012
            load_addr_set = 1;
1013
            load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
1014
            if (elf_ex.e_type == ET_DYN) {
1015
                load_bias += error -
1016
                    X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
1017
                load_addr += load_bias;
1018
            }
1019
        }
1020
        k = elf_ppnt->p_vaddr;
1021
        if (k < start_code) 
1022
            start_code = k;
1023
        k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1024
        if (k > elf_bss) 
1025
            elf_bss = k;
1026
        if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
1027
            end_code = k;
1028
        if (end_data < k) 
1029
            end_data = k;
1030
        k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1031
        if (k > elf_brk) elf_brk = k;
1032
    }
1033

    
1034
    elf_entry += load_bias;
1035
    elf_bss += load_bias;
1036
    elf_brk += load_bias;
1037
    start_code += load_bias;
1038
    end_code += load_bias;
1039
    //    start_data += load_bias;
1040
    end_data += load_bias;
1041

    
1042
    if (elf_interpreter) {
1043
        if (interpreter_type & 1) {
1044
            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1045
        }
1046
        else if (interpreter_type & 2) {
1047
            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1048
                                            &interp_load_addr);
1049
        }
1050

    
1051
        close(interpreter_fd);
1052
        free(elf_interpreter);
1053

    
1054
        if (elf_entry == ~0UL) {
1055
            printf("Unable to load interpreter\n");
1056
            free(elf_phdata);
1057
            exit(-1);
1058
            return 0;
1059
        }
1060
    }
1061

    
1062
    free(elf_phdata);
1063

    
1064
    if (loglevel)
1065
        load_symbols(&elf_ex, bprm->fd);
1066

    
1067
    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1068
    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1069

    
1070
#ifdef LOW_ELF_STACK
1071
    info->start_stack = bprm->p = elf_stack - 4;
1072
#endif
1073
    bprm->p = (unsigned long)
1074
      create_elf_tables((char *)bprm->p,
1075
                    bprm->argc,
1076
                    bprm->envc,
1077
                    (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
1078
                    load_addr, load_bias,
1079
                    interp_load_addr,
1080
                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1081
                    info);
1082
    if (interpreter_type == INTERPRETER_AOUT)
1083
      info->arg_start += strlen(passed_fileno) + 1;
1084
    info->start_brk = info->brk = elf_brk;
1085
    info->end_code = end_code;
1086
    info->start_code = start_code;
1087
    info->end_data = end_data;
1088
    info->start_stack = bprm->p;
1089

    
1090
    /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1091
       sections */
1092
    set_brk(elf_bss, elf_brk);
1093

    
1094
    padzero(elf_bss);
1095

    
1096
#if 0
1097
    printf("(start_brk) %x\n" , info->start_brk);
1098
    printf("(end_code) %x\n" , info->end_code);
1099
    printf("(start_code) %x\n" , info->start_code);
1100
    printf("(end_data) %x\n" , info->end_data);
1101
    printf("(start_stack) %x\n" , info->start_stack);
1102
    printf("(brk) %x\n" , info->brk);
1103
#endif
1104

    
1105
    if ( info->personality == PER_SVR4 )
1106
    {
1107
            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1108
               and some applications "depend" upon this behavior.
1109
               Since we do not have the power to recompile these, we
1110
               emulate the SVr4 behavior.  Sigh.  */
1111
            mapped_addr = mmap4k(NULL, ALPHA_PAGE_SIZE, PROT_READ | PROT_EXEC,
1112
                            MAP_FIXED | MAP_PRIVATE, -1, 0);
1113
    }
1114

    
1115
#ifdef ELF_PLAT_INIT
1116
    /*
1117
     * The ABI may specify that certain registers be set up in special
1118
     * ways (on i386 %edx is the address of a DT_FINI function, for
1119
     * example.  This macro performs whatever initialization to
1120
     * the regs structure is required.
1121
     */
1122
    ELF_PLAT_INIT(regs);
1123
#endif
1124

    
1125

    
1126
    info->entry = elf_entry;
1127

    
1128
    return 0;
1129
}
1130

    
1131

    
1132

    
1133
int elf_exec(const char * filename, char ** argv, char ** envp, 
1134
             struct target_pt_regs * regs, struct image_info *infop)
1135
{
1136
        struct linux_binprm bprm;
1137
        int retval;
1138
        int i;
1139

    
1140
        bprm.p = X86_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1141
        for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
1142
                bprm.page[i] = 0;
1143
        retval = open(filename, O_RDONLY);
1144
        if (retval == -1) {
1145
            perror(filename);
1146
            exit(-1);
1147
            /* return retval; */
1148
        }
1149
        else {
1150
            bprm.fd = retval;
1151
        }
1152
        bprm.filename = (char *)filename;
1153
        bprm.sh_bang = 0;
1154
        bprm.loader = 0;
1155
        bprm.exec = 0;
1156
        bprm.dont_iput = 0;
1157
        bprm.argc = count(argv);
1158
        bprm.envc = count(envp);
1159

    
1160
        retval = prepare_binprm(&bprm);
1161

    
1162
        if(retval>=0) {
1163
            bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1164
            bprm.exec = bprm.p;
1165
            bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1166
            bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1167
            if (!bprm.p) {
1168
                retval = -E2BIG;
1169
            }
1170
        }
1171

    
1172
        if(retval>=0) {
1173
            retval = load_elf_binary(&bprm,regs,infop);
1174
        }
1175
        if(retval>=0) {
1176
            /* success.  Initialize important registers */
1177
            regs->esp = infop->start_stack;
1178
            regs->eip = infop->entry;
1179
            return retval;
1180
        }
1181

    
1182
        /* Something went wrong, return the inode and free the argument pages*/
1183
        for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1184
            free_page((void *)bprm.page[i]);
1185
        }
1186
        return(retval);
1187
}
1188

    
1189

    
1190
static int load_aout_interp(void * exptr, int interp_fd)
1191
{
1192
    printf("a.out interpreter not yet supported\n");
1193
    return(0);
1194
}
1195