Statistics
| Branch: | Revision:

root / linux-user / elfload.c @ 5a91de8c

History | View | Annotate | Download (32.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
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
/* max code+data+bss space allocated to elf interpreter */
99
#define INTERP_MAP_SIZE (32 * 1024 * 1024)
100

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

    
104
/* from personality.h */
105

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

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

    
123
/* Necessary parameters */
124
#define NGROUPS 32
125

    
126
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
127
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
128
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
129

    
130
#define INTERPRETER_NONE 0
131
#define INTERPRETER_AOUT 1
132
#define INTERPRETER_ELF 2
133

    
134
#define DLINFO_ITEMS 12
135

    
136
#define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
137
#define get_user(ptr) (typeof(*ptr))(*(ptr))
138

    
139
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
140
{
141
        memcpy(to, from, n);
142
}
143

    
144
static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
145
{
146
        memcpy(to, from, n);
147
}
148

    
149
extern unsigned long x86_stack_size;
150

    
151
static int load_aout_interp(void * exptr, int interp_fd);
152

    
153
#ifdef BSWAP_NEEDED
154
static void bswap_ehdr(Elf32_Ehdr *ehdr)
155
{
156
    bswap16s(&ehdr->e_type);                        /* Object file type */
157
    bswap16s(&ehdr->e_machine);                /* Architecture */
158
    bswap32s(&ehdr->e_version);                /* Object file version */
159
    bswap32s(&ehdr->e_entry);                /* Entry point virtual address */
160
    bswap32s(&ehdr->e_phoff);                /* Program header table file offset */
161
    bswap32s(&ehdr->e_shoff);                /* Section header table file offset */
162
    bswap32s(&ehdr->e_flags);                /* Processor-specific flags */
163
    bswap16s(&ehdr->e_ehsize);                /* ELF header size in bytes */
164
    bswap16s(&ehdr->e_phentsize);                /* Program header table entry size */
165
    bswap16s(&ehdr->e_phnum);                /* Program header table entry count */
166
    bswap16s(&ehdr->e_shentsize);                /* Section header table entry size */
167
    bswap16s(&ehdr->e_shnum);                /* Section header table entry count */
168
    bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */
169
}
170

    
171
static void bswap_phdr(Elf32_Phdr *phdr)
172
{
173
    bswap32s(&phdr->p_type);                        /* Segment type */
174
    bswap32s(&phdr->p_offset);                /* Segment file offset */
175
    bswap32s(&phdr->p_vaddr);                /* Segment virtual address */
176
    bswap32s(&phdr->p_paddr);                /* Segment physical address */
177
    bswap32s(&phdr->p_filesz);                /* Segment size in file */
178
    bswap32s(&phdr->p_memsz);                /* Segment size in memory */
179
    bswap32s(&phdr->p_flags);                /* Segment flags */
180
    bswap32s(&phdr->p_align);                /* Segment alignment */
181
}
182

    
183
static void bswap_shdr(Elf32_Shdr *shdr)
184
{
185
    bswap32s(&shdr->sh_name);
186
    bswap32s(&shdr->sh_type);
187
    bswap32s(&shdr->sh_flags);
188
    bswap32s(&shdr->sh_addr);
189
    bswap32s(&shdr->sh_offset);
190
    bswap32s(&shdr->sh_size);
191
    bswap32s(&shdr->sh_link);
192
    bswap32s(&shdr->sh_info);
193
    bswap32s(&shdr->sh_addralign);
194
    bswap32s(&shdr->sh_entsize);
195
}
196

    
197
static void bswap_sym(Elf32_Sym *sym)
198
{
199
    bswap32s(&sym->st_name);
200
    bswap32s(&sym->st_value);
201
    bswap32s(&sym->st_size);
202
    bswap16s(&sym->st_shndx);
203
}
204
#endif
205

    
206
static void * get_free_page(void)
207
{
208
    void *        retval;
209

    
210
    /* User-space version of kernel get_free_page.  Returns a page-aligned
211
     * page-sized chunk of memory.
212
     */
213
    retval = (void *)target_mmap(0, host_page_size, PROT_READ|PROT_WRITE, 
214
                                 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
215

    
216
    if((long)retval == -1) {
217
        perror("get_free_page");
218
        exit(-1);
219
    }
220
    else {
221
        return(retval);
222
    }
223
}
224

    
225
static void free_page(void * pageaddr)
226
{
227
    target_munmap((unsigned long)pageaddr, host_page_size);
228
}
229

    
230
/*
231
 * 'copy_string()' copies argument/envelope strings from user
232
 * memory to free pages in kernel mem. These are in a format ready
233
 * to be put directly into the top of new user memory.
234
 *
235
 */
236
static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
237
                unsigned long p)
238
{
239
    char *tmp, *tmp1, *pag = NULL;
240
    int len, offset = 0;
241

    
242
    if (!p) {
243
        return 0;       /* bullet-proofing */
244
    }
245
    while (argc-- > 0) {
246
        if (!(tmp1 = tmp = get_user(argv+argc))) {
247
            fprintf(stderr, "VFS: argc is wrong");
248
            exit(-1);
249
        }
250
        while (get_user(tmp++));
251
        len = tmp - tmp1;
252
        if (p < len) {  /* this shouldn't happen - 128kB */
253
                return 0;
254
        }
255
        while (len) {
256
            --p; --tmp; --len;
257
            if (--offset < 0) {
258
                offset = p % TARGET_PAGE_SIZE;
259
                if (!(pag = (char *) page[p/TARGET_PAGE_SIZE]) &&
260
                    !(pag = (char *) page[p/TARGET_PAGE_SIZE] =
261
                      (unsigned long *) get_free_page())) {
262
                        return 0;
263
                }
264
            }
265
            if (len == 0 || offset == 0) {
266
                *(pag + offset) = get_user(tmp);
267
            }
268
            else {
269
              int bytes_to_copy = (len > offset) ? offset : len;
270
              tmp -= bytes_to_copy;
271
              p -= bytes_to_copy;
272
              offset -= bytes_to_copy;
273
              len -= bytes_to_copy;
274
              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
275
            }
276
        }
277
    }
278
    return p;
279
}
280

    
281
static int in_group_p(gid_t g)
282
{
283
    /* return TRUE if we're in the specified group, FALSE otherwise */
284
    int                ngroup;
285
    int                i;
286
    gid_t        grouplist[NGROUPS];
287

    
288
    ngroup = getgroups(NGROUPS, grouplist);
289
    for(i = 0; i < ngroup; i++) {
290
        if(grouplist[i] == g) {
291
            return 1;
292
        }
293
    }
294
    return 0;
295
}
296

    
297
static int count(char ** vec)
298
{
299
    int                i;
300

    
301
    for(i = 0; *vec; i++) {
302
        vec++;
303
    }
304

    
305
    return(i);
306
}
307

    
308
static int prepare_binprm(struct linux_binprm *bprm)
309
{
310
    struct stat                st;
311
    int mode;
312
    int retval, id_change;
313

    
314
    if(fstat(bprm->fd, &st) < 0) {
315
        return(-errno);
316
    }
317

    
318
    mode = st.st_mode;
319
    if(!S_ISREG(mode)) {        /* Must be regular file */
320
        return(-EACCES);
321
    }
322
    if(!(mode & 0111)) {        /* Must have at least one execute bit set */
323
        return(-EACCES);
324
    }
325

    
326
    bprm->e_uid = geteuid();
327
    bprm->e_gid = getegid();
328
    id_change = 0;
329

    
330
    /* Set-uid? */
331
    if(mode & S_ISUID) {
332
            bprm->e_uid = st.st_uid;
333
        if(bprm->e_uid != geteuid()) {
334
            id_change = 1;
335
        }
336
    }
337

    
338
    /* Set-gid? */
339
    /*
340
     * If setgid is set but no group execute bit then this
341
     * is a candidate for mandatory locking, not a setgid
342
     * executable.
343
     */
344
    if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
345
        bprm->e_gid = st.st_gid;
346
        if (!in_group_p(bprm->e_gid)) {
347
                id_change = 1;
348
        }
349
    }
350

    
351
    memset(bprm->buf, 0, sizeof(bprm->buf));
352
    retval = lseek(bprm->fd, 0L, SEEK_SET);
353
    if(retval >= 0) {
354
        retval = read(bprm->fd, bprm->buf, 128);
355
    }
356
    if(retval < 0) {
357
        perror("prepare_binprm");
358
        exit(-1);
359
        /* return(-errno); */
360
    }
361
    else {
362
        return(retval);
363
    }
364
}
365

    
366
unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
367
                                                struct image_info * info)
