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