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