368
{
369
    unsigned long stack_base, size, error;
370
    int i;
371

    
372
    /* Create enough stack to hold everything.  If we don't use
373
     * it for args, we'll use it for something else...
374
     */
375
    size = x86_stack_size;
376
    if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
377
        size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
378
    error = target_mmap(0, 
379
                        size + host_page_size,
380
                        PROT_READ | PROT_WRITE,
381
                        MAP_PRIVATE | MAP_ANONYMOUS,
382
                        -1, 0);
383
    if (error == -1) {
384
        perror("stk mmap");
385
        exit(-1);
386
    }
387
    /* we reserve one extra page at the top of the stack as guard */
388
    target_mprotect(error + size, host_page_size, PROT_NONE);
389

    
390
    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;
391
    p += stack_base;
392

    
393
    if (bprm->loader) {
394
        bprm->loader += stack_base;
395
    }
396
    bprm->exec += stack_base;
397

    
398
    for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
399
        if (bprm->page[i]) {
400
            info->rss++;
401

    
402
            memcpy((void *)stack_base, (void *)bprm->page[i], TARGET_PAGE_SIZE);
403
            free_page((void *)bprm->page[i]);
404
        }
405
        stack_base += TARGET_PAGE_SIZE;
406
    }
407
    return p;
408
}
409

    
410
static void set_brk(unsigned long start, unsigned long end)
411
{
412
        /* page-align the start and end addresses... */
413
        start = HOST_PAGE_ALIGN(start);
414
        end = HOST_PAGE_ALIGN(end);
415
        if (end <= start)
416
                return;
417
        if(target_mmap(start, end - start,
418
                       PROT_READ | PROT_WRITE | PROT_EXEC,
419
                       MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
420
            perror("cannot mmap brk");
421
            exit(-1);
422
        }
423
}
424

    
425

    
426
/* We need to explicitly zero any fractional pages
427
   after the data section (i.e. bss).  This would
428
   contain the junk from the file that should not
429
   be in memory */
430

    
431

    
432
static void padzero(unsigned long elf_bss)
433
{
434
        unsigned long nbyte;
435
        char * fpnt;
436

    
437
        nbyte = elf_bss & (host_page_size-1);        /* was TARGET_PAGE_SIZE - JRP */
438
        if (nbyte) {
439
            nbyte = host_page_size - nbyte;
440
            fpnt = (char *) elf_bss;
441
            do {
442
                *fpnt++ = 0;
443
            } while (--nbyte);
444
        }
445
}
446

    
447
static unsigned int * create_elf_tables(char *p, int argc, int envc,
448
                                        struct elfhdr * exec,
449
                                        unsigned long load_addr,
450
                                        unsigned long load_bias,
451
                                        unsigned long interp_load_addr, int ibcs,
452
                                        struct image_info *info)
453
{
454
        target_ulong *argv, *envp, *dlinfo;
455
        target_ulong *sp;
456

    
457
        /*
458
         * Force 16 byte alignment here for generality.
459
         */
460
        sp = (unsigned int *) (~15UL & (unsigned long) p);
461
        sp -= exec ? DLINFO_ITEMS*2 : 2;
462
        dlinfo = sp;
463
        sp -= envc+1;
464
        envp = sp;
465
        sp -= argc+1;
466
        argv = sp;
467
        if (!ibcs) {
468
                put_user(tswapl((target_ulong)envp),--sp);
469
                put_user(tswapl((target_ulong)argv),--sp);
470
        }
471

    
472
#define NEW_AUX_ENT(id, val) \
473
          put_user (tswapl(id), dlinfo++); \
474
          put_user (tswapl(val), dlinfo++)
475

    
476
        if (exec) { /* Put this here for an ELF program interpreter */
477
          NEW_AUX_ENT (AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
478
          NEW_AUX_ENT (AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
479
          NEW_AUX_ENT (AT_PHNUM, (target_ulong)(exec->e_phnum));
480
          NEW_AUX_ENT (AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
481
          NEW_AUX_ENT (AT_BASE, (target_ulong)(interp_load_addr));
482
          NEW_AUX_ENT (AT_FLAGS, (target_ulong)0);
483
          NEW_AUX_ENT (AT_ENTRY, load_bias + exec->e_entry);
484
          NEW_AUX_ENT (AT_UID, (target_ulong) getuid());
485
          NEW_AUX_ENT (AT_EUID, (target_ulong) geteuid());
486
          NEW_AUX_ENT (AT_GID, (target_ulong) getgid());
487
          NEW_AUX_ENT (AT_EGID, (target_ulong) getegid());
488
        }
489
        NEW_AUX_ENT (AT_NULL, 0);
490
#undef NEW_AUX_ENT
491
        put_user(tswapl(argc),--sp);
492
        info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
493
        while (argc-->0) {
494
                put_user(tswapl((target_ulong)p),argv++);
495
                while (get_user(p++)) /* nothing */ ;
496
        }
497
        put_user(0,argv);
498
        info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
499
        while (envc-->0) {
500
                put_user(tswapl((target_ulong)p),envp++);
501
                while (get_user(p++)) /* nothing */ ;
502
        }
503
        put_user(0,envp);
504
        info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
505
        return sp;
506
}
507

    
508

    
509

    
510
static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
511
                                     int interpreter_fd,
512
                                     unsigned long *interp_load_addr)
513
{
514
        struct elf_phdr *elf_phdata  =  NULL;
515
        struct elf_phdr *eppnt;
516
        unsigned long load_addr = 0;
517
        int load_addr_set = 0;
518
        int retval;
519
        unsigned long last_bss, elf_bss;
520
        unsigned long error;
521
        int i;
522
        
523
        elf_bss = 0;
524
        last_bss = 0;
525
        error = 0;
526

    
527
#ifdef BSWAP_NEEDED
528
        bswap_ehdr(interp_elf_ex);
529
#endif
530
        /* First of all, some simple consistency checks */
531
        if ((interp_elf_ex->e_type != ET_EXEC && 
532
             interp_elf_ex->e_type != ET_DYN) || 
533
           !elf_check_arch(interp_elf_ex->e_machine)) {
534
                return ~0UL;
535
        }
536
        
537

    
538
        /* Now read in all of the header information */
539
        
540
        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
541
            return ~0UL;
542
        
543
        elf_phdata =  (struct elf_phdr *) 
544
                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
545

    
546
        if (!elf_phdata)
547
          return ~0UL;
548
        
549
        /*
550
         * If the size of this structure has changed, then punt, since
551
         * we will be doing the wrong thing.
552
         */
553
        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
554
            free(elf_phdata);
555
            return ~0UL;
556
        }
557

    
558
        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
559
        if(retval >= 0) {
560
            retval = read(interpreter_fd,
561
                           (char *) elf_phdata,
562
                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
563
        }
564
        if (retval < 0) {
565
                perror("load_elf_interp");
566
                exit(-1);
567
                free (elf_phdata);
568
                return retval;
569
         }
570
#ifdef BSWAP_NEEDED
571
        eppnt = elf_phdata;
572
        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
573
            bswap_phdr(eppnt);
574
        }
575
#endif
576

    
577
        if (interp_elf_ex->e_type == ET_DYN) {
578
            /* in order to avoid harcoding the interpreter load
579
               address in qemu, we allocate a big enough memory zone */
580
            error = target_mmap(0, INTERP_MAP_SIZE,
581
                                PROT_NONE, MAP_PRIVATE | MAP_ANON, 
582
                                -1, 0);
583
            if (error == -1) {
584
                perror("mmap");
585
                exit(-1);
586
            }
587
            load_addr = error;
588
            load_addr_set = 1;
589
        }
590

    
591
        eppnt = elf_phdata;
592
        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
593
          if (eppnt->p_type == PT_LOAD) {
594
            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
595
            int elf_prot = 0;
596
            unsigned long vaddr = 0;
597
            unsigned long k;
598

    
599
            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
600
            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
601
            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
602
            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
603
                    elf_type |= MAP_FIXED;
604
                    vaddr = eppnt->p_vaddr;
605
            }
606
            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr),
607
                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr),
608
                 elf_prot,
609
                 elf_type,
610
                 interpreter_fd,
611
                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr));
