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