]> Git Repo - qemu.git/blame - linux-user/elfload.c
loglevel export
[qemu.git] / linux-user / elfload.c
CommitLineData
31e31b8a
FB
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
3ef693a0 13#include "qemu.h"
31e31b8a 14
30ac07d4
FB
15#ifdef TARGET_I386
16
17#define ELF_START_MMAP 0x80000000
18
19typedef uint32_t elf_greg_t;
20
21#define ELF_NGREG (sizeof (struct target_pt_regs) / sizeof(elf_greg_t))
22typedef elf_greg_t elf_gregset_t[ELF_NGREG];
23
24typedef struct user_i387_struct elf_fpregset_t;
25
26/*
27 * This is used to ensure we don't load something for the wrong architecture.
28 */
29#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
30
31/*
32 * These are used to set parameters in the core dumps.
33 */
34#define ELF_CLASS ELFCLASS32
35#define ELF_DATA ELFDATA2LSB
36#define ELF_ARCH EM_386
37
38 /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
39 starts %edx contains a pointer to a function which might be
40 registered using `atexit'. This provides a mean for the
41 dynamic linker to call DT_FINI functions for shared libraries
42 that have been loaded before the code runs.
43
44 A value of 0 tells we have no such handler. */
45#define ELF_PLAT_INIT(_r) _r->edx = 0
46
47#define USE_ELF_CORE_DUMP
48#define ELF_EXEC_PAGESIZE 4096
49
50#endif
51
31e31b8a 52#include "elf.h"
09bfb054
FB
53
54/*
55 * MAX_ARG_PAGES defines the number of pages allocated for arguments
56 * and envelope for the new program. 32 should suffice, this gives
57 * a maximum env+arg of 128kB w/4KB pages!
58 */
59#define MAX_ARG_PAGES 32
60
61/*
62 * This structure is used to hold the arguments that are
63 * used when loading binaries.
64 */
65struct linux_binprm {
66 char buf[128];
67 unsigned long page[MAX_ARG_PAGES];
68 unsigned long p;
69 int sh_bang;
70 int fd;
71 int e_uid, e_gid;
72 int argc, envc;
09bfb054
FB
73 char * filename; /* Name of binary */
74 unsigned long loader, exec;
75 int dont_iput; /* binfmt handler has put inode */
76};
77
78struct exec
79{
80 unsigned int a_info; /* Use macros N_MAGIC, etc for access */
81 unsigned int a_text; /* length of text, in bytes */
82 unsigned int a_data; /* length of data, in bytes */
83 unsigned int a_bss; /* length of uninitialized data area, in bytes */
84 unsigned int a_syms; /* length of symbol table data in file, in bytes */
85 unsigned int a_entry; /* start address */
86 unsigned int a_trsize; /* length of relocation info for text, in bytes */
87 unsigned int a_drsize; /* length of relocation info for data, in bytes */
88};
89
90
91#define N_MAGIC(exec) ((exec).a_info & 0xffff)
92#define OMAGIC 0407
93#define NMAGIC 0410
94#define ZMAGIC 0413
95#define QMAGIC 0314
96
97#define X86_STACK_TOP 0x7d000000
98
99/* max code+data+bss space allocated to elf interpreter */
100#define INTERP_MAP_SIZE (32 * 1024 * 1024)
101
102/* max code+data+bss+brk space allocated to ET_DYN executables */
103#define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
104
105/* from personality.h */
106
107/* Flags for bug emulation. These occupy the top three bytes. */
108#define STICKY_TIMEOUTS 0x4000000
109#define WHOLE_SECONDS 0x2000000
110
111/* Personality types. These go in the low byte. Avoid using the top bit,
112 * it will conflict with error returns.
113 */
114#define PER_MASK (0x00ff)
115#define PER_LINUX (0x0000)
116#define PER_SVR4 (0x0001 | STICKY_TIMEOUTS)
117#define PER_SVR3 (0x0002 | STICKY_TIMEOUTS)
118#define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
119#define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
120#define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
121#define PER_BSD (0x0006)
122#define PER_XENIX (0x0007 | STICKY_TIMEOUTS)
31e31b8a
FB
123
124/* Necessary parameters */
125#define ALPHA_PAGE_SIZE 4096
126#define X86_PAGE_SIZE 4096
127
128#define ALPHA_PAGE_MASK (~(ALPHA_PAGE_SIZE-1))
129#define X86_PAGE_MASK (~(X86_PAGE_SIZE-1))
130
131#define ALPHA_PAGE_ALIGN(addr) ((((addr)+ALPHA_PAGE_SIZE)-1)&ALPHA_PAGE_MASK)
132#define X86_PAGE_ALIGN(addr) ((((addr)+X86_PAGE_SIZE)-1)&X86_PAGE_MASK)
133
134#define NGROUPS 32
135
136#define X86_ELF_EXEC_PAGESIZE X86_PAGE_SIZE
137#define X86_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(X86_ELF_EXEC_PAGESIZE-1))
138#define X86_ELF_PAGEOFFSET(_v) ((_v) & (X86_ELF_EXEC_PAGESIZE-1))
139
140#define ALPHA_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ALPHA_PAGE_SIZE-1))
141#define ALPHA_ELF_PAGEOFFSET(_v) ((_v) & (ALPHA_PAGE_SIZE-1))
142
143#define INTERPRETER_NONE 0
144#define INTERPRETER_AOUT 1
145#define INTERPRETER_ELF 2
146
147#define DLINFO_ITEMS 12
148
09bfb054
FB
149#define put_user(x,ptr) (void)(*(ptr) = (typeof(*ptr))(x))
150#define get_user(ptr) (typeof(*ptr))(*(ptr))
151
152static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
153{
154 memcpy(to, from, n);
155}
d691f669 156
09bfb054
FB
157static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
158{
159 memcpy(to, from, n);
160}
31e31b8a
FB
161
162//extern void * mmap4k();
163#define mmap4k(a, b, c, d, e, f) mmap((void *)(a), b, c, d, e, f)
164
165extern unsigned long x86_stack_size;
166
167static int load_aout_interp(void * exptr, int interp_fd);
168
169#ifdef BSWAP_NEEDED
170static void bswap_ehdr(Elf32_Ehdr *ehdr)
171{
172 bswap16s(&ehdr->e_type); /* Object file type */
173 bswap16s(&ehdr->e_machine); /* Architecture */
174 bswap32s(&ehdr->e_version); /* Object file version */
175 bswap32s(&ehdr->e_entry); /* Entry point virtual address */
176 bswap32s(&ehdr->e_phoff); /* Program header table file offset */
177 bswap32s(&ehdr->e_shoff); /* Section header table file offset */
178 bswap32s(&ehdr->e_flags); /* Processor-specific flags */
179 bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
180 bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
181 bswap16s(&ehdr->e_phnum); /* Program header table entry count */
182 bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
183 bswap16s(&ehdr->e_shnum); /* Section header table entry count */
184 bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
185}
186
187static void bswap_phdr(Elf32_Phdr *phdr)
188{
189 bswap32s(&phdr->p_type); /* Segment type */
190 bswap32s(&phdr->p_offset); /* Segment file offset */
191 bswap32s(&phdr->p_vaddr); /* Segment virtual address */
192 bswap32s(&phdr->p_paddr); /* Segment physical address */
193 bswap32s(&phdr->p_filesz); /* Segment size in file */
194 bswap32s(&phdr->p_memsz); /* Segment size in memory */
195 bswap32s(&phdr->p_flags); /* Segment flags */
196 bswap32s(&phdr->p_align); /* Segment alignment */
197}
198#endif
199
200static void * get_free_page(void)
201{
202 void * retval;
203
204 /* User-space version of kernel get_free_page. Returns a page-aligned
205 * page-sized chunk of memory.
206 */
207 retval = mmap4k(0, ALPHA_PAGE_SIZE, PROT_READ|PROT_WRITE,
208 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
209
210 if((long)retval == -1) {
211 perror("get_free_page");
212 exit(-1);
213 }
214 else {
215 return(retval);
216 }
217}
218
219static void free_page(void * pageaddr)
220{
221 (void)munmap(pageaddr, ALPHA_PAGE_SIZE);
222}
223
224/*
225 * 'copy_string()' copies argument/envelope strings from user
226 * memory to free pages in kernel mem. These are in a format ready
227 * to be put directly into the top of new user memory.
228 *
229 */
230static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
231 unsigned long p)
232{
233 char *tmp, *tmp1, *pag = NULL;
234 int len, offset = 0;
235
236 if (!p) {
237 return 0; /* bullet-proofing */
238 }
239 while (argc-- > 0) {
240 if (!(tmp1 = tmp = get_user(argv+argc))) {
241 fprintf(stderr, "VFS: argc is wrong");
242 exit(-1);
243 }
244 while (get_user(tmp++));
245 len = tmp - tmp1;
246 if (p < len) { /* this shouldn't happen - 128kB */
247 return 0;
248 }
249 while (len) {
250 --p; --tmp; --len;
251 if (--offset < 0) {
252 offset = p % X86_PAGE_SIZE;
253 if (!(pag = (char *) page[p/X86_PAGE_SIZE]) &&
254 !(pag = (char *) page[p/X86_PAGE_SIZE] =
255 (unsigned long *) get_free_page())) {
256 return 0;
257 }
258 }
259 if (len == 0 || offset == 0) {
260 *(pag + offset) = get_user(tmp);
261 }
262 else {
263 int bytes_to_copy = (len > offset) ? offset : len;
264 tmp -= bytes_to_copy;
265 p -= bytes_to_copy;
266 offset -= bytes_to_copy;
267 len -= bytes_to_copy;
268 memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
269 }
270 }
271 }
272 return p;
273}
274
275static int in_group_p(gid_t g)
276{
277 /* return TRUE if we're in the specified group, FALSE otherwise */
278 int ngroup;
279 int i;
280 gid_t grouplist[NGROUPS];
281
282 ngroup = getgroups(NGROUPS, grouplist);
283 for(i = 0; i < ngroup; i++) {
284 if(grouplist[i] == g) {
285 return 1;
286 }
287 }
288 return 0;
289}
290
291static int count(char ** vec)
292{
293 int i;
294
295 for(i = 0; *vec; i++) {
296 vec++;
297 }
298
299 return(i);
300}
301
302static int prepare_binprm(struct linux_binprm *bprm)
303{
304 struct stat st;
305 int mode;
306 int retval, id_change;
307
308 if(fstat(bprm->fd, &st) < 0) {
309 return(-errno);
310 }
311
312 mode = st.st_mode;
313 if(!S_ISREG(mode)) { /* Must be regular file */
314 return(-EACCES);
315 }
316 if(!(mode & 0111)) { /* Must have at least one execute bit set */
317 return(-EACCES);
318 }
319
320 bprm->e_uid = geteuid();
321 bprm->e_gid = getegid();
322 id_change = 0;
323
324 /* Set-uid? */
325 if(mode & S_ISUID) {
326 bprm->e_uid = st.st_uid;
327 if(bprm->e_uid != geteuid()) {
328 id_change = 1;
329 }
330 }
331
332 /* Set-gid? */
333 /*
334 * If setgid is set but no group execute bit then this
335 * is a candidate for mandatory locking, not a setgid
336 * executable.
337 */
338 if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
339 bprm->e_gid = st.st_gid;
340 if (!in_group_p(bprm->e_gid)) {
341 id_change = 1;
342 }
343 }
344
345 memset(bprm->buf, 0, sizeof(bprm->buf));
346 retval = lseek(bprm->fd, 0L, SEEK_SET);
347 if(retval >= 0) {
348 retval = read(bprm->fd, bprm->buf, 128);
349 }
350 if(retval < 0) {
351 perror("prepare_binprm");
352 exit(-1);
353 /* return(-errno); */
354 }
355 else {
356 return(retval);
357 }
358}
359
360unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
361 struct image_info * info)
362{
09bfb054 363 unsigned long stack_base, size, error;
31e31b8a 364 int i;
31e31b8a 365
09bfb054
FB
366 /* Create enough stack to hold everything. If we don't use
367 * it for args, we'll use it for something else...
368 */
369 size = x86_stack_size;
370 if (size < MAX_ARG_PAGES*X86_PAGE_SIZE)
371 size = MAX_ARG_PAGES*X86_PAGE_SIZE;
372 error = (unsigned long)mmap4k(NULL,
373 size + X86_PAGE_SIZE,
374 PROT_READ | PROT_WRITE,
375 MAP_PRIVATE | MAP_ANONYMOUS,
376 -1, 0);
377 if (error == -1) {
378 perror("stk mmap");
379 exit(-1);
380 }
381 /* we reserve one extra page at the top of the stack as guard */
382 mprotect((void *)(error + size), X86_PAGE_SIZE, PROT_NONE);
31e31b8a 383
09bfb054 384 stack_base = error + size - MAX_ARG_PAGES*X86_PAGE_SIZE;
31e31b8a 385 p += stack_base;
09bfb054 386
31e31b8a
FB
387 if (bprm->loader) {
388 bprm->loader += stack_base;
389 }
390 bprm->exec += stack_base;
391
31e31b8a
FB
392 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
393 if (bprm->page[i]) {
394 info->rss++;
395
396 memcpy((void *)stack_base, (void *)bprm->page[i], X86_PAGE_SIZE);
397 free_page((void *)bprm->page[i]);
398 }
399 stack_base += X86_PAGE_SIZE;
400 }
401 return p;
402}
403
404static void set_brk(unsigned long start, unsigned long end)
405{
406 /* page-align the start and end addresses... */
407 start = ALPHA_PAGE_ALIGN(start);
408 end = ALPHA_PAGE_ALIGN(end);
409 if (end <= start)
410 return;
411 if((long)mmap4k(start, end - start,
412 PROT_READ | PROT_WRITE | PROT_EXEC,
413 MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == -1) {
414 perror("cannot mmap brk");
415 exit(-1);
416 }
417}
418
419
420/* We need to explicitly zero any fractional pages
421 after the data section (i.e. bss). This would
422 contain the junk from the file that should not
423 be in memory */
424
425
426static void padzero(unsigned long elf_bss)
427{
428 unsigned long nbyte;
429 char * fpnt;
430
431 nbyte = elf_bss & (ALPHA_PAGE_SIZE-1); /* was X86_PAGE_SIZE - JRP */
432 if (nbyte) {
433 nbyte = ALPHA_PAGE_SIZE - nbyte;
434 fpnt = (char *) elf_bss;
435 do {
436 *fpnt++ = 0;
437 } while (--nbyte);
438 }
439}
440
441static unsigned int * create_elf_tables(char *p, int argc, int envc,
09bfb054
FB
442 struct elfhdr * exec,
443 unsigned long load_addr,
444 unsigned long load_bias,
445 unsigned long interp_load_addr, int ibcs,
446 struct image_info *info)
31e31b8a 447{
b17780d5
FB
448 target_ulong *argv, *envp, *dlinfo;
449 target_ulong *sp;
31e31b8a
FB
450
451 /*
452 * Force 16 byte alignment here for generality.
453 */
454 sp = (unsigned int *) (~15UL & (unsigned long) p);
455 sp -= exec ? DLINFO_ITEMS*2 : 2;
456 dlinfo = sp;
457 sp -= envc+1;
458 envp = sp;
459 sp -= argc+1;
460 argv = sp;
461 if (!ibcs) {
b17780d5
FB
462 put_user(tswapl((target_ulong)envp),--sp);
463 put_user(tswapl((target_ulong)argv),--sp);
31e31b8a 464 }
31e31b8a
FB
465
466#define NEW_AUX_ENT(id, val) \
b17780d5
FB
467 put_user (tswapl(id), dlinfo++); \
468 put_user (tswapl(val), dlinfo++)
31e31b8a
FB
469
470 if (exec) { /* Put this here for an ELF program interpreter */
09bfb054
FB
471 NEW_AUX_ENT (AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
472 NEW_AUX_ENT (AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
473 NEW_AUX_ENT (AT_PHNUM, (target_ulong)(exec->e_phnum));
474 NEW_AUX_ENT (AT_PAGESZ, (target_ulong)(ALPHA_PAGE_SIZE));
475 NEW_AUX_ENT (AT_BASE, (target_ulong)(interp_load_addr));
476 NEW_AUX_ENT (AT_FLAGS, (target_ulong)0);
477 NEW_AUX_ENT (AT_ENTRY, load_bias + exec->e_entry);
478 NEW_AUX_ENT (AT_UID, (target_ulong) getuid());
479 NEW_AUX_ENT (AT_EUID, (target_ulong) geteuid());
480 NEW_AUX_ENT (AT_GID, (target_ulong) getgid());
481 NEW_AUX_ENT (AT_EGID, (target_ulong) getegid());
31e31b8a
FB
482 }
483 NEW_AUX_ENT (AT_NULL, 0);
484#undef NEW_AUX_ENT
b17780d5 485 put_user(tswapl(argc),--sp);
31e31b8a
FB
486 info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
487 while (argc-->0) {
b17780d5 488 put_user(tswapl((target_ulong)p),argv++);
31e31b8a
FB
489 while (get_user(p++)) /* nothing */ ;
490 }
491 put_user(0,argv);
492 info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
31e31b8a 493 while (envc-->0) {
b17780d5 494 put_user(tswapl((target_ulong)p),envp++);
31e31b8a
FB
495 while (get_user(p++)) /* nothing */ ;
496 }
497 put_user(0,envp);
31e31b8a
FB
498 info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
499 return sp;
500}
501
502
503
504static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
505 int interpreter_fd,
506 unsigned long *interp_load_addr)
507{
508 struct elf_phdr *elf_phdata = NULL;
509 struct elf_phdr *eppnt;
09bfb054 510 unsigned long load_addr = 0;
31e31b8a
FB
511 int load_addr_set = 0;
512 int retval;
513 unsigned long last_bss, elf_bss;
514 unsigned long error;
515 int i;
516
517 elf_bss = 0;
518 last_bss = 0;
519 error = 0;
520
644c433c
FB
521#ifdef BSWAP_NEEDED
522 bswap_ehdr(interp_elf_ex);
523#endif
31e31b8a
FB
524 /* First of all, some simple consistency checks */
525 if ((interp_elf_ex->e_type != ET_EXEC &&
09bfb054 526 interp_elf_ex->e_type != ET_DYN) ||
31e31b8a
FB
527 !elf_check_arch(interp_elf_ex->e_machine)) {
528 return ~0UL;
529 }
530
644c433c 531
31e31b8a
FB
532 /* Now read in all of the header information */
533
534 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > X86_PAGE_SIZE)
535 return ~0UL;
536
537 elf_phdata = (struct elf_phdr *)
538 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
539
540 if (!elf_phdata)
541 return ~0UL;
542
543 /*
544 * If the size of this structure has changed, then punt, since
545 * we will be doing the wrong thing.
546 */
09bfb054 547 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
31e31b8a
FB
548 free(elf_phdata);
549 return ~0UL;
09bfb054 550 }
31e31b8a
FB
551
552 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
553 if(retval >= 0) {
554 retval = read(interpreter_fd,
555 (char *) elf_phdata,
556 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
557 }
31e31b8a
FB
558 if (retval < 0) {
559 perror("load_elf_interp");
560 exit(-1);
561 free (elf_phdata);
562 return retval;
563 }
564#ifdef BSWAP_NEEDED
565 eppnt = elf_phdata;
566 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
567 bswap_phdr(eppnt);
568 }
569#endif
09bfb054
FB
570
571 if (interp_elf_ex->e_type == ET_DYN) {
572 /* in order to avoid harcoding the interpreter load
573 address in qemu, we allocate a big enough memory zone */
574 error = (unsigned long)mmap4k(NULL, INTERP_MAP_SIZE,
575 PROT_NONE, MAP_PRIVATE | MAP_ANON,
576 -1, 0);
577 if (error == -1) {
578 perror("mmap");
579 exit(-1);
580 }
581 load_addr = error;
582 load_addr_set = 1;
583 }
584
31e31b8a
FB
585 eppnt = elf_phdata;
586 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
587 if (eppnt->p_type == PT_LOAD) {
588 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
589 int elf_prot = 0;
590 unsigned long vaddr = 0;
591 unsigned long k;
592
593 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
594 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
595 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
596 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
597 elf_type |= MAP_FIXED;
598 vaddr = eppnt->p_vaddr;
599 }
600 error = (unsigned long)mmap4k(load_addr+X86_ELF_PAGESTART(vaddr),
601 eppnt->p_filesz + X86_ELF_PAGEOFFSET(eppnt->p_vaddr),
602 elf_prot,
603 elf_type,
604 interpreter_fd,
605 eppnt->p_offset - X86_ELF_PAGEOFFSET(eppnt->p_vaddr));
606
607 if (error > -1024UL) {
608 /* Real error */
609 close(interpreter_fd);
610 free(elf_phdata);
611 return ~0UL;
612 }
613
614 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
615 load_addr = error;
616 load_addr_set = 1;
617 }
618
619 /*
620 * Find the end of the file mapping for this phdr, and keep
621 * track of the largest address we see for this.
622 */
623 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
624 if (k > elf_bss) elf_bss = k;
625
626 /*
627 * Do the same thing for the memory mapping - between
628 * elf_bss and last_bss is the bss section.
629 */
630 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
631 if (k > last_bss) last_bss = k;
632 }
633
634 /* Now use mmap to map the library into memory. */
635
636 close(interpreter_fd);
637
638 /*
639 * Now fill out the bss section. First pad the last page up
640 * to the page boundary, and then perform a mmap to make sure
641 * that there are zeromapped pages up to and including the last
642 * bss page.
643 */
644 padzero(elf_bss);
645 elf_bss = X86_ELF_PAGESTART(elf_bss + ALPHA_PAGE_SIZE - 1); /* What we have mapped so far */
646
647 /* Map the last of the bss segment */
648 if (last_bss > elf_bss) {
649 mmap4k(elf_bss, last_bss-elf_bss,
650 PROT_READ|PROT_WRITE|PROT_EXEC,
651 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
652 }
653 free(elf_phdata);
654
655 *interp_load_addr = load_addr;
656 return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
657}
658
659
660
b17780d5
FB
661static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
662 struct image_info * info)
31e31b8a
FB
663{
664 struct elfhdr elf_ex;
665 struct elfhdr interp_elf_ex;
666 struct exec interp_ex;
667 int interpreter_fd = -1; /* avoid warning */
09bfb054 668 unsigned long load_addr, load_bias;
31e31b8a
FB
669 int load_addr_set = 0;
670 unsigned int interpreter_type = INTERPRETER_NONE;
671 unsigned char ibcs2_interpreter;
672 int i;
673 void * mapped_addr;
674 struct elf_phdr * elf_ppnt;
675 struct elf_phdr *elf_phdata;
676 unsigned long elf_bss, k, elf_brk;
677 int retval;
678 char * elf_interpreter;
679 unsigned long elf_entry, interp_load_addr = 0;
680 int status;
681 unsigned long start_code, end_code, end_data;
682 unsigned long elf_stack;
683 char passed_fileno[6];
684
685 ibcs2_interpreter = 0;
686 status = 0;
687 load_addr = 0;
09bfb054 688 load_bias = 0;
31e31b8a
FB
689 elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
690#ifdef BSWAP_NEEDED
691 bswap_ehdr(&elf_ex);
692#endif
693
694 if (elf_ex.e_ident[0] != 0x7f ||
695 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
696 return -ENOEXEC;
697 }
698
31e31b8a
FB
699 /* First of all, some simple consistency checks */
700 if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
701 (! elf_check_arch(elf_ex.e_machine))) {
702 return -ENOEXEC;
703 }
704
705 /* Now read in all of the header information */
706
707 elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
708 if (elf_phdata == NULL) {
709 return -ENOMEM;
710 }
711
712 retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
713 if(retval > 0) {
714 retval = read(bprm->fd, (char *) elf_phdata,
715 elf_ex.e_phentsize * elf_ex.e_phnum);
716 }
717
718 if (retval < 0) {
719 perror("load_elf_binary");
720 exit(-1);
721 free (elf_phdata);
722 return -errno;
723 }
724
b17780d5
FB
725#ifdef BSWAP_NEEDED
726 elf_ppnt = elf_phdata;
727 for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
728 bswap_phdr(elf_ppnt);
729 }
730#endif
31e31b8a
FB
731 elf_ppnt = elf_phdata;
732
733 elf_bss = 0;
734 elf_brk = 0;
735
736
737 elf_stack = ~0UL;
738 elf_interpreter = NULL;
739 start_code = ~0UL;
740 end_code = 0;
741 end_data = 0;
742
743 for(i=0;i < elf_ex.e_phnum; i++) {
744 if (elf_ppnt->p_type == PT_INTERP) {
745 if ( elf_interpreter != NULL )
746 {
747 free (elf_phdata);
748 free(elf_interpreter);
749 close(bprm->fd);
750 return -EINVAL;
751 }
752
753 /* This is the program interpreter used for
754 * shared libraries - for now assume that this
755 * is an a.out format binary
756 */
757
32ce6337 758 elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
31e31b8a
FB
759
760 if (elf_interpreter == NULL) {
761 free (elf_phdata);
762 close(bprm->fd);
763 return -ENOMEM;
764 }
765
31e31b8a
FB
766 retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET);
767 if(retval >= 0) {
32ce6337 768 retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz);
31e31b8a
FB
769 }
770 if(retval < 0) {
771 perror("load_elf_binary2");
772 exit(-1);
773 }
774
775 /* If the program interpreter is one of these two,
776 then assume an iBCS2 image. Otherwise assume
777 a native linux image. */
778
779 /* JRP - Need to add X86 lib dir stuff here... */
780
781 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
782 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
783 ibcs2_interpreter = 1;
784 }
785
786#if 0
787 printf("Using ELF interpreter %s\n", elf_interpreter);
788#endif
789 if (retval >= 0) {
32ce6337 790 retval = open(path(elf_interpreter), O_RDONLY);
31e31b8a
FB
791 if(retval >= 0) {
792 interpreter_fd = retval;
793 }
794 else {
795 perror(elf_interpreter);
796 exit(-1);
797 /* retval = -errno; */
798 }
799 }
800
801 if (retval >= 0) {
802 retval = lseek(interpreter_fd, 0, SEEK_SET);
803 if(retval >= 0) {
804 retval = read(interpreter_fd,bprm->buf,128);
805 }
806 }
807 if (retval >= 0) {
808 interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */
809 interp_elf_ex=*((struct elfhdr *) bprm->buf); /* elf exec-header */
810 }
811 if (retval < 0) {
812 perror("load_elf_binary3");
813 exit(-1);
814 free (elf_phdata);
815 free(elf_interpreter);
816 close(bprm->fd);
817 return retval;
818 }
819 }
820 elf_ppnt++;
821 }
822
823 /* Some simple consistency checks for the interpreter */
824 if (elf_interpreter){
825 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
826
827 /* Now figure out which format our binary is */
828 if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) &&
829 (N_MAGIC(interp_ex) != QMAGIC)) {
830 interpreter_type = INTERPRETER_ELF;
831 }
832
833 if (interp_elf_ex.e_ident[0] != 0x7f ||
834 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0) {
835 interpreter_type &= ~INTERPRETER_ELF;
836 }
837
838 if (!interpreter_type) {
839 free(elf_interpreter);
840 free(elf_phdata);
841 close(bprm->fd);
842 return -ELIBBAD;
843 }
844 }
845
846 /* OK, we are done with that, now set up the arg stuff,
847 and then start this sucker up */
848
849 if (!bprm->sh_bang) {
850 char * passed_p;
851
852 if (interpreter_type == INTERPRETER_AOUT) {
853 sprintf(passed_fileno, "%d", bprm->fd);
854 passed_p = passed_fileno;
855
856 if (elf_interpreter) {
857 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p);
858 bprm->argc++;
859 }
860 }
861 if (!bprm->p) {
862 if (elf_interpreter) {
863 free(elf_interpreter);
864 }
865 free (elf_phdata);
866 close(bprm->fd);
867 return -E2BIG;
868 }
869 }
870
871 /* OK, This is the point of no return */
872 info->end_data = 0;
873 info->end_code = 0;
874 info->start_mmap = (unsigned long)ELF_START_MMAP;
875 info->mmap = 0;
876 elf_entry = (unsigned long) elf_ex.e_entry;
877
878 /* Do this so that we can load the interpreter, if need be. We will
879 change some of these later */
880 info->rss = 0;
881 bprm->p = setup_arg_pages(bprm->p, bprm, info);
882 info->start_stack = bprm->p;
883
884 /* Now we do a little grungy work by mmaping the ELF image into
885 * the correct location in memory. At this point, we assume that
886 * the image should be loaded at fixed address, not at a variable
887 * address.
888 */
889
31e31b8a 890 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
09bfb054
FB
891 int elf_prot = 0;
892 int elf_flags = 0;
893 unsigned long error;
894
895 if (elf_ppnt->p_type != PT_LOAD)
896 continue;
897
898 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
899 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
900 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
901 elf_flags = MAP_PRIVATE | MAP_DENYWRITE;
902 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
903 elf_flags |= MAP_FIXED;
904 } else if (elf_ex.e_type == ET_DYN) {
905 /* Try and get dynamic programs out of the way of the default mmap
906 base, as well as whatever program they might try to exec. This
907 is because the brk will follow the loader, and is not movable. */
908 /* NOTE: for qemu, we do a big mmap to get enough space
909 without harcoding any address */
910 error = (unsigned long)mmap4k(NULL, ET_DYN_MAP_SIZE,
911 PROT_NONE, MAP_PRIVATE | MAP_ANON,
912 -1, 0);
913 if (error == -1) {
914 perror("mmap");
915 exit(-1);
916 }
917 load_bias = X86_ELF_PAGESTART(error - elf_ppnt->p_vaddr);
918 }
919
920 error = (unsigned long)mmap4k(
921 X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
922 (elf_ppnt->p_filesz +
923 X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
924 elf_prot,
925 (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
926 bprm->fd,
927 (elf_ppnt->p_offset -
928 X86_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
929 if (error == -1) {
930 perror("mmap");
931 exit(-1);
932 }
31e31b8a
FB
933
934#ifdef LOW_ELF_STACK
09bfb054
FB
935 if (X86_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
936 elf_stack = X86_ELF_PAGESTART(elf_ppnt->p_vaddr);
31e31b8a 937#endif
09bfb054
FB
938
939 if (!load_addr_set) {
940 load_addr_set = 1;
941 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
942 if (elf_ex.e_type == ET_DYN) {
943 load_bias += error -
944 X86_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr);
945 load_addr += load_bias;
946 }
947 }
948 k = elf_ppnt->p_vaddr;
949 if (k < start_code)
950 start_code = k;
951 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
952 if (k > elf_bss)
953 elf_bss = k;
954 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
955 end_code = k;
956 if (end_data < k)
957 end_data = k;
958 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
959 if (k > elf_brk) elf_brk = k;
31e31b8a
FB
960 }
961
09bfb054
FB
962 elf_entry += load_bias;
963 elf_bss += load_bias;
964 elf_brk += load_bias;
965 start_code += load_bias;
966 end_code += load_bias;
967 // start_data += load_bias;
968 end_data += load_bias;
969
31e31b8a
FB
970 if (elf_interpreter) {
971 if (interpreter_type & 1) {
972 elf_entry = load_aout_interp(&interp_ex, interpreter_fd);
973 }
974 else if (interpreter_type & 2) {
975 elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd,
976 &interp_load_addr);
977 }
978
979 close(interpreter_fd);
980 free(elf_interpreter);
981
982 if (elf_entry == ~0UL) {
983 printf("Unable to load interpreter\n");
984 free(elf_phdata);
985 exit(-1);
986 return 0;
987 }
988 }
989
990 free(elf_phdata);
991
992 if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd);
993 info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
994
995#ifdef LOW_ELF_STACK
996 info->start_stack = bprm->p = elf_stack - 4;
997#endif
998 bprm->p = (unsigned long)
999 create_elf_tables((char *)bprm->p,
1000 bprm->argc,
1001 bprm->envc,
1002 (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
09bfb054 1003 load_addr, load_bias,
31e31b8a
FB
1004 interp_load_addr,
1005 (interpreter_type == INTERPRETER_AOUT ? 0 : 1),
1006 info);
1007 if (interpreter_type == INTERPRETER_AOUT)
1008 info->arg_start += strlen(passed_fileno) + 1;
1009 info->start_brk = info->brk = elf_brk;
1010 info->end_code = end_code;
1011 info->start_code = start_code;
1012 info->end_data = end_data;
1013 info->start_stack = bprm->p;
1014
1015 /* Calling set_brk effectively mmaps the pages that we need for the bss and break
1016 sections */
1017 set_brk(elf_bss, elf_brk);
1018
1019 padzero(elf_bss);
1020
1021#if 0
1022 printf("(start_brk) %x\n" , info->start_brk);
1023 printf("(end_code) %x\n" , info->end_code);
1024 printf("(start_code) %x\n" , info->start_code);
1025 printf("(end_data) %x\n" , info->end_data);
1026 printf("(start_stack) %x\n" , info->start_stack);
1027 printf("(brk) %x\n" , info->brk);
1028#endif
1029
1030 if ( info->personality == PER_SVR4 )
1031 {
1032 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
1033 and some applications "depend" upon this behavior.
1034 Since we do not have the power to recompile these, we
1035 emulate the SVr4 behavior. Sigh. */
1036 mapped_addr = mmap4k(NULL, ALPHA_PAGE_SIZE, PROT_READ | PROT_EXEC,
1037 MAP_FIXED | MAP_PRIVATE, -1, 0);
1038 }
1039
1040#ifdef ELF_PLAT_INIT
1041 /*
1042 * The ABI may specify that certain registers be set up in special
1043 * ways (on i386 %edx is the address of a DT_FINI function, for
1044 * example. This macro performs whatever initialization to
1045 * the regs structure is required.
1046 */
1047 ELF_PLAT_INIT(regs);
1048#endif
1049
1050
1051 info->entry = elf_entry;
1052
1053 return 0;
1054}
1055
1056
1057
32ce6337 1058int elf_exec(const char * filename, char ** argv, char ** envp,
b17780d5 1059 struct target_pt_regs * regs, struct image_info *infop)
31e31b8a
FB
1060{
1061 struct linux_binprm bprm;
1062 int retval;
1063 int i;
1064
1065 bprm.p = X86_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
1066 for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
1067 bprm.page[i] = 0;
1068 retval = open(filename, O_RDONLY);
1069 if (retval == -1) {
1070 perror(filename);
1071 exit(-1);
1072 /* return retval; */
1073 }
1074 else {
1075 bprm.fd = retval;
1076 }
1077 bprm.filename = (char *)filename;
1078 bprm.sh_bang = 0;
1079 bprm.loader = 0;
1080 bprm.exec = 0;
1081 bprm.dont_iput = 0;
1082 bprm.argc = count(argv);
1083 bprm.envc = count(envp);
1084
1085 retval = prepare_binprm(&bprm);
1086
1087 if(retval>=0) {
1088 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p);
1089 bprm.exec = bprm.p;
1090 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p);
1091 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p);
1092 if (!bprm.p) {
1093 retval = -E2BIG;
1094 }
1095 }
1096
1097 if(retval>=0) {
1098 retval = load_elf_binary(&bprm,regs,infop);
1099 }
1100 if(retval>=0) {
1101 /* success. Initialize important registers */
1102 regs->esp = infop->start_stack;
1103 regs->eip = infop->entry;
1104 return retval;
1105 }
1106
1107 /* Something went wrong, return the inode and free the argument pages*/
1108 for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1109 free_page((void *)bprm.page[i]);
1110 }
1111 return(retval);
1112}
1113
1114
1115static int load_aout_interp(void * exptr, int interp_fd)
1116{
1117 printf("a.out interpreter not yet supported\n");
1118 return(0);
1119}
1120
This page took 0.142073 seconds and 4 git commands to generate.