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