1 /* $NetBSD: file.c,v 1.20 2024/12/03 05:57:02 kalvisd 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 #if defined (HAVE_NBTOOL_CONFIG_H) 28 # include "nbtool_config.h" 29 #else 30 # include "port.h" 31 #endif /* defined (HAVE_NBTOOL_CONFIG_H) */ 32 #ifndef lint 33 __RCSID("$NetBSD: file.c,v 1.20 2024/12/03 05:57:02 kalvisd Exp $"); 34 #endif 35 36 #include "os.h" 37 #include "common.h" 38 #include "file.h" 39 #include "mopdef.h" 40 #include <stddef.h> 41 42 #ifndef NOAOUT 43 # if defined (HAVE_NBTOOL_CONFIG_H) || defined(__NetBSD__) || defined(__OpenBSD__) 44 # include <sys/exec_aout.h> 45 # endif 46 # if defined(__bsdi__) 47 # define NOAOUT 48 # endif 49 # if defined(__FreeBSD__) 50 # include <sys/imgact_aout.h> 51 # endif 52 # if !defined(MID_VAX) 53 # define MID_VAX 150 54 # endif 55 # if !defined(MID_VAX1K) 56 # define MID_VAX1K 140 57 # endif 58 #endif /* NOAOUT */ 59 60 #ifndef NOELF 61 # if defined (HAVE_NBTOOL_CONFIG_H) || defined(__NetBSD__) 62 # include <sys/exec_elf.h> 63 # else 64 # define NOELF 65 # endif 66 #endif /* NOELF */ 67 68 #ifndef NOAOUT 69 static int getCLBYTES(int); 70 static int getMID(int, int); 71 #endif 72 73 const char * 74 FileTypeName(mopd_imagetype type) 75 { 76 77 switch (type) { 78 case IMAGE_TYPE_MOP: 79 return ("MOP"); 80 81 case IMAGE_TYPE_ELF32: 82 return ("Elf32"); 83 84 case IMAGE_TYPE_AOUT: 85 return ("a.out"); 86 } 87 88 abort(); 89 } 90 91 void 92 mopFilePutLX(u_char *buf, int idx, u_int32_t value, int cnt) 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(u_char *buf, int idx, u_int32_t value, int cnt) 103 { 104 int i; 105 for (i = 0; i < cnt; i++) { 106 buf[idx+cnt-1-i] = value % 256; 107 value = value / 256; 108 } 109 } 110 111 u_int32_t 112 mopFileGetLX(u_char *buf, int idx, int cnt) 113 { 114 u_int32_t ret = 0; 115 int i; 116 117 for (i = 0; i < cnt; i++) { 118 int j = idx + cnt - 1 - i; 119 if (j < 0) 120 abort(); 121 ret = ret * 256 + buf[j]; 122 } 123 124 return(ret); 125 } 126 127 u_int32_t 128 mopFileGetBX(u_char *buf, int idx, int cnt) 129 { 130 u_int32_t ret = 0; 131 int i; 132 133 for (i = 0; i < cnt; i++) { 134 int j = idx + i; 135 if (j < 0) 136 abort(); 137 ret = ret * 256 + buf[j]; 138 } 139 140 return(ret); 141 } 142 143 void 144 mopFileSwapX(u_char *buf, int idx, int cnt) 145 { 146 int i; 147 u_char c; 148 149 for (i = 0; i < (cnt / 2); i++) { 150 c = buf[idx+i]; 151 buf[idx+i] = buf[idx+cnt-1-i]; 152 buf[idx+cnt-1-i] = c; 153 } 154 155 } 156 157 int 158 CheckMopFile(int fd) 159 { 160 u_char header[512]; 161 short image_type; 162 163 if (read(fd, header, 512) != 512) 164 return(-1); 165 166 (void)lseek(fd, (off_t) 0, SEEK_SET); 167 168 image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + 169 header[IHD_W_ALIAS]); 170 171 switch(image_type) { 172 case IHD_C_NATIVE: /* Native mode image (VAX) */ 173 case IHD_C_RSX: /* RSX image produced by TKB */ 174 case IHD_C_BPA: /* BASIC plus analog */ 175 case IHD_C_ALIAS: /* Alias */ 176 case IHD_C_CLI: /* Image is CLI */ 177 case IHD_C_PMAX: /* PMAX system image */ 178 case IHD_C_ALPHA: /* ALPHA system image */ 179 break; 180 default: 181 return(-1); 182 } 183 184 return(0); 185 } 186 187 int 188 GetMopFileInfo(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 static int 300 getMID(int old_mid, int new_mid) 301 { 302 int mid; 303 304 mid = old_mid; 305 306 switch (new_mid) { 307 case MID_I386: 308 mid = MID_I386; 309 break; 310 #ifdef MID_M68K 311 case MID_M68K: 312 mid = MID_M68K; 313 break; 314 #endif 315 #ifdef MID_M68K4K 316 case MID_M68K4K: 317 mid = MID_M68K4K; 318 break; 319 #endif 320 #ifdef MID_NS32532 321 case MID_NS32532: 322 mid = MID_NS32532; 323 break; 324 #endif 325 case MID_SPARC: 326 mid = MID_SPARC; 327 break; 328 #ifdef MID_PMAX 329 case MID_PMAX: 330 mid = MID_PMAX; 331 break; 332 #endif 333 #ifdef MID_VAX 334 case MID_VAX: 335 mid = MID_VAX; 336 break; 337 #endif 338 #ifdef MID_VAX1K 339 case MID_VAX1K: 340 mid = MID_VAX1K; 341 break; 342 #endif 343 #ifdef MID_ALPHA 344 case MID_ALPHA: 345 mid = MID_ALPHA; 346 break; 347 #endif 348 #ifdef MID_MIPS 349 case MID_MIPS: 350 mid = MID_MIPS; 351 break; 352 #endif 353 #ifdef MID_ARM6 354 case MID_ARM6: 355 mid = MID_ARM6; 356 break; 357 #endif 358 default: 359 break; 360 } 361 362 return(mid); 363 } 364 365 static int 366 getCLBYTES(int mid) 367 { 368 int clbytes; 369 370 switch (mid) { 371 #ifdef MID_VAX1K 372 case MID_VAX1K: 373 clbytes = 1024; 374 break; 375 #endif 376 #ifdef MID_I386 377 case MID_I386: 378 #endif 379 #ifdef MID_M68K4K 380 case MID_M68K4K: 381 #endif 382 #ifdef MID_NS32532 383 case MID_NS32532: 384 #endif 385 #ifdef MID_PMAX 386 case MID_PMAX: 387 #endif 388 #ifdef MID_MIPS 389 case MID_MIPS: 390 #endif 391 #ifdef MID_ARM6 392 case MID_ARM6: 393 #endif 394 #ifdef MID_VAX 395 case MID_VAX: 396 #endif 397 #if defined(MID_I386) || defined(MID_M68K4K) || defined(MID_NS32532) || \ 398 defined(MID_PMAX) || defined(MID_MIPS) || defined(MID_ARM6) || \ 399 defined(MID_VAX) 400 clbytes = 4096; 401 break; 402 #endif 403 #ifdef MID_M68K 404 case MID_M68K: 405 #endif 406 #ifdef MID_ALPHA 407 case MID_ALPHA: 408 #endif 409 #ifdef MID_SPARC 410 case MID_SPARC: 411 #endif 412 #if defined(MID_M68K) || defined(MID_ALPHA) || defined(MID_SPARC) 413 clbytes = 8192; 414 break; 415 #endif 416 default: 417 clbytes = 0; 418 } 419 420 return(clbytes); 421 } 422 #endif 423 424 int 425 CheckElfFile(int fd) 426 { 427 #ifdef NOELF 428 return(-1); 429 #else 430 Elf32_Ehdr ehdr; 431 432 (void)lseek(fd, (off_t) 0, SEEK_SET); 433 434 if (read(fd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr)) 435 return(-1); 436 437 if (ehdr.e_ident[0] != ELFMAG0 || 438 ehdr.e_ident[1] != ELFMAG1 || 439 ehdr.e_ident[2] != ELFMAG2 || 440 ehdr.e_ident[3] != ELFMAG3) 441 return(-1); 442 443 /* Must be Elf32... */ 444 if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) 445 return(-1); 446 447 return(0); 448 #endif /* NOELF */ 449 } 450 451 int 452 GetElfFileInfo(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(int fd) 636 { 637 #ifdef NOAOUT 638 return(-1); 639 #else 640 struct exec ex, ex_swap; 641 int mid = -1; 642 643 if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex)) 644 return(-1); 645 646 (void)lseek(fd, (off_t) 0, SEEK_SET); 647 648 if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap)) 649 return(-1); 650 651 (void)lseek(fd, (off_t) 0, SEEK_SET); 652 653 mid = getMID(mid, N_GETMID (ex)); 654 655 if (mid == -1) { 656 mid = getMID(mid, N_GETMID (ex_swap)); 657 } 658 659 if (mid != -1) { 660 return(0); 661 } else { 662 return(-1); 663 } 664 #endif /* NOAOUT */ 665 } 666 667 int 668 GetAOutFileInfo(struct dllist *dl) 669 { 670 #ifdef NOAOUT 671 return(-1); 672 #else 673 struct exec ex, ex_swap; 674 u_int32_t mid = -1; 675 u_int32_t magic, clbytes, clofset; 676 677 if (read(dl->ldfd, (char *)&ex, sizeof(ex)) != sizeof(ex)) 678 return(-1); 679 680 (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET); 681 682 if (read(dl->ldfd, (char *)&ex_swap, 683 sizeof(ex_swap)) != sizeof(ex_swap)) 684 return(-1); 685 686 mopFileSwapX((u_char *)&ex_swap, 0, 4); 687 688 mid = getMID(mid, N_GETMID (ex)); 689 690 if (mid == (uint32_t)-1) { 691 mid = getMID(mid, N_GETMID (ex_swap)); 692 if (mid != (uint32_t)-1) { 693 mopFileSwapX((u_char *)&ex, 0, 4); 694 } 695 } 696 697 if (mid == (uint32_t)-1) { 698 return(-1); 699 } 700 701 if (N_BADMAG (ex)) { 702 return(-1); 703 } 704 705 switch (mid) { 706 case MID_I386: 707 #ifdef MID_NS32532 708 case MID_NS32532: 709 #endif 710 #ifdef MID_PMAX 711 case MID_PMAX: 712 #endif 713 #ifdef MID_VAX 714 case MID_VAX: 715 #endif 716 #ifdef MID_VAX1K 717 case MID_VAX1K: 718 #endif 719 #ifdef MID_ALPHA 720 case MID_ALPHA: 721 #endif 722 #ifdef MID_ARM6 723 case MID_ARM6: 724 #endif 725 ex.a_text = mopFileGetLX((u_char *)&ex_swap, 4, 4); 726 ex.a_data = mopFileGetLX((u_char *)&ex_swap, 8, 4); 727 ex.a_bss = mopFileGetLX((u_char *)&ex_swap, 12, 4); 728 ex.a_syms = mopFileGetLX((u_char *)&ex_swap, 16, 4); 729 ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4); 730 ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4); 731 ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4); 732 break; 733 #ifdef MID_M68K 734 case MID_M68K: 735 #endif 736 #ifdef MID_M68K4K 737 case MID_M68K4K: 738 #endif 739 case MID_SPARC: 740 #ifdef MID_MIPS 741 case MID_MIPS: 742 #endif 743 ex.a_text = mopFileGetBX((u_char *)&ex_swap, 4, 4); 744 ex.a_data = mopFileGetBX((u_char *)&ex_swap, 8, 4); 745 ex.a_bss = mopFileGetBX((u_char *)&ex_swap, 12, 4); 746 ex.a_syms = mopFileGetBX((u_char *)&ex_swap, 16, 4); 747 ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4); 748 ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4); 749 ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4); 750 break; 751 default: 752 break; 753 } 754 755 printf("a.out image ("); 756 switch (N_GETMID (ex)) { 757 case MID_I386: 758 printf("i386"); 759 break; 760 #ifdef MID_M68K 761 case MID_M68K: 762 printf("m68k"); 763 break; 764 #endif 765 #ifdef MID_M68K4K 766 case MID_M68K4K: 767 printf("m68k 4k"); 768 break; 769 #endif 770 #ifdef MID_NS32532 771 case MID_NS32532: 772 printf("pc532"); 773 break; 774 #endif 775 case MID_SPARC: 776 printf("sparc"); 777 break; 778 #ifdef MID_PMAX 779 case MID_PMAX: 780 printf("pmax"); 781 break; 782 #endif 783 #ifdef MID_VAX 784 case MID_VAX: 785 printf("vax"); 786 break; 787 #endif 788 #ifdef MID_VAX1K 789 case MID_VAX1K: 790 printf("vax 1k"); 791 break; 792 #endif 793 #ifdef MID_ALPHA 794 case MID_ALPHA: 795 printf("alpha"); 796 break; 797 #endif 798 #ifdef MID_MIPS 799 case MID_MIPS: 800 printf("mips"); 801 break; 802 #endif 803 #ifdef MID_ARM6 804 case MID_ARM6: 805 printf("arm32"); 806 break; 807 #endif 808 default: 809 break; 810 } 811 printf(") Magic: "); 812 switch (N_GETMAGIC (ex)) { 813 case OMAGIC: 814 printf("OMAGIC"); 815 break; 816 case NMAGIC: 817 printf("NMAGIC"); 818 break; 819 case ZMAGIC: 820 printf("ZMAGIC"); 821 break; 822 case QMAGIC: 823 printf("QMAGIC"); 824 break; 825 default: 826 printf("Unknown %ld", (long) N_GETMAGIC (ex)); 827 } 828 printf("\n"); 829 printf("Size of text: %08lx\n", (long)ex.a_text); 830 printf("Size of data: %08lx\n", (long)ex.a_data); 831 printf("Size of bss: %08lx\n", (long)ex.a_bss); 832 printf("Size of symbol tab: %08lx\n", (long)ex.a_syms); 833 printf("Transfer Address: %08lx\n", (long)ex.a_entry); 834 printf("Size of reloc text: %08lx\n", (long)ex.a_trsize); 835 printf("Size of reloc data: %08lx\n", (long)ex.a_drsize); 836 837 magic = N_GETMAGIC (ex); 838 clbytes = getCLBYTES(mid); 839 clofset = clbytes - 1; 840 841 dl->image_type = IMAGE_TYPE_AOUT; 842 dl->loadaddr = 0; 843 dl->xferaddr = ex.a_entry; 844 845 dl->a_text = ex.a_text; 846 if (magic == ZMAGIC || magic == NMAGIC) { 847 dl->a_text_fill = clbytes - (ex.a_text & clofset); 848 if (dl->a_text_fill == clbytes) 849 dl->a_text_fill = 0; 850 } else 851 dl->a_text_fill = 0; 852 dl->a_data = ex.a_data; 853 if (magic == ZMAGIC || magic == NMAGIC) { 854 dl->a_data_fill = clbytes - (ex.a_data & clofset); 855 if (dl->a_data_fill == clbytes) 856 dl->a_data_fill = 0; 857 } else 858 dl->a_data_fill = 0; 859 dl->a_bss = ex.a_bss; 860 if (magic == ZMAGIC || magic == NMAGIC) { 861 dl->a_bss_fill = clbytes - (ex.a_bss & clofset); 862 if (dl->a_bss_fill == clbytes) 863 dl->a_bss_fill = 0; 864 } else { 865 dl->a_bss_fill = clbytes - 866 ((ex.a_text+ex.a_data+ex.a_bss) & clofset); 867 if (dl->a_bss_fill == clbytes) 868 dl->a_bss_fill = 0; 869 } 870 dl->a_mid = mid; 871 872 return(0); 873 #endif /* NOAOUT */ 874 } 875 876 int 877 GetFileInfo(struct dllist *dl) 878 { 879 int error; 880 881 error = CheckElfFile(dl->ldfd); 882 if (error == 0) { 883 error = GetElfFileInfo(dl); 884 if (error != 0) { 885 return(-1); 886 } 887 return (0); 888 } 889 890 error = CheckAOutFile(dl->ldfd); 891 if (error == 0) { 892 error = GetAOutFileInfo(dl); 893 if (error != 0) { 894 return(-1); 895 } 896 return (0); 897 } 898 899 error = CheckMopFile(dl->ldfd); 900 if (error == 0) { 901 error = GetMopFileInfo(dl); 902 if (error != 0) { 903 return(-1); 904 } 905 return (0); 906 } 907 908 /* Unknown file format. */ 909 return(-1); 910 } 911 912 ssize_t 913 mopFileRead(struct dllist *dlslot, u_char *buf) 914 { 915 ssize_t len, outlen; 916 int bsz, sec; 917 int32_t pos, notdone, total; 918 uint32_t secoff; 919 920 switch (dlslot->image_type) { 921 case IMAGE_TYPE_MOP: 922 len = read(dlslot->ldfd,buf,dlslot->dl_bsz); 923 break; 924 925 case IMAGE_TYPE_ELF32: 926 sec = dlslot->e_cursec; 927 928 /* 929 * We're pretty simplistic here. We do only file-backed 930 * or only zero-fill. 931 */ 932 933 /* Determine offset into section. */ 934 secoff = dlslot->e_curpos - dlslot->e_sections[sec].s_loff; 935 936 /* 937 * If we're in the file-backed part of the section, 938 * transmit some of the file. 939 */ 940 if (secoff < dlslot->e_sections[sec].s_fsize) { 941 bsz = dlslot->e_sections[sec].s_fsize - secoff; 942 if (bsz > dlslot->dl_bsz) 943 bsz = dlslot->dl_bsz; 944 if (lseek(dlslot->ldfd, 945 dlslot->e_sections[sec].s_foff + secoff, 946 SEEK_SET) == (off_t) -1) 947 return (-1); 948 len = read(dlslot->ldfd, buf, bsz); 949 } 950 /* 951 * Otherwise, if we're in the zero-fill part of the 952 * section, transmit some zeros. 953 */ 954 else if (secoff < (dlslot->e_sections[sec].s_fsize + 955 dlslot->e_sections[sec].s_pad)) { 956 bsz = dlslot->e_sections[sec].s_pad - 957 (secoff - dlslot->e_sections[sec].s_fsize); 958 if (bsz > dlslot->dl_bsz) 959 bsz = dlslot->dl_bsz; 960 memset(buf, 0, (len = bsz)); 961 } 962 /* 963 * ...and if we haven't hit either of those cases, 964 * that's the end of the image. 965 */ 966 else { 967 return (0); 968 } 969 /* 970 * Advance the logical image pointer. 971 */ 972 dlslot->e_curpos += bsz; 973 if (dlslot->e_curpos >= (dlslot->e_sections[sec].s_loff + 974 dlslot->e_sections[sec].s_fsize + 975 dlslot->e_sections[sec].s_pad)) 976 if (++dlslot->e_cursec >= dlslot->e_nsec) 977 return (0); 978 break; 979 980 case IMAGE_TYPE_AOUT: 981 bsz = dlslot->dl_bsz; 982 pos = dlslot->a_lseek; 983 len = 0; 984 985 total = dlslot->a_text; 986 987 if (pos < total) { 988 notdone = total - pos; 989 if (notdone <= bsz) { 990 outlen = read(dlslot->ldfd,&buf[len],notdone); 991 } else { 992 outlen = read(dlslot->ldfd,&buf[len],bsz); 993 } 994 len = len + outlen; 995 pos = pos + outlen; 996 bsz = bsz - outlen; 997 } 998 999 total = total + dlslot->a_text_fill; 1000 1001 if ((bsz > 0) && (pos < total)) { 1002 notdone = total - pos; 1003 if (notdone <= bsz) { 1004 outlen = notdone; 1005 } else { 1006 outlen = bsz; 1007 } 1008 memset(&buf[len], 0, outlen); 1009 len = len + outlen; 1010 pos = pos + outlen; 1011 bsz = bsz - outlen; 1012 } 1013 1014 total = total + dlslot->a_data; 1015 1016 if ((bsz > 0) && (pos < total)) { 1017 notdone = total - pos; 1018 if (notdone <= bsz) { 1019 outlen = read(dlslot->ldfd,&buf[len],notdone); 1020 } else { 1021 outlen = read(dlslot->ldfd,&buf[len],bsz); 1022 } 1023 len = len + outlen; 1024 pos = pos + outlen; 1025 bsz = bsz - outlen; 1026 } 1027 1028 total = total + dlslot->a_data_fill; 1029 1030 if ((bsz > 0) && (pos < total)) { 1031 notdone = total - pos; 1032 if (notdone <= bsz) { 1033 outlen = notdone; 1034 } else { 1035 outlen = bsz; 1036 } 1037 memset(&buf[len], 0, outlen); 1038 len = len + outlen; 1039 pos = pos + outlen; 1040 bsz = bsz - outlen; 1041 } 1042 1043 total = total + dlslot->a_bss; 1044 1045 if ((bsz > 0) && (pos < total)) { 1046 notdone = total - pos; 1047 if (notdone <= bsz) { 1048 outlen = notdone; 1049 } else { 1050 outlen = bsz; 1051 } 1052 memset(&buf[len], 0, outlen); 1053 len = len + outlen; 1054 pos = pos + outlen; 1055 bsz = bsz - outlen; 1056 } 1057 1058 total = total + dlslot->a_bss_fill; 1059 1060 if ((bsz > 0) && (pos < total)) { 1061 notdone = total - pos; 1062 if (notdone <= bsz) { 1063 outlen = notdone; 1064 } else { 1065 outlen = bsz; 1066 } 1067 memset(&buf[len], 0, outlen); 1068 len = len + outlen; 1069 pos = pos + outlen; 1070 bsz = bsz - outlen; 1071 } 1072 1073 dlslot->a_lseek = pos; 1074 break; 1075 1076 default: 1077 abort(); 1078 } 1079 1080 return(len); 1081 } 1082