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