612
            
613
            if (error > -1024UL) {
614
              /* Real error */
615
              close(interpreter_fd);
616
              free(elf_phdata);
617
              return ~0UL;
618
            }
619

    
620
            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
621
              load_addr = error;
622
              load_addr_set = 1;
623
            }
624

    
625
            /*
626
             * Find the end of the file  mapping for this phdr, and keep
627
             * track of the largest address we see for this.
628
             */
629
            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
630
            if (k > elf_bss) elf_bss = k;
631

    
632
            /*
633
             * Do the same thing for the memory mapping - between
634
             * elf_bss and last_bss is the bss section.
635
             */
636
            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
637
            if (k > last_bss) last_bss = k;
638
          }
639
        
640
        /* Now use mmap to map the library into memory. */
641

    
642
        close(interpreter_fd);
643

    
644
        /*
645
         * Now fill out the bss section.  First pad the last page up
646
         * to the page boundary, and then perform a mmap to make sure
647
         * that there are zeromapped pages up to and including the last
648
         * bss page.
649
         */
650
        padzero(elf_bss);
651
        elf_bss = TARGET_ELF_PAGESTART(elf_bss + host_page_size - 1); /* What we have mapped so far */
652

    
653
        /* Map the last of the bss segment */
654
        if (last_bss > elf_bss) {
655
            target_mmap(elf_bss, last_bss-elf_bss,
656
                        PROT_READ|PROT_WRITE|PROT_EXEC,
657
                        MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
658
        }
659
        free(elf_phdata);
660

    
661
        *interp_load_addr = load_addr;
662
        return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
663
}
664

    
665
/* Best attempt to load symbols from this ELF object. */
666
static void load_symbols(struct elfhdr *hdr, int fd)
667
{
668
    unsigned int i;
669
    struct elf_shdr sechdr, symtab, strtab;
670
    char *strings;
671

    
672
    lseek(fd, hdr->e_shoff, SEEK_SET);
673
    for (i = 0; i < hdr->e_shnum; i++) {
674
        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
675
            return;
676
#ifdef BSWAP_NEEDED
677
        bswap_shdr(&sechdr);
678
#endif
679
        if (sechdr.sh_type == SHT_SYMTAB) {
680
            symtab = sechdr;
681
            lseek(fd, hdr->e_shoff
682
                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
683
            if (read(fd, &strtab, sizeof(strtab))
684
                != sizeof(strtab))
685
                return;
686
#ifdef BSWAP_NEEDED
687
            bswap_shdr(&strtab);
688
#endif
689
            goto found;
690
        }
691
    }
692
    return; /* Shouldn't happen... */
693

    
694
 found:
695
    /* Now know where the strtab and symtab are.  Snarf them. */
696
    disas_symtab = malloc(symtab.sh_size);
697
    disas_strtab = strings = malloc(strtab.sh_size);
698
    if (!disas_symtab || !disas_strtab)
699
        return;
700
        
701
    lseek(fd, symtab.sh_offset, SEEK_SET);
702
    if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
703
        return;
704

    
705
#ifdef BSWAP_NEEDED
706
    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
707
        bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
708
#endif
709

    
710
    lseek(fd, strtab.sh_offset, SEEK_SET);
711
    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
712
        return;
713
    disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
714
}
715

    
716
static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
717
                           struct image_info * info)
