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