diff options
| author | YAMAMOTO Mitsuharu | 2006-11-02 04:37:35 +0000 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2006-11-02 04:37:35 +0000 |
| commit | 73da71f9263bde6b273665baba5b3b9842803f59 (patch) | |
| tree | 0d380a738ecc88479b613171760a00c2ae14b18d /src | |
| parent | 95eefb35101f1489de82f26366a42a0c3ed2de7a (diff) | |
| download | emacs-73da71f9263bde6b273665baba5b3b9842803f59.tar.gz emacs-73da71f9263bde6b273665baba5b3b9842803f59.zip | |
2006-11-02 Nozomu Ando <nand@mac.com>
* unexmacosx.c (mach_header, segment_command, vm_region, section)
[_LP64]: New defines.
(VM_REGION_BASIC_INFO_COUNT, VM_REGION_BASIC_INFO, LC_SEGMENT)
(MH_MAGIC) [_LP64]: Redefine.
(delta): Remove variable.
(curr_file_offset, pagesize): New variables.
(ROUNDUP_TO_PAGE_BOUNDARY): New macro.
(data_segment_old_fileoff): Initialize explicitly.
(print_region, unexec_regions_recorder, print_load_command_name)
(copy_segment, copy_data_segment): Use long format in printf.
(MAX_UNEXEC_REGIONS): Increase to 400.
(unexec_regions_recorder): Don't warn too many regions here.
(find_emacs_zone_regions): Warn too many regions here.
(print_load_command_name) [_LP64]: Show correct load command name.
(copy_segment, copy_data_segment): Use variable `curr_file_offset'.
Show starting virtual memory address. Don't show ending file offset.
(copy_symtab, copy_dysymtab, copy_twolevelhints): New argument DELTA.
(dump_it): Use new local variable `linkedit_delta' and pass to them.
Error if trying to handle multiple DATA segments.
(unexec): Initialize variable `pagesize'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 23 | ||||
| -rw-r--r-- | src/unexmacosx.c | 118 |
2 files changed, 98 insertions, 43 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d81f43cbec9..ad87bbc9dad 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,26 @@ | |||
| 1 | 2006-11-02 Nozomu Ando <nand@mac.com> | ||
| 2 | |||
| 3 | * unexmacosx.c (mach_header, segment_command, vm_region, section) | ||
| 4 | [_LP64]: New defines. | ||
| 5 | (VM_REGION_BASIC_INFO_COUNT, VM_REGION_BASIC_INFO, LC_SEGMENT) | ||
| 6 | (MH_MAGIC) [_LP64]: Redefine. | ||
| 7 | (delta): Remove variable. | ||
| 8 | (curr_file_offset, pagesize): New variables. | ||
| 9 | (ROUNDUP_TO_PAGE_BOUNDARY): New macro. | ||
| 10 | (data_segment_old_fileoff): Initialize explicitly. | ||
| 11 | (print_region, unexec_regions_recorder, print_load_command_name) | ||
| 12 | (copy_segment, copy_data_segment): Use long format in printf. | ||
| 13 | (MAX_UNEXEC_REGIONS): Increase to 400. | ||
| 14 | (unexec_regions_recorder): Don't warn too many regions here. | ||
| 15 | (find_emacs_zone_regions): Warn too many regions here. | ||
| 16 | (print_load_command_name) [_LP64]: Show correct load command name. | ||
| 17 | (copy_segment, copy_data_segment): Use variable `curr_file_offset'. | ||
| 18 | Show starting virtual memory address. Don't show ending file offset. | ||
| 19 | (copy_symtab, copy_dysymtab, copy_twolevelhints): New argument DELTA. | ||
| 20 | (dump_it): Use new local variable `linkedit_delta' and pass to them. | ||
| 21 | Error if trying to handle multiple DATA segments. | ||
| 22 | (unexec): Initialize variable `pagesize'. | ||
| 23 | |||
| 1 | 2006-11-01 Juanma Barranquero <lekktu@gmail.com> | 24 | 2006-11-01 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 25 | ||
| 3 | * eval.c (Fcatch): Doc fix. | 26 | * eval.c (Fcatch): Doc fix. |
diff --git a/src/unexmacosx.c b/src/unexmacosx.c index f65fd9cbc22..a1950f9445e 100644 --- a/src/unexmacosx.c +++ b/src/unexmacosx.c | |||
| @@ -112,6 +112,20 @@ Boston, MA 02110-1301, USA. */ | |||
| 112 | 112 | ||
| 113 | #include <assert.h> | 113 | #include <assert.h> |
| 114 | 114 | ||
| 115 | #ifdef _LP64 | ||
| 116 | #define mach_header mach_header_64 | ||
| 117 | #define segment_command segment_command_64 | ||
| 118 | #undef VM_REGION_BASIC_INFO_COUNT | ||
| 119 | #define VM_REGION_BASIC_INFO_COUNT VM_REGION_BASIC_INFO_COUNT_64 | ||
| 120 | #undef VM_REGION_BASIC_INFO | ||
| 121 | #define VM_REGION_BASIC_INFO VM_REGION_BASIC_INFO_64 | ||
| 122 | #undef LC_SEGMENT | ||
| 123 | #define LC_SEGMENT LC_SEGMENT_64 | ||
| 124 | #define vm_region vm_region_64 | ||
| 125 | #define section section_64 | ||
| 126 | #undef MH_MAGIC | ||
| 127 | #define MH_MAGIC MH_MAGIC_64 | ||
| 128 | #endif | ||
| 115 | 129 | ||
| 116 | #define VERBOSE 1 | 130 | #define VERBOSE 1 |
| 117 | 131 | ||
| @@ -164,9 +178,11 @@ struct mach_header mh; | |||
| 164 | /* Offset at which the next load command should be written. */ | 178 | /* Offset at which the next load command should be written. */ |
| 165 | unsigned long curr_header_offset = sizeof (struct mach_header); | 179 | unsigned long curr_header_offset = sizeof (struct mach_header); |
| 166 | 180 | ||
| 167 | /* Current adjustment that needs to be made to offset values because | 181 | /* Offset at which the next segment should be written. */ |
| 168 | of additional data segments. */ | 182 | static unsigned long curr_file_offset = 0; |
| 169 | unsigned long delta = 0; | 183 | |
| 184 | static unsigned long pagesize; | ||
| 185 | #define ROUNDUP_TO_PAGE_BOUNDARY(x) (((x) + pagesize - 1) & ~(pagesize - 1)) | ||
| 170 | 186 | ||
| 171 | int infd, outfd; | 187 | int infd, outfd; |
| 172 | 188 | ||
| @@ -175,7 +191,7 @@ int in_dumped_exec = 0; | |||
| 175 | malloc_zone_t *emacs_zone; | 191 | malloc_zone_t *emacs_zone; |
| 176 | 192 | ||
| 177 | /* file offset of input file's data segment */ | 193 | /* file offset of input file's data segment */ |
| 178 | off_t data_segment_old_fileoff; | 194 | off_t data_segment_old_fileoff = 0; |
| 179 | 195 | ||
| 180 | struct segment_command *data_segment_scp; | 196 | struct segment_command *data_segment_scp; |
| 181 | 197 | ||
| @@ -286,7 +302,7 @@ static void | |||
| 286 | print_region (vm_address_t address, vm_size_t size, vm_prot_t prot, | 302 | print_region (vm_address_t address, vm_size_t size, vm_prot_t prot, |
| 287 | vm_prot_t max_prot) | 303 | vm_prot_t max_prot) |
| 288 | { | 304 | { |
| 289 | printf ("%#10x %#8x ", address, size); | 305 | printf ("%#10lx %#8lx ", (long) address, (long) size); |
| 290 | print_prot (prot); | 306 | print_prot (prot); |
| 291 | putchar (' '); | 307 | putchar (' '); |
| 292 | print_prot (max_prot); | 308 | print_prot (max_prot); |
| @@ -412,7 +428,7 @@ build_region_list () | |||
| 412 | } | 428 | } |
| 413 | 429 | ||
| 414 | 430 | ||
| 415 | #define MAX_UNEXEC_REGIONS 200 | 431 | #define MAX_UNEXEC_REGIONS 400 |
| 416 | 432 | ||
| 417 | int num_unexec_regions; | 433 | int num_unexec_regions; |
| 418 | vm_range_t unexec_regions[MAX_UNEXEC_REGIONS]; | 434 | vm_range_t unexec_regions[MAX_UNEXEC_REGIONS]; |
| @@ -424,11 +440,10 @@ unexec_regions_recorder (task_t task, void *rr, unsigned type, | |||
| 424 | while (num && num_unexec_regions < MAX_UNEXEC_REGIONS) | 440 | while (num && num_unexec_regions < MAX_UNEXEC_REGIONS) |
| 425 | { | 441 | { |
| 426 | unexec_regions[num_unexec_regions++] = *ranges; | 442 | unexec_regions[num_unexec_regions++] = *ranges; |
| 427 | printf ("%#8x (sz: %#8x)\n", ranges->address, ranges->size); | 443 | printf ("%#8lx (sz: %#8lx)\n", |
| 444 | (long) (ranges->address), (long) (ranges->size)); | ||
| 428 | ranges++; num--; | 445 | ranges++; num--; |
| 429 | } | 446 | } |
| 430 | if (num_unexec_regions == MAX_UNEXEC_REGIONS) | ||
| 431 | fprintf (stderr, "malloc_freezedry_recorder: too many regions\n"); | ||
| 432 | } | 447 | } |
| 433 | 448 | ||
| 434 | static kern_return_t | 449 | static kern_return_t |
| @@ -449,6 +464,9 @@ find_emacs_zone_regions () | |||
| 449 | (vm_address_t) emacs_zone, | 464 | (vm_address_t) emacs_zone, |
| 450 | unexec_reader, | 465 | unexec_reader, |
| 451 | unexec_regions_recorder); | 466 | unexec_regions_recorder); |
| 467 | |||
| 468 | if (num_unexec_regions == MAX_UNEXEC_REGIONS) | ||
| 469 | unexec_error ("find_emacs_zone_regions: too many regions"); | ||
| 452 | } | 470 | } |
| 453 | 471 | ||
| 454 | static int | 472 | static int |
| @@ -500,7 +518,11 @@ print_load_command_name (int lc) | |||
| 500 | switch (lc) | 518 | switch (lc) |
| 501 | { | 519 | { |
| 502 | case LC_SEGMENT: | 520 | case LC_SEGMENT: |
| 521 | #ifndef _LP64 | ||
| 503 | printf ("LC_SEGMENT "); | 522 | printf ("LC_SEGMENT "); |
| 523 | #else | ||
| 524 | printf ("LC_SEGMENT_64 "); | ||
| 525 | #endif | ||
| 504 | break; | 526 | break; |
| 505 | case LC_LOAD_DYLINKER: | 527 | case LC_LOAD_DYLINKER: |
| 506 | printf ("LC_LOAD_DYLINKER "); | 528 | printf ("LC_LOAD_DYLINKER "); |
| @@ -541,14 +563,14 @@ print_load_command (struct load_command *lc) | |||
| 541 | int j; | 563 | int j; |
| 542 | 564 | ||
| 543 | scp = (struct segment_command *) lc; | 565 | scp = (struct segment_command *) lc; |
| 544 | printf (" %-16.16s %#10x %#8x\n", | 566 | printf (" %-16.16s %#10lx %#8lx\n", |
| 545 | scp->segname, scp->vmaddr, scp->vmsize); | 567 | scp->segname, (long) (scp->vmaddr), (long) (scp->vmsize)); |
| 546 | 568 | ||
| 547 | sectp = (struct section *) (scp + 1); | 569 | sectp = (struct section *) (scp + 1); |
| 548 | for (j = 0; j < scp->nsects; j++) | 570 | for (j = 0; j < scp->nsects; j++) |
| 549 | { | 571 | { |
| 550 | printf (" %-16.16s %#10x %#8x\n", | 572 | printf (" %-16.16s %#10lx %#8lx\n", |
| 551 | sectp->sectname, sectp->addr, sectp->size); | 573 | sectp->sectname, (long) (sectp->addr), (long) (sectp->size)); |
| 552 | sectp++; | 574 | sectp++; |
| 553 | } | 575 | } |
| 554 | } | 576 | } |
| @@ -644,21 +666,23 @@ copy_segment (struct load_command *lc) | |||
| 644 | struct section *sectp; | 666 | struct section *sectp; |
| 645 | int j; | 667 | int j; |
| 646 | 668 | ||
| 647 | scp->fileoff += delta; | 669 | scp->fileoff = curr_file_offset; |
| 648 | 670 | ||
| 649 | sectp = (struct section *) (scp + 1); | 671 | sectp = (struct section *) (scp + 1); |
| 650 | for (j = 0; j < scp->nsects; j++) | 672 | for (j = 0; j < scp->nsects; j++) |
| 651 | { | 673 | { |
| 652 | sectp->offset += delta; | 674 | sectp->offset += curr_file_offset - old_fileoff; |
| 653 | sectp++; | 675 | sectp++; |
| 654 | } | 676 | } |
| 655 | 677 | ||
| 656 | printf ("Writing segment %-16.16s at %#8x - %#8x (sz: %#8x)\n", | 678 | printf ("Writing segment %-16.16s @ %#8lx (%#8lx @ %#8lx)\n", |
| 657 | scp->segname, scp->fileoff, scp->fileoff + scp->filesize, | 679 | scp->segname, (long) (scp->fileoff), (long) (scp->vmsize), |
| 658 | scp->filesize); | 680 | (long) (scp->vmaddr)); |
| 659 | 681 | ||
| 660 | if (!unexec_copy (scp->fileoff, old_fileoff, scp->filesize)) | 682 | if (!unexec_copy (scp->fileoff, old_fileoff, scp->filesize)) |
| 661 | unexec_error ("cannot copy segment from input to output file"); | 683 | unexec_error ("cannot copy segment from input to output file"); |
| 684 | curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (scp->filesize); | ||
| 685 | |||
| 662 | if (!unexec_write (curr_header_offset, lc, lc->cmdsize)) | 686 | if (!unexec_write (curr_header_offset, lc, lc->cmdsize)) |
| 663 | unexec_error ("cannot write load command to header"); | 687 | unexec_error ("cannot write load command to header"); |
| 664 | 688 | ||
| @@ -685,12 +709,9 @@ copy_data_segment (struct load_command *lc) | |||
| 685 | int j; | 709 | int j; |
| 686 | unsigned long header_offset, file_offset, old_file_offset; | 710 | unsigned long header_offset, file_offset, old_file_offset; |
| 687 | 711 | ||
| 688 | printf ("Writing segment %-16.16s at %#8x - %#8x (sz: %#8x)\n", | 712 | printf ("Writing segment %-16.16s @ %#8lx (%#8lx @ %#8lx)\n", |
| 689 | scp->segname, scp->fileoff, scp->fileoff + scp->filesize, | 713 | scp->segname, curr_file_offset, (long)(scp->vmsize), |
| 690 | scp->filesize); | 714 | (long) (scp->vmaddr)); |
| 691 | |||
| 692 | if (delta != 0) | ||
| 693 | unexec_error ("cannot handle multiple DATA segments in input file"); | ||
| 694 | 715 | ||
| 695 | /* Offsets in the output file for writing the next section structure | 716 | /* Offsets in the output file for writing the next section structure |
| 696 | and segment data block, respectively. */ | 717 | and segment data block, respectively. */ |
| @@ -700,7 +721,7 @@ copy_data_segment (struct load_command *lc) | |||
| 700 | for (j = 0; j < scp->nsects; j++) | 721 | for (j = 0; j < scp->nsects; j++) |
| 701 | { | 722 | { |
| 702 | old_file_offset = sectp->offset; | 723 | old_file_offset = sectp->offset; |
| 703 | sectp->offset = sectp->addr - scp->vmaddr + scp->fileoff; | 724 | sectp->offset = sectp->addr - scp->vmaddr + curr_file_offset; |
| 704 | /* The __data section is dumped from memory. The __bss and | 725 | /* The __data section is dumped from memory. The __bss and |
| 705 | __common sections are also dumped from memory but their flag | 726 | __common sections are also dumped from memory but their flag |
| 706 | fields require changing (from S_ZEROFILL to S_REGULAR). The | 727 | fields require changing (from S_ZEROFILL to S_REGULAR). The |
| @@ -762,9 +783,9 @@ copy_data_segment (struct load_command *lc) | |||
| 762 | else | 783 | else |
| 763 | unexec_error ("unrecognized section name in __DATA segment"); | 784 | unexec_error ("unrecognized section name in __DATA segment"); |
| 764 | 785 | ||
| 765 | printf (" section %-16.16s at %#8x - %#8x (sz: %#8x)\n", | 786 | printf (" section %-16.16s at %#8lx - %#8lx (sz: %#8lx)\n", |
| 766 | sectp->sectname, sectp->offset, sectp->offset + sectp->size, | 787 | sectp->sectname, (long) (sectp->offset), |
| 767 | sectp->size); | 788 | (long) (sectp->offset + sectp->size), (long) (sectp->size)); |
| 768 | 789 | ||
| 769 | header_offset += sizeof (struct section); | 790 | header_offset += sizeof (struct section); |
| 770 | sectp++; | 791 | sectp++; |
| @@ -775,17 +796,16 @@ copy_data_segment (struct load_command *lc) | |||
| 775 | this may leave unused locations at the end of the segment data | 796 | this may leave unused locations at the end of the segment data |
| 776 | block because the total of the sizes of all sections in the | 797 | block because the total of the sizes of all sections in the |
| 777 | segment is generally smaller than vmsize. */ | 798 | segment is generally smaller than vmsize. */ |
| 778 | delta = scp->vmsize - scp->filesize; | ||
| 779 | scp->filesize = scp->vmsize; | 799 | scp->filesize = scp->vmsize; |
| 780 | if (!unexec_write (curr_header_offset, scp, sizeof (struct segment_command))) | 800 | if (!unexec_write (curr_header_offset, scp, sizeof (struct segment_command))) |
| 781 | unexec_error ("cannot write header of __DATA segment"); | 801 | unexec_error ("cannot write header of __DATA segment"); |
| 782 | curr_header_offset += lc->cmdsize; | 802 | curr_header_offset += lc->cmdsize; |
| 803 | curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (scp->filesize); | ||
| 783 | 804 | ||
| 784 | /* Create new __DATA segment load commands for regions on the region | 805 | /* Create new __DATA segment load commands for regions on the region |
| 785 | list that do not corresponding to any segment load commands in | 806 | list that do not corresponding to any segment load commands in |
| 786 | the input file. | 807 | the input file. |
| 787 | */ | 808 | */ |
| 788 | file_offset = scp->fileoff + scp->filesize; | ||
| 789 | for (j = 0; j < num_unexec_regions; j++) | 809 | for (j = 0; j < num_unexec_regions; j++) |
| 790 | { | 810 | { |
| 791 | struct segment_command sc; | 811 | struct segment_command sc; |
| @@ -795,21 +815,20 @@ copy_data_segment (struct load_command *lc) | |||
| 795 | strncpy (sc.segname, SEG_DATA, 16); | 815 | strncpy (sc.segname, SEG_DATA, 16); |
| 796 | sc.vmaddr = unexec_regions[j].address; | 816 | sc.vmaddr = unexec_regions[j].address; |
| 797 | sc.vmsize = unexec_regions[j].size; | 817 | sc.vmsize = unexec_regions[j].size; |
| 798 | sc.fileoff = file_offset; | 818 | sc.fileoff = curr_file_offset; |
| 799 | sc.filesize = unexec_regions[j].size; | 819 | sc.filesize = unexec_regions[j].size; |
| 800 | sc.maxprot = VM_PROT_READ | VM_PROT_WRITE; | 820 | sc.maxprot = VM_PROT_READ | VM_PROT_WRITE; |
| 801 | sc.initprot = VM_PROT_READ | VM_PROT_WRITE; | 821 | sc.initprot = VM_PROT_READ | VM_PROT_WRITE; |
| 802 | sc.nsects = 0; | 822 | sc.nsects = 0; |
| 803 | sc.flags = 0; | 823 | sc.flags = 0; |
| 804 | 824 | ||
| 805 | printf ("Writing segment %-16.16s at %#8x - %#8x (sz: %#8x)\n", | 825 | printf ("Writing segment %-16.16s @ %#8lx (%#8lx @ %#8lx)\n", |
| 806 | sc.segname, sc.fileoff, sc.fileoff + sc.filesize, | 826 | sc.segname, (long) (sc.fileoff), (long) (sc.vmsize), |
| 807 | sc.filesize); | 827 | (long) (sc.vmaddr)); |
| 808 | 828 | ||
| 809 | if (!unexec_write (sc.fileoff, (void *) sc.vmaddr, sc.vmsize)) | 829 | if (!unexec_write (sc.fileoff, (void *) sc.vmaddr, sc.vmsize)) |
| 810 | unexec_error ("cannot write new __DATA segment"); | 830 | unexec_error ("cannot write new __DATA segment"); |
| 811 | delta += sc.filesize; | 831 | curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (sc.filesize); |
| 812 | file_offset += sc.filesize; | ||
| 813 | 832 | ||
| 814 | if (!unexec_write (curr_header_offset, &sc, sc.cmdsize)) | 833 | if (!unexec_write (curr_header_offset, &sc, sc.cmdsize)) |
| 815 | unexec_error ("cannot write new __DATA segment's header"); | 834 | unexec_error ("cannot write new __DATA segment's header"); |
| @@ -821,7 +840,7 @@ copy_data_segment (struct load_command *lc) | |||
| 821 | /* Copy a LC_SYMTAB load command from the input file to the output | 840 | /* Copy a LC_SYMTAB load command from the input file to the output |
| 822 | file, adjusting the file offset fields. */ | 841 | file, adjusting the file offset fields. */ |
| 823 | static void | 842 | static void |
| 824 | copy_symtab (struct load_command *lc) | 843 | copy_symtab (struct load_command *lc, long delta) |
| 825 | { | 844 | { |
| 826 | struct symtab_command *stp = (struct symtab_command *) lc; | 845 | struct symtab_command *stp = (struct symtab_command *) lc; |
| 827 | 846 | ||
| @@ -898,7 +917,7 @@ unrelocate (const char *name, off_t reloff, int nrel) | |||
| 898 | /* Copy a LC_DYSYMTAB load command from the input file to the output | 917 | /* Copy a LC_DYSYMTAB load command from the input file to the output |
| 899 | file, adjusting the file offset fields. */ | 918 | file, adjusting the file offset fields. */ |
| 900 | static void | 919 | static void |
| 901 | copy_dysymtab (struct load_command *lc) | 920 | copy_dysymtab (struct load_command *lc, long delta) |
| 902 | { | 921 | { |
| 903 | struct dysymtab_command *dstp = (struct dysymtab_command *) lc; | 922 | struct dysymtab_command *dstp = (struct dysymtab_command *) lc; |
| 904 | 923 | ||
| @@ -927,7 +946,7 @@ copy_dysymtab (struct load_command *lc) | |||
| 927 | /* Copy a LC_TWOLEVEL_HINTS load command from the input file to the output | 946 | /* Copy a LC_TWOLEVEL_HINTS load command from the input file to the output |
| 928 | file, adjusting the file offset fields. */ | 947 | file, adjusting the file offset fields. */ |
| 929 | static void | 948 | static void |
| 930 | copy_twolevelhints (struct load_command *lc) | 949 | copy_twolevelhints (struct load_command *lc, long delta) |
| 931 | { | 950 | { |
| 932 | struct twolevel_hints_command *tlhp = (struct twolevel_hints_command *) lc; | 951 | struct twolevel_hints_command *tlhp = (struct twolevel_hints_command *) lc; |
| 933 | 952 | ||
| @@ -964,6 +983,7 @@ static void | |||
| 964 | dump_it () | 983 | dump_it () |
| 965 | { | 984 | { |
| 966 | int i; | 985 | int i; |
| 986 | long linkedit_delta = 0; | ||
| 967 | 987 | ||
| 968 | printf ("--- Load Commands written to Output File ---\n"); | 988 | printf ("--- Load Commands written to Output File ---\n"); |
| 969 | 989 | ||
| @@ -977,6 +997,9 @@ dump_it () | |||
| 977 | { | 997 | { |
| 978 | /* save data segment file offset and segment_command for | 998 | /* save data segment file offset and segment_command for |
| 979 | unrelocate */ | 999 | unrelocate */ |
| 1000 | if (data_segment_old_fileoff) | ||
| 1001 | unexec_error ("cannot handle multiple DATA segments" | ||
| 1002 | " in input file"); | ||
| 980 | data_segment_old_fileoff = scp->fileoff; | 1003 | data_segment_old_fileoff = scp->fileoff; |
| 981 | data_segment_scp = scp; | 1004 | data_segment_scp = scp; |
| 982 | 1005 | ||
| @@ -984,18 +1007,26 @@ dump_it () | |||
| 984 | } | 1007 | } |
| 985 | else | 1008 | else |
| 986 | { | 1009 | { |
| 1010 | if (strncmp (scp->segname, SEG_LINKEDIT, 16) == 0) | ||
| 1011 | { | ||
| 1012 | if (linkedit_delta) | ||
| 1013 | unexec_error ("cannot handle multiple LINKEDIT segments" | ||
| 1014 | " in input file"); | ||
| 1015 | linkedit_delta = curr_file_offset - scp->fileoff; | ||
| 1016 | } | ||
| 1017 | |||
| 987 | copy_segment (lca[i]); | 1018 | copy_segment (lca[i]); |
| 988 | } | 1019 | } |
| 989 | } | 1020 | } |
| 990 | break; | 1021 | break; |
| 991 | case LC_SYMTAB: | 1022 | case LC_SYMTAB: |
| 992 | copy_symtab (lca[i]); | 1023 | copy_symtab (lca[i], linkedit_delta); |
| 993 | break; | 1024 | break; |
| 994 | case LC_DYSYMTAB: | 1025 | case LC_DYSYMTAB: |
| 995 | copy_dysymtab (lca[i]); | 1026 | copy_dysymtab (lca[i], linkedit_delta); |
| 996 | break; | 1027 | break; |
| 997 | case LC_TWOLEVEL_HINTS: | 1028 | case LC_TWOLEVEL_HINTS: |
| 998 | copy_twolevelhints (lca[i]); | 1029 | copy_twolevelhints (lca[i], linkedit_delta); |
| 999 | break; | 1030 | break; |
| 1000 | default: | 1031 | default: |
| 1001 | copy_other (lca[i]); | 1032 | copy_other (lca[i]); |
| @@ -1024,6 +1055,7 @@ unexec (char *outfile, char *infile, void *start_data, void *start_bss, | |||
| 1024 | if (in_dumped_exec) | 1055 | if (in_dumped_exec) |
| 1025 | unexec_error ("Unexec from a dumped executable is not supported."); | 1056 | unexec_error ("Unexec from a dumped executable is not supported."); |
| 1026 | 1057 | ||
| 1058 | pagesize = getpagesize (); | ||
| 1027 | infd = open (infile, O_RDONLY, 0); | 1059 | infd = open (infile, O_RDONLY, 0); |
| 1028 | if (infd < 0) | 1060 | if (infd < 0) |
| 1029 | { | 1061 | { |