718
{
719
    struct elfhdr elf_ex;
720
    struct elfhdr interp_elf_ex;
721
    struct exec interp_ex;
722
    int interpreter_fd = -1; /* avoid warning */
723
    unsigned long load_addr, load_bias;
724
    int load_addr_set = 0;
725
    unsigned int interpreter_type = INTERPRETER_NONE;
726
    unsigned char ibcs2_interpreter;
727
    int i;
728
    unsigned long mapped_addr;
729
    struct elf_phdr * elf_ppnt;
730
    struct elf_phdr *elf_phdata;
731
    unsigned long elf_bss, k, elf_brk;
732
    int retval;
733
    char * elf_interpreter;
734
    unsigned long elf_entry, interp_load_addr = 0;
735
    int status;
736
    unsigned long start_code, end_code, end_data;
737
    unsigned long elf_stack;
738
    char passed_fileno[6];
739

    
740
    ibcs2_interpreter = 0;
741
    status = 0;
742
    load_addr = 0;
743
    load_bias = 0;
744
    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
745
#ifdef BSWAP_NEEDED
746
    bswap_ehdr(&elf_ex);
747
#endif
748

    
749
    if (elf_ex.e_ident[0] != 0x7f ||
750
        strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
751
            return  -ENOEXEC;
752
    }
753

    
754
    /* First of all, some simple consistency checks */
755
    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
756
                                       (! elf_check_arch(elf_ex.e_machine))) {
757
            return -ENOEXEC;
758
    }
