1 /* $OpenBSD: file.c,v 1.15 2013/10/17 08:02:21 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1995-96 Mats O Jansson. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "os.h" 28 #include "common.h" 29 #include "file.h" 30 #include "mopdef.h" 31 #include <stddef.h> 32 33 #ifndef NOAOUT 34 #if defined(__OpenBSD__) 35 #include <sys/exec.h> 36 #endif 37 #if defined(__bsdi__) 38 #define NOAOUT 39 #endif 40 #if defined(__FreeBSD__) 41 #include <sys/imgact_aout.h> 42 #endif 43 #if !defined(MID_I386) 44 #define MID_I386 134 45 #endif 46 #if !defined(MID_SPARC) 47 #define MID_SPARC 138 48 #endif 49 #if !defined(MID_VAX) 50 #define MID_VAX 140 51 #endif 52 #endif 53 54 #ifndef NOELF 55 #if defined(__OpenBSD__) 56 #include <sys/exec_elf.h> 57 #else 58 #define NOELF 59 #endif 60 #endif 61 62 #ifndef NOAOUT 63 static int getCLBYTES(int); 64 static int getMID(int, int); 65 #endif 66 67 const char * 68 FileTypeName(mopd_imagetype type) 69 { 70 71 switch (type) { 72 case IMAGE_TYPE_MOP: 73 return ("MOP"); 74 75 case IMAGE_TYPE_ELF32: 76 return ("Elf32"); 77 78 case IMAGE_TYPE_AOUT: 79 return ("a.out"); 80 } 81 82 abort(); 83 } 84 85 void 86 mopFilePutLX(u_char *buf, int idx, u_int32_t value, int cnt) 87 { 88 int i; 89 for (i = 0; i < cnt; i++) { 90 buf[idx+i] = value % 256; 91 value = value / 256; 92 } 93 } 94 95 void 96 mopFilePutBX(u_char *buf, int idx, u_int32_t value, int cnt) 97 { 98 int i; 99 for (i = 0; i < cnt; i++) { 100 buf[idx+cnt-1-i] = value % 256; 101 value = value / 256; 102 } 103 } 104 105 u_int32_t 106 mopFileGetLX(u_char *buf, int idx, int cnt) 107 { 108 u_int32_t ret = 0; 109 int i; 110 111 for (i = 0; i < cnt; i++) { 112 int j = idx + cnt - 1 - i; 113 if (j < 0) 114 abort(); 115 ret = ret * 256 + buf[j]; 116 } 117 118 return(ret); 119 } 120 121 u_int32_t 122 mopFileGetBX(u_char *buf, int idx, int cnt) 123 { 124 u_int32_t ret = 0; 125 int i; 126 127 for (i = 0; i < cnt; i++) { 128 int j = idx + i; 129 if (j < 0) 130 abort(); 131 ret = ret * 256 + buf[j]; 132 } 133 134 return(ret); 135 } 136 137 void 138 mopFileSwapX(u_char *buf, int idx, int cnt) 139 { 140 int i; 141 u_char c; 142 143 for (i = 0; i < (cnt / 2); i++) { 144 c = buf[idx+i]; 145 buf[idx+i] = buf[idx+cnt-1-i]; 146 buf[idx+cnt-1-i] = c; 147 } 148 149 } 150 151 int 152 CheckMopFile(int fd) 153 { 154 u_char header[512]; 155 short image_type; 156 157 if (read(fd, header, 512) != 512) 158 return(-1); 159 160 (void)lseek(fd, (off_t) 0, SEEK_SET); 161 162 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + 163 header[IHD_W_ALIAS]); 164 165 switch(image_type) { 166 case IHD_C_NATIVE: /* Native mode image (VAX) */ 167 case IHD_C_RSX: /* RSX image produced by TKB */ 168 case IHD_C_BPA: /* BASIC plus analog */ 169 case IHD_C_ALIAS: /* Alias */ 170 case IHD_C_CLI: /* Image is CLI */ 171 case IHD_C_PMAX: /* PMAX system image */ 172 case IHD_C_ALPHA: /* ALPHA system image */ 173 break; 174 default: 175 return(-1); 176 } 177 178 return(0); 179 } 180 181 int 182 GetMopFileInfo(struct dllist *dl, int info) 183 { 184 u_char header[512]; 185 short image_type; 186 u_int32_t load_addr, xfr_addr, isd, iha, hbcnt, isize; 187 188 if (read(dl->ldfd, header, 512) != 512) 189 return(-1); 190 191 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + 192 header[IHD_W_ALIAS]); 193 194 switch(image_type) { 195 case IHD_C_NATIVE: /* Native mode image (VAX) */ 196 isd = (header[IHD_W_SIZE+1]*256 + 197 header[IHD_W_SIZE]); 198 iha = (header[IHD_W_ACTIVOFF+1]*256 + 199 header[IHD_W_ACTIVOFF]); 200 hbcnt = (header[IHD_B_HDRBLKCNT]); 201 isize = (header[isd+ISD_W_PAGCNT+1]*256 + 202 header[isd+ISD_W_PAGCNT]) * 512; 203 load_addr = ((header[isd+ISD_V_VPN+1]*256 + 204 header[isd+ISD_V_VPN]) & ISD_M_VPN) 205 * 512; 206 xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + 207 header[iha+IHA_L_TFRADR1+2]*0x10000 + 208 header[iha+IHA_L_TFRADR1+1]*0x100 + 209 header[iha+IHA_L_TFRADR1]) & 0x7fffffff; 210 if (info == INFO_PRINT) { 211 printf("Native Image (VAX)\n"); 212 printf("Header Block Count: %d\n",hbcnt); 213 printf("Image Size: %08x\n",isize); 214 printf("Load Address: %08x\n",load_addr); 215 printf("Transfer Address: %08x\n",xfr_addr); 216 } 217 break; 218 case IHD_C_RSX: /* RSX image produced by TKB */ 219 hbcnt = header[L_BBLK+1]*256 + header[L_BBLK]; 220 isize = (header[L_BLDZ+1]*256 + header[L_BLDZ]) * 64; 221 load_addr = header[L_BSA+1]*256 + header[L_BSA]; 222 xfr_addr = header[L_BXFR+1]*256 + header[L_BXFR]; 223 if (info == INFO_PRINT) { 224 printf("RSX Image\n"); 225 printf("Header Block Count: %d\n",hbcnt); 226 printf("Image Size: %08x\n",isize); 227 printf("Load Address: %08x\n",load_addr); 228 printf("Transfer Address: %08x\n",xfr_addr); 229 } 230 break; 231 case IHD_C_BPA: /* BASIC plus analog */ 232 if (info == INFO_PRINT) { 233 printf("BASIC-Plus Image, not supported\n"); 234 } 235 return(-1); 236 break; 237 case IHD_C_ALIAS: /* Alias */ 238 if (info == INFO_PRINT) { 239 printf("Alias, not supported\n"); 240 } 241 return(-1); 242 break; 243 case IHD_C_CLI: /* Image is CLI */ 244 if (info == INFO_PRINT) { 245 printf("CLI, not supported\n"); 246 } 247 return(-1); 248 break; 249 case IHD_C_PMAX: /* PMAX system image */ 250 isd = (header[IHD_W_SIZE+1]*256 + 251 header[IHD_W_SIZE]); 252 iha = (header[IHD_W_ACTIVOFF+1]*256 + 253 header[IHD_W_ACTIVOFF]); 254 hbcnt = (header[IHD_B_HDRBLKCNT]); 255 isize = (header[isd+ISD_W_PAGCNT+1]*256 + 256 header[isd+ISD_W_PAGCNT]) * 512; 257 load_addr = (header[isd+ISD_V_VPN+1]*256 + 258 header[isd+ISD_V_VPN]) * 512; 259 xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + 260 header[iha+IHA_L_TFRADR1+2]*0x10000 + 261 header[iha+IHA_L_TFRADR1+1]*0x100 + 262 header[iha+IHA_L_TFRADR1]); 263 if (info == INFO_PRINT) { 264 printf("PMAX Image \n"); 265 printf("Header Block Count: %d\n",hbcnt); 266 printf("Image Size: %08x\n",isize); 267 printf("Load Address: %08x\n",load_addr); 268 printf("Transfer Address: %08x\n",xfr_addr); 269 } 270 break; 271 case IHD_C_ALPHA: /* ALPHA system image */ 272 isd = (header[EIHD_L_ISDOFF+3]*0x1000000 + 273 header[EIHD_L_ISDOFF+2]*0x10000 + 274 header[EIHD_L_ISDOFF+1]*0x100 + 275 header[EIHD_L_ISDOFF]); 276 hbcnt = (header[EIHD_L_HDRBLKCNT+3]*0x1000000 + 277 header[EIHD_L_HDRBLKCNT+2]*0x10000 + 278 header[EIHD_L_HDRBLKCNT+1]*0x100 + 279 header[EIHD_L_HDRBLKCNT]); 280 isize = (header[isd+EISD_L_SECSIZE+3]*0x1000000 + 281 header[isd+EISD_L_SECSIZE+2]*0x10000 + 282 header[isd+EISD_L_SECSIZE+1]*0x100 + 283 header[isd+EISD_L_SECSIZE]); 284 load_addr = 0; 285 xfr_addr = 0; 286 if (info == INFO_PRINT) { 287 printf("Alpha Image \n"); 288 printf("Header Block Count: %d\n",hbcnt); 289 printf("Image Size: %08x\n",isize); 290 printf("Load Address: %08x\n",load_addr); 291 printf("Transfer Address: %08x\n",xfr_addr); 292 } 293 break; 294 default: 295 if (info == INFO_PRINT) { 296 printf("Unknown Image (%d)\n",image_type); 297 } 298 return(-1); 299 } 300 301 dl->image_type = IMAGE_TYPE_MOP; 302 dl->loadaddr = load_addr; 303 dl->xferaddr = xfr_addr; 304 305 return(0); 306 } 307 308 #ifndef NOAOUT 309 static int 310 getMID(int old_mid, int new_mid) 311 { 312 int mid; 313 314 mid = old_mid; 315 316 switch (new_mid) { 317 case MID_I386: 318 mid = MID_I386; 319 break; 320 #ifdef MID_M68K 321 case MID_M68K: 322 mid = MID_M68K; 323 break; 324 #endif 325 #ifdef MID_M68K4K 326 case MID_M68K4K: 327 mid = MID_M68K4K; 328 break; 329 #endif 330 #ifdef MID_NS32532 331 case MID_NS32532: 332 mid = MID_NS32532; 333 break; 334 #endif 335 case MID_SPARC: 336 mid = MID_SPARC; 337 break; 338 #ifdef MID_PMAX 339 case MID_PMAX: 340 mid = MID_PMAX; 341 break; 342 #endif 343 #ifdef MID_VAX 344 case MID_VAX: 345 mid = MID_VAX; 346 break; 347 #endif 348 #ifdef MID_ALPHA 349 case MID_ALPHA: 350 mid = MID_ALPHA; 351 break; 352 #endif 353 #ifdef MID_MIPS 354 case MID_MIPS: 355 mid = MID_MIPS; 356 break; 357 #endif 358 #ifdef MID_ARM6 359 case MID_ARM6: 360 mid = MID_ARM6; 361 break; 362 #endif 363 default: 364 break; 365 } 366 367 return(mid); 368 } 369 370 static int 371 getCLBYTES(int mid) 372 { 373 int clbytes; 374 375 switch (mid) { 376 #ifdef MID_VAX 377 case MID_VAX: 378 clbytes = 1024; 379 break; 380 #endif 381 #ifdef MID_I386 382 case MID_I386: 383 #endif 384 #ifdef MID_M68K4K 385 case MID_M68K4K: 386 #endif 387 #ifdef MID_NS32532 388 case MID_NS32532: 389 #endif 390 #ifdef MID_PMAX 391 case MID_PMAX: 392 #endif 393 #ifdef MID_MIPS 394 case MID_MIPS: 395 #endif 396 #ifdef MID_ARM6 397 case MID_ARM6: 398 #endif 399 #if defined(MID_I386) || defined(MID_M68K4K) || defined(MID_NS32532) || \ 400 defined(MID_PMAX) || defined(MID_MIPS) || defined(MID_ARM6) 401 clbytes = 4096; 402 break; 403 #endif 404 #ifdef MID_M68K 405 case MID_M68K: 406 #endif 407 #ifdef MID_ALPHA 408 case MID_ALPHA: 409 #endif 410 #ifdef MID_SPARC 411 case MID_SPARC: 412 #endif 413 #if defined(MID_M68K) || defined(MID_ALPHA) || defined(MID_SPARC) 414 clbytes = 8192; 415 break; 416 #endif 417 default: 418 clbytes = 0; 419 } 420 421 return(clbytes); 422 } 423 #endif 424 425 int 426 CheckElfFile(int fd) 427 { 428 #ifdef NOELF 429 return(-1); 430 #else 431 Elf32_Ehdr ehdr; 432 433 (void)lseek(fd, (off_t) 0, SEEK_SET); 434 435 if (read(fd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr)) 436 return(-1); 437 438 if (ehdr.e_ident[0] != ELFMAG0 || 439 ehdr.e_ident[1] != ELFMAG1 || 440 ehdr.e_ident[2] != ELFMAG2 || 441 ehdr.e_ident[3] != ELFMAG3) 442 return(-1); 443 444 /* Must be Elf32... */ 445 if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) 446 return(-1); 447 448 return(0); 449 #endif /* NOELF */ 450 } 451 452 int 453 GetElfFileInfo(struct dllist *dl, int info) 454 { 455 #ifdef NOELF 456 return(-1); 457 #else 458 Elf32_Ehdr ehdr; 459 Elf32_Phdr phdr; 460 uint32_t e_machine, e_entry; 461 uint32_t e_phoff, e_phentsize, e_phnum; 462 int ei_data, i; 463 464 (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET); 465 466 if (read(dl->ldfd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr)) 467 return(-1); 468 469 if (ehdr.e_ident[0] != ELFMAG0 || 470 ehdr.e_ident[1] != ELFMAG1 || 471 ehdr.e_ident[2] != ELFMAG2 || 472 ehdr.e_ident[3] != ELFMAG3) 473 return(-1); 474 475 /* Must be Elf32... */ 476 if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) 477 return(-1); 478 479 ei_data = ehdr.e_ident[EI_DATA]; 480 481 switch (ei_data) { 482 case ELFDATA2LSB: 483 e_machine = mopFileGetLX((u_char *) &ehdr, 484 offsetof(Elf32_Ehdr, e_machine), 485 sizeof(ehdr.e_machine)); 486 e_entry = mopFileGetLX((u_char *) &ehdr, 487 offsetof(Elf32_Ehdr, e_entry), 488 sizeof(ehdr.e_entry)); 489 490 e_phoff = mopFileGetLX((u_char *) &ehdr, 491 offsetof(Elf32_Ehdr, e_phoff), 492 sizeof(ehdr.e_phoff)); 493 e_phentsize = mopFileGetLX((u_char *) &ehdr, 494 offsetof(Elf32_Ehdr, e_phentsize), 495 sizeof(ehdr.e_phentsize)); 496 e_phnum = mopFileGetLX((u_char *) &ehdr, 497 offsetof(Elf32_Ehdr, e_phnum), 498 sizeof(ehdr.e_phnum)); 499 break; 500 501 case ELFDATA2MSB: 502 e_machine = mopFileGetBX((u_char *) &ehdr, 503 offsetof(Elf32_Ehdr, e_machine), 504 sizeof(ehdr.e_machine)); 505 e_entry = mopFileGetBX((u_char *) &ehdr, 506 offsetof(Elf32_Ehdr, e_entry), 507 sizeof(ehdr.e_entry)); 508 509 e_phoff = mopFileGetBX((u_char *) &ehdr, 510 offsetof(Elf32_Ehdr, e_phoff), 511 sizeof(ehdr.e_phoff)); 512 e_phentsize = mopFileGetBX((u_char *) &ehdr, 513 offsetof(Elf32_Ehdr, e_phentsize), 514 sizeof(ehdr.e_phentsize)); 515 e_phnum = mopFileGetBX((u_char *) &ehdr, 516 offsetof(Elf32_Ehdr, e_phnum), 517 sizeof(ehdr.e_phnum)); 518 break; 519 520 default: 521 return(-1); 522 } 523 524 if (e_phnum > SEC_MAX) 525 return(-1); 526 dl->e_nsec = e_phnum; 527 for (i = 0; i < dl->e_nsec; i++) { 528 if (lseek(dl->ldfd, (off_t) e_phoff + (i * e_phentsize), 529 SEEK_SET) == (off_t) -1) 530 return(-1); 531 if (read(dl->ldfd, (char *) &phdr, sizeof(phdr)) != 532 sizeof(phdr)) 533 return(-1); 534 535 switch (ei_data) { 536 case ELFDATA2LSB: 537 dl->e_sections[i].s_foff = 538 mopFileGetLX((u_char *) &phdr, 539 offsetof(Elf32_Phdr, p_offset), 540 sizeof(phdr.p_offset)); 541 dl->e_sections[i].s_vaddr = 542 mopFileGetLX((u_char *) &phdr, 543 offsetof(Elf32_Phdr, p_vaddr), 544 sizeof(phdr.p_vaddr)); 545 dl->e_sections[i].s_fsize = 546 mopFileGetLX((u_char *) &phdr, 547 offsetof(Elf32_Phdr, p_filesz), 548 sizeof(phdr.p_filesz)); 549 dl->e_sections[i].s_msize = 550 mopFileGetLX((u_char *) &phdr, 551 offsetof(Elf32_Phdr, p_memsz), 552 sizeof(phdr.p_memsz)); 553 break; 554 555 case ELFDATA2MSB: 556 dl->e_sections[i].s_foff = 557 mopFileGetBX((u_char *) &phdr, 558 offsetof(Elf32_Phdr, p_offset), 559 sizeof(phdr.p_offset)); 560 dl->e_sections[i].s_vaddr = 561 mopFileGetBX((u_char *) &phdr, 562 offsetof(Elf32_Phdr, p_vaddr), 563 sizeof(phdr.p_vaddr)); 564 dl->e_sections[i].s_fsize = 565 mopFileGetBX((u_char *) &phdr, 566 offsetof(Elf32_Phdr, p_filesz), 567 sizeof(phdr.p_filesz)); 568 dl->e_sections[i].s_msize = 569 mopFileGetBX((u_char *) &phdr, 570 offsetof(Elf32_Phdr, p_memsz), 571 sizeof(phdr.p_memsz)); 572 break; 573 574 default: 575 return(-1); 576 } 577 } 578 /* 579 * In addition to padding between segments, this also 580 * takes care of memsz > filesz. 581 */ 582 for (i = 0; i < dl->e_nsec - 1; i++) { 583 dl->e_sections[i].s_pad = 584 dl->e_sections[i + 1].s_vaddr - 585 (dl->e_sections[i].s_vaddr + dl->e_sections[i].s_fsize); 586 } 587 dl->e_sections[dl->e_nsec - 1].s_pad = 588 dl->e_sections[dl->e_nsec - 1].s_msize - 589 dl->e_sections[dl->e_nsec - 1].s_fsize; 590 /* 591 * Now compute the logical offsets for each section. 592 */ 593 dl->e_sections[0].s_loff = 0; 594 for (i = 1; i < dl->e_nsec; i++) { 595 dl->e_sections[i].s_loff = 596 dl->e_sections[i - 1].s_loff + 597 dl->e_sections[i - 1].s_fsize + 598 dl->e_sections[i - 1].s_pad; 599 } 600 601 dl->image_type = IMAGE_TYPE_ELF32; 602 dl->loadaddr = 0; 603 #if 0 604 dl->xferaddr = e_entry; /* will relocate itself if necessary */ 605 #else 606 dl->xferaddr = e_entry - dl->e_sections[0].s_vaddr; 607 #endif 608 609 /* Print info about the image. */ 610 if (info == INFO_PRINT) { 611 printf("Elf32 image ("); 612 switch (e_machine) { 613 #ifdef EM_VAX 614 case EM_VAX: 615 printf("VAX"); 616 break; 617 #endif 618 default: 619 printf("machine %d", e_machine); 620 break; 621 } 622 printf(")\n"); 623 printf("Transfer Address: %08x\n", dl->xferaddr); 624 printf("Program Sections: %d\n", dl->e_nsec); 625 for (i = 0; i < dl->e_nsec; i++) { 626 printf(" S%d File Size: %08x\n", i, 627 dl->e_sections[i].s_fsize); 628 printf(" S%d Pad Size: %08x\n", i, 629 dl->e_sections[i].s_pad); 630 } 631 } 632 633 dl->e_machine = e_machine; 634 635 dl->e_curpos = 0; 636 dl->e_cursec = 0; 637 638 return(0); 639 #endif /* NOELF */ 640 } 641 642 int 643 CheckAOutFile(int fd) 644 { 645 #ifdef NOAOUT 646 return(-1); 647 #else 648 struct exec ex, ex_swap; 649 int mid = -1; 650 651 if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex)) 652 return(-1); 653 654 (void)lseek(fd, (off_t) 0, SEEK_SET); 655 656 if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap)) 657 return(-1); 658 659 (void)lseek(fd, (off_t) 0, SEEK_SET); 660 661 mid = getMID(mid, N_GETMID (ex)); 662 663 if (mid == -1) { 664 mid = getMID(mid, N_GETMID (ex_swap)); 665 } 666 667 if (mid != -1) { 668 return(0); 669 } else { 670 return(-1); 671 } 672 #endif /* NOAOUT */ 673 } 674 675 int 676 GetAOutFileInfo(struct dllist *dl, int info) 677 { 678 #ifdef NOAOUT 679 return(-1); 680 #else 681 struct exec ex, ex_swap; 682 u_int32_t mid = -1; 683 u_int32_t magic, clbytes, clofset; 684 685 if (read(dl->ldfd, (char *)&ex, sizeof(ex)) != sizeof(ex)) 686 return(-1); 687 688 (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET); 689 690 if (read(dl->ldfd, (char *)&ex_swap, 691 sizeof(ex_swap)) != sizeof(ex_swap)) 692 return(-1); 693 694 mopFileSwapX((u_char *)&ex_swap, 0, 4); 695 696 mid = getMID(mid, N_GETMID (ex)); 697 698 if (mid == (uint32_t)-1) { 699 mid = getMID(mid, N_GETMID (ex_swap)); 700 if (mid != (uint32_t)-1) { 701 mopFileSwapX((u_char *)&ex, 0, 4); 702 } 703 } 704 705 if (mid == (uint32_t)-1) { 706 return(-1); 707 } 708 709 if (N_BADMAG (ex)) { 710 return(-1); 711 } 712 713 switch (mid) { 714 case MID_I386: 715 #ifdef MID_NS32532 716 case MID_NS32532: 717 #endif 718 #ifdef MID_PMAX 719 case MID_PMAX: 720 #endif 721 #ifdef MID_VAX 722 case MID_VAX: 723 #endif 724 #ifdef MID_ALPHA 725 case MID_ALPHA: 726 #endif 727 #ifdef MID_ARM6 728 case MID_ARM6: 729 #endif 730 ex.a_text = mopFileGetLX((u_char *)&ex_swap, 4, 4); 731 ex.a_data = mopFileGetLX((u_char *)&ex_swap, 8, 4); 732 ex.a_bss = mopFileGetLX((u_char *)&ex_swap, 12, 4); 733 ex.a_syms = mopFileGetLX((u_char *)&ex_swap, 16, 4); 734 ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4); 735 ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4); 736 ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4); 737 break; 738 #ifdef MID_M68K 739 case MID_M68K: 740 #endif 741 #ifdef MID_M68K4K 742 case MID_M68K4K: 743 #endif 744 case MID_SPARC: 745 #ifdef MID_MIPS 746 case MID_MIPS: 747 #endif 748 ex.a_text = mopFileGetBX((u_char *)&ex_swap, 4, 4); 749 ex.a_data = mopFileGetBX((u_char *)&ex_swap, 8, 4); 750 ex.a_bss = mopFileGetBX((u_char *)&ex_swap, 12, 4); 751 ex.a_syms = mopFileGetBX((u_char *)&ex_swap, 16, 4); 752 ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4); 753 ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4); 754 ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4); 755 break; 756 default: 757 break; 758 } 759 760 if (info == INFO_PRINT) { 761 printf("a.out image ("); 762 switch (N_GETMID (ex)) { 763 case MID_I386: 764 printf("i386"); 765 break; 766 #ifdef MID_M68K 767 case MID_M68K: 768 printf("m68k"); 769 break; 770 #endif 771 #ifdef MID_M68K4K 772 case MID_M68K4K: 773 printf("m68k 4k"); 774 break; 775 #endif 776 #ifdef MID_NS32532 777 case MID_NS32532: 778 printf("pc532"); 779 break; 780 #endif 781 case MID_SPARC: 782 printf("sparc"); 783 break; 784 #ifdef MID_PMAX 785 case MID_PMAX: 786 printf("pmax"); 787 break; 788 #endif 789 #ifdef MID_VAX 790 case MID_VAX: 791 printf("vax"); 792 break; 793 #endif 794 #ifdef MID_ALPHA 795 case MID_ALPHA: 796 printf("alpha"); 797 break; 798 #endif 799 #ifdef MID_MIPS 800 case MID_MIPS: 801 printf("mips"); 802 break; 803 #endif 804 #ifdef MID_ARM6 805 case MID_ARM6: 806 printf("arm32"); 807 break; 808 #endif 809 default: 810 break; 811 } 812 printf(") Magic: "); 813 switch (N_GETMAGIC (ex)) { 814 case OMAGIC: 815 printf("OMAGIC"); 816 break; 817 case NMAGIC: 818 printf("NMAGIC"); 819 break; 820 case ZMAGIC: 821 printf("ZMAGIC"); 822 break; 823 case QMAGIC: 824 printf("QMAGIC"); 825 break; 826 default: 827 printf("Unknown %ld", (long) N_GETMAGIC (ex)); 828 } 829 printf("\n"); 830 printf("Size of text: %08lx\n", (long)ex.a_text); 831 printf("Size of data: %08lx\n", (long)ex.a_data); 832 printf("Size of bss: %08lx\n", (long)ex.a_bss); 833 printf("Size of symbol tab: %08lx\n", (long)ex.a_syms); 834 printf("Transfer Address: %08lx\n", (long)ex.a_entry); 835 printf("Size of reloc text: %08lx\n", (long)ex.a_trsize); 836 printf("Size of reloc data: %08lx\n", (long)ex.a_drsize); 837 } 838 839 magic = N_GETMAGIC (ex); 840 clbytes = getCLBYTES(mid); 841 clofset = clbytes - 1; 842 843 dl->image_type = IMAGE_TYPE_AOUT; 844 dl->loadaddr = 0; 845 dl->xferaddr = ex.a_entry; 846 847 dl->a_text = ex.a_text; 848 if (magic == ZMAGIC || magic == NMAGIC) { 849 dl->a_text_fill = clbytes - (ex.a_text & clofset); 850 if (dl->a_text_fill == clbytes) 851 dl->a_text_fill = 0; 852 } else 853 dl->a_text_fill = 0; 854 dl->a_data = ex.a_data; 855 if (magic == ZMAGIC || magic == NMAGIC) { 856 dl->a_data_fill = clbytes - (ex.a_data & clofset); 857 if (dl->a_data_fill == clbytes) 858 dl->a_data_fill = 0; 859 } else 860 dl->a_data_fill = 0; 861 dl->a_bss = ex.a_bss; 862 if (magic == ZMAGIC || magic == NMAGIC) { 863 dl->a_bss_fill = clbytes - (ex.a_bss & clofset); 864 if (dl->a_bss_fill == clbytes) 865 dl->a_bss_fill = 0; 866 } else { 867 dl->a_bss_fill = clbytes - 868 ((ex.a_text+ex.a_data+ex.a_bss) & clofset); 869 if (dl->a_bss_fill == clbytes) 870 dl->a_bss_fill = 0; 871 } 872 dl->a_mid = mid; 873 874 return(0); 875 #endif /* NOAOUT */ 876 } 877 878 int 879 GetFileInfo(struct dllist *dl, int info) 880 { 881 int error; 882 883 error = CheckElfFile(dl->ldfd); 884 if (error == 0) { 885 error = GetElfFileInfo(dl, info); 886 if (error != 0) { 887 return(-1); 888 } 889 return (0); 890 } 891 892 error = CheckAOutFile(dl->ldfd); 893 if (error == 0) { 894 error = GetAOutFileInfo(dl, info); 895 if (error != 0) { 896 return(-1); 897 } 898 return (0); 899 } 900 901 error = CheckMopFile(dl->ldfd); 902 if (error == 0) { 903 error = GetMopFileInfo(dl, info); 904 if (error != 0) { 905 return(-1); 906 } 907 return (0); 908 } 909 910 /* Unknown file format. */ 911 return(-1); 912 } 913 914 ssize_t 915 mopFileRead(struct dllist *dlslot, u_char *buf) 916 { 917 ssize_t len, outlen; 918 int bsz, sec; 919 int32_t pos, notdone, total; 920 uint32_t secoff; 921 922 switch (dlslot->image_type) { 923 case IMAGE_TYPE_MOP: 924 len = read(dlslot->ldfd,buf,dlslot->dl_bsz); 925 break; 926 927 case IMAGE_TYPE_ELF32: 928 sec = dlslot->e_cursec; 929 930 /* 931 * We're pretty simplistic here. We do only file-backed 932 * or only zero-fill. 933 */ 934 935 /* Determine offset into section. */ 936 secoff = dlslot->e_curpos - dlslot->e_sections[sec].s_loff; 937 938 /* 939 * If we're in the file-backed part of the section, 940 * transmit some of the file. 941 */ 942 if (secoff < dlslot->e_sections[sec].s_fsize) { 943 bsz = dlslot->e_sections[sec].s_fsize - secoff; 944 if (bsz > dlslot->dl_bsz) 945 bsz = dlslot->dl_bsz; 946 if (lseek(dlslot->ldfd, 947 dlslot->e_sections[sec].s_foff + secoff, 948 SEEK_SET) == (off_t) -1) 949 return (-1); 950 len = read(dlslot->ldfd, buf, bsz); 951 } 952 /* 953 * Otherwise, if we're in the zero-fill part of the 954 * section, transmit some zeros. 955 */ 956 else if (secoff < (dlslot->e_sections[sec].s_fsize + 957 dlslot->e_sections[sec].s_pad)) { 958 bsz = dlslot->e_sections[sec].s_pad - 959 (secoff - dlslot->e_sections[sec].s_fsize); 960 if (bsz > dlslot->dl_bsz) 961 bsz = dlslot->dl_bsz; 962 memset(buf, 0, (len = bsz)); 963 } 964 /* 965 * ...and if we haven't hit either of those cases, 966 * that's the end of the image. 967 */ 968 else { 969 return (0); 970 } 971 /* 972 * Advance the logical image pointer. 973 */ 974 dlslot->e_curpos += bsz; 975 if (dlslot->e_curpos >= (dlslot->e_sections[sec].s_loff + 976 dlslot->e_sections[sec].s_fsize + 977 dlslot->e_sections[sec].s_pad)) 978 dlslot->e_cursec++; 979 break; 980 981 case IMAGE_TYPE_AOUT: 982 bsz = dlslot->dl_bsz; 983 pos = dlslot->a_lseek; 984 len = 0; 985 986 total = dlslot->a_text; 987 988 if (pos < total) { 989 notdone = total - pos; 990 if (notdone <= bsz) { 991 outlen = read(dlslot->ldfd,&buf[len],notdone); 992 } else { 993 outlen = read(dlslot->ldfd,&buf[len],bsz); 994 } 995 len = len + outlen; 996 pos = pos + outlen; 997 bsz = bsz - outlen; 998 } 999 1000 total = total + dlslot->a_text_fill; 1001 1002 if ((bsz > 0) && (pos < total)) { 1003 notdone = total - pos; 1004 if (notdone <= bsz) { 1005 outlen = notdone; 1006 } else { 1007 outlen = bsz; 1008 } 1009 memset(&buf[len], 0, outlen); 1010 len = len + outlen; 1011 pos = pos + outlen; 1012 bsz = bsz - outlen; 1013 } 1014 1015 total = total + dlslot->a_data; 1016 1017 if ((bsz > 0) && (pos < total)) { 1018 notdone = total - pos; 1019 if (notdone <= bsz) { 1020 outlen = read(dlslot->ldfd,&buf[len],notdone); 1021 } else { 1022 outlen = read(dlslot->ldfd,&buf[len],bsz); 1023 } 1024 len = len + outlen; 1025 pos = pos + outlen; 1026 bsz = bsz - outlen; 1027 } 1028 1029 total = total + dlslot->a_data_fill; 1030 1031 if ((bsz > 0) && (pos < total)) { 1032 notdone = total - pos; 1033 if (notdone <= bsz) { 1034 outlen = notdone; 1035 } else { 1036 outlen = bsz; 1037 } 1038 memset(&buf[len], 0, outlen); 1039 len = len + outlen; 1040 pos = pos + outlen; 1041 bsz = bsz - outlen; 1042 } 1043 1044 total = total + dlslot->a_bss; 1045 1046 if ((bsz > 0) && (pos < total)) { 1047 notdone = total - pos; 1048 if (notdone <= bsz) { 1049 outlen = notdone; 1050 } else { 1051 outlen = bsz; 1052 } 1053 memset(&buf[len], 0, outlen); 1054 len = len + outlen; 1055 pos = pos + outlen; 1056 bsz = bsz - outlen; 1057 } 1058 1059 total = total + dlslot->a_bss_fill; 1060 1061 if ((bsz > 0) && (pos < total)) { 1062 notdone = total - pos; 1063 if (notdone <= bsz) { 1064 outlen = notdone; 1065 } else { 1066 outlen = bsz; 1067 } 1068 memset(&buf[len], 0, outlen); 1069 len = len + outlen; 1070 pos = pos + outlen; 1071 bsz = bsz - outlen; 1072 } 1073 1074 dlslot->a_lseek = pos; 1075 break; 1076 1077 default: 1078 abort(); 1079 } 1080 1081 return(len); 1082 } 1083