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