759

    
760
    /* Now read in all of the header information */
761

    
762
    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
763
    if (elf_phdata == NULL) {
764
        return -ENOMEM;
765
    }
766

    
767
    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
768
    if(retval > 0) {
769
        retval = read(bprm->fd, (char *) elf_phdata, 
770
                                elf_ex.e_phentsize * elf_ex.e_phnum);
771
    }
772

    
773
    if (retval < 0) {
774
        perror("load_elf_binary");
775
        exit(-1);
776
        free (elf_phdata);
777
        return -errno;
778
    }
779

    
780
#ifdef BSWAP_NEEDED
781
    elf_ppnt = elf_phdata;
782
    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
783
        bswap_phdr(elf_ppnt);
784
    }
785
#endif
786
    elf_ppnt = elf_phdata;
787

    
788
    elf_bss = 0;
789
    elf_brk = 0;
790

    
791

    
792
    elf_stack = ~0UL;
793
    elf_interpreter = NULL;
794
    start_code = ~0UL;
795
    end_code = 0;
796
    end_data = 0;
797

    
798
    for(i=0;i < elf_ex.e_phnum; i++) {
799
        if (elf_ppnt->p_type == PT_INTERP) {
800
            if ( elf_interpreter != NULL )
801
            {
802
                free (elf_phdata);
803
                free(elf_interpreter);
804
                close(bprm->fd);
805
                return -EINVAL;
806
            }
807

    
808
            /* This is the program interpreter used for
809
             * shared libraries - for now assume that this
810
             * is an a.out format binary
811
             */
812

    
813
            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
814

    
815
            if (elf_interpreter == NULL) {
816
                free (elf_phdata);
817
                close(bprm->fd);
818
                return -ENOMEM;
819
            }
820

    
821
            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
822
            if(retval >= 0) {
823
                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
824
            }
825
            if(retval < 0) {
826
                 perror("load_elf_binary2");
827
                exit(-1);
828
            }        
829

    
830
            /* If the program interpreter is one of these two,
831
               then assume an iBCS2 image. Otherwise assume
832
               a native linux image. */
833

    
834
            /* JRP - Need to add X86 lib dir stuff here... */
835

    
836
            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
837
                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
838
              ibcs2_interpreter = 1;
839
            }
840

    
841
#if 0
842
            printf("Using ELF interpreter %s\n", elf_interpreter);
843
#endif
844
            if (retval >= 0) {
845
                retval = open(path(elf_interpreter), O_RDONLY);
846
                if(retval >= 0) {
847
                    interpreter_fd = retval;
848
                }
849
                else {
850
                    perror(elf_interpreter);
851
                    exit(-1);
852
                    /* retval = -errno; */
853
                }
854
            }
855

    
856
            if (retval >= 0) {
857
                retval = lseek(interpreter_fd, 0, SEEK_SET);
858
                if(retval >= 0) {
859
                    retval = read(interpreter_fd,bprm->buf,128);
860
                }
861
            }
862
            if (retval >= 0) {
863
                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
864
                interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
865
            }
866
            if (retval < 0) {
867
                perror("load_elf_binary3");
868
                exit(-1);
869
                free (elf_phdata);
870
                free(elf_interpreter);
871
                close(bprm->fd);
872
                return retval;
873
            }
874
        }
