]> git.proxmox.com Git - qemu.git/blob - linux-user/elfload.c
edb3176bcbeaeec6541194af46ace40e541d7552
[qemu.git] / linux-user / elfload.c
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