875
        elf_ppnt++;
876
    }
877

    
878
    /* Some simple consistency checks for the interpreter */
879
    if (elf_interpreter){
880
        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
881

    
882
        /* Now figure out which format our binary is */
883
        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
884
                    (N_MAGIC(interp_ex) != QMAGIC)) {
885
          interpreter_type = INTERPRETER_ELF;
886
        }
887

    
888
        if (interp_elf_ex.e_ident[0] != 0x7f ||
889
                    strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
890
            interpreter_type &= ~INTERPRETER_ELF;
891
        }
892

    
893
        if (!interpreter_type) {
894
            free(elf_interpreter);
895
            free(elf_phdata);
896
            close(bprm->fd);
897
            return -ELIBBAD;
898
        }
899
    }
900

    
901
    /* OK, we are done with that, now set up the arg stuff,
902
       and then start this sucker up */
903

    
904
    if (!bprm->sh_bang) {
905
        char * passed_p;
906

    
907
        if (interpreter_type == INTERPRETER_AOUT) {
908
            sprintf(passed_fileno, "%d", bprm->fd);
909
            passed_p = passed_fileno;
910

    
911
            if (elf_interpreter) {
912
                bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
913
                bprm->argc++;
914
            }
915
        }
916
        if (!bprm->p) {
917
            if (elf_interpreter) {
918
                free(elf_interpreter);
919
            }
920
            free (elf_phdata);
921
            close(bprm->fd);
922
            return -E2BIG;
923
        }
924
    }
925

    
926
    /* OK, This is the point of no return */
927
    info->end_data = 0;
928
    info->end_code = 0;
929
    info->start_mmap = (unsigned long)ELF_START_MMAP;
930
    info->mmap = 0;
931
    elf_entry = (unsigned long) elf_ex.e_entry;
932

    
933
    /* Do this so that we can load the interpreter, if need be.  We will
934
       change some of these later */
935
    info->rss = 0;
936
    bprm->p = setup_arg_pages(bprm->p, bprm, info);
937
    info->start_stack = bprm->p;
938

    
939
    /* Now we do a little grungy work by mmaping the ELF image into
940
     * the correct location in memory.  At this point, we assume that
941
     * the image should be loaded at fixed address, not at a variable
942
     * address.
943
     */
944

    
945
    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
946
        int elf_prot = 0;
947
        int elf_flags = 0;
948
        unsigned long error;
949
        
950
        if (elf_ppnt->p_type != PT_LOAD)
951
            continue;
952
        
953
        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
954
        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
955
        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
956
        elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
957
        if (elf_ex.e_type == ET_EXEC || load_addr_set) {
958
            elf_flags |= MAP_FIXED;
959
        } else if (elf_ex.e_type == ET_DYN) {
960
            /* Try and get dynamic programs out of the way of the default mmap
961
               base, as well as whatever program they might try to exec.  This
962
               is because the brk will follow the loader, and is not movable.  */
963
            /* NOTE: for qemu, we do a big mmap to get enough space
964
               without harcoding any address */
965
            error = target_mmap(0, ET_DYN_MAP_SIZE,
966
                                PROT_NONE, MAP_PRIVATE | MAP_ANON, 
967
                                -1, 0);
968
            if (error == -1) {
969
                perror("mmap");
970
                exit(-1);
971
            }
972
            load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
973
        }
974
        
975
        error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
976
                            (elf_ppnt->p_filesz +
977
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
978
                            elf_prot,
979
                            (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
980
                            bprm->fd,
981
                            (elf_ppnt->p_offset - 
982
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
983
        if (error == -1) {
984
            perror("mmap");
985
            exit(-1);
986
        }
987

    
988
#ifdef LOW_ELF_STACK
989
        if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
990
            elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr);
991
#endif
992
        
993
        if (!load_addr_set) {
994
            load_addr_set = 1;
995
            load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
996
            if (elf_ex.e_type == ET_DYN) {
997
                load_bias += error -
998
                    TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
999
                load_addr += load_bias;
1000
            }
1001
        }
1002
        k = elf_ppnt->p_vaddr;
1003
        if (k < start_code) 
1004
            start_code = k;
1005
        k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1006
        if (k > elf_bss) 
1007
            elf_bss = k;
1008
        if ((elf_ppnt->p_flags & PF_X) && end_code <  k)
1009
            end_code = k;
1010
        if (end_data < k) 
1011
            end_data = k;
1012
        k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
1013
        if (k > elf_brk) elf_brk = k;
1014
    }
1015

    
1016
    elf_entry += load_bias;
1017
    elf_bss += load_bias;
1018
    elf_brk += load_bias;
1019
    start_code += load_bias;
1020
    end_code += load_bias;
1021
    //    start_data += load_bias;
1022
    end_data += load_bias;
1023

    
1024
    if (elf_interpreter) {
1025
        if (interpreter_type & 1) {
1026
            elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
1027
        }
1028
        else if (interpreter_type & 2) {
1029
            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
1030
                                            &interp_load_addr);
1031
        }
1032

    
1033
        close(interpreter_fd);
1034
        free(elf_interpreter);
1035

    
1036
        if (elf_entry == ~0UL) {
1037
            printf("Unable to load interpreter\n");
1038
            free(elf_phdata);
1039
            exit(-1);
1040
            return 0;
1041
        }
1042
    }
1043

    
1044
    free(elf_phdata);
1045

    
1046
    if (loglevel)
1047
        load_symbols(&elf_ex, bprm->fd);
1048

    
1049
    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
1050
    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
1051

    
1052
#ifdef LOW_ELF_STACK
1053
    info->start_stack = bprm->p = elf_stack - 4;
1054
#endif
1055
    bprm->p = (unsigned long)
1056
      create_elf_tables((char *)bprm->p,
1057
                    bprm->argc,
1058
                    bprm->envc,
1059
                    (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
1060
                    load_addr, load_bias,
1061
                    interp_load_addr,
1062
                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1063
                    info);
1064
    if (interpreter_type == INTERPRETER_AOUT)
1065
      info->arg_start += strlen(passed_fileno) + 1;
1066
    info->start_brk = info->brk = elf_brk;
1067
    info->end_code = end_code;
1068
    info->start_code = start_code;
1069
    info->end_data = end_data;
1070
    info->start_stack = bprm->p;
1071

    
1072
    /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1073
       sections */
1074
    set_brk(elf_bss, elf_brk);
1075

    
1076
    padzero(elf_bss);
1077

    
1078
#if 0
1079
    printf("(start_brk) %x\n" , info->start_brk);
1080
    printf("(end_code) %x\n" , info->end_code);
1081
    printf("(start_code) %x\n" , info->start_code);
1082
    printf("(end_data) %x\n" , info->end_data);
1083
    printf("(start_stack) %x\n" , info->start_stack);
1084
    printf("(brk) %x\n" , info->brk);
1085
#endif
1086

    
1087
    if ( info->personality == PER_SVR4 )
1088
    {
1089
            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
1090
               and some applications "depend" upon this behavior.
1091
               Since we do not have the power to recompile these, we
1092
               emulate the SVr4 behavior.  Sigh.  */
1093
            mapped_addr = target_mmap(0, host_page_size, PROT_READ | PROT_EXEC,
1094
                                      MAP_FIXED | MAP_PRIVATE, -1, 0);
1095
    }
1096

    
1097
#ifdef ELF_PLAT_INIT
1098
    /*
1099
     * The ABI may specify that certain registers be set up in special
1100
     * ways (on i386 %edx is the address of a DT_FINI function, for
1101
     * example.  This macro performs whatever initialization to
1102
     * the regs structure is required.
1103
     */
1104
    ELF_PLAT_INIT(regs);
1105
#endif
1106

    
1107

    
1108
    info->entry = elf_entry;
1109

    
1110
    return 0;
1111
}
1112

    
1113

    
1114

    
1115
int elf_exec(const char * filename, char ** argv, char ** envp, 
1116
             struct target_pt_regs * regs, struct image_info *infop)
1117
{
1118
        struct linux_binprm bprm;
1119
        int retval;
1120
        int i;
1121

    
1122
        bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1123
        for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
1124
                bprm.page[i] = 0;
1125
        retval = open(filename, O_RDONLY);
1126
        if (retval == -1) {
1127
            perror(filename);
1128
            exit(-1);
1129
            /* return retval; */
1130
        }
1131
        else {
1132
            bprm.fd = retval;
1133
        }
1134
        bprm.filename = (char *)filename;
1135
        bprm.sh_bang = 0;
1136
        bprm.loader = 0;
1137
        bprm.exec = 0;
1138
        bprm.dont_iput = 0;
1139
        bprm.argc = count(argv);
1140
        bprm.envc = count(envp);
1141

    
1142
        retval = prepare_binprm(&bprm);
1143

    
1144
        if(retval>=0) {
1145
            bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1146
            bprm.exec = bprm.p;
1147
            bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1148
            bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1149
            if (!bprm.p) {
1150
                retval = -E2BIG;
1151
            }
1152
        }
1153

    
1154
        if(retval>=0) {
1155
            retval = load_elf_binary(&bprm,regs,infop);
1156
        }
1157
        if(retval>=0) {
1158
            /* success.  Initialize important registers */
1159
            regs->esp = infop->start_stack;
1160
            regs->eip = infop->entry;
1161
            return retval;
1162
        }
1163

    
1164
        /* Something went wrong, return the inode and free the argument pages*/
1165
        for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1166
            free_page((void *)bprm.page[i]);
1167
        }
1168
        return(retval);
1169
}
1170

    
1171

    
1172
static int load_aout_interp(void * exptr, int interp_fd)
1173
{
1174
    printf("a.out interpreter not yet supported\n");
1175
    return(0);
1176
}
1177