Mercurial > emacs
comparison src/unexmacosx.c @ 73613:fd7f97a75198
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'.
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
---|---|
date | Thu, 02 Nov 2006 04:37:26 +0000 |
parents | 470ac698d6f7 |
children | 04b7851d50f8 |
comparison
equal
deleted
inserted
replaced
73612:0dc9329d69be | 73613:fd7f97a75198 |
---|---|
110 #include <objc/malloc.h> | 110 #include <objc/malloc.h> |
111 #endif | 111 #endif |
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 |
118 /* Size of buffer used to copy data from the input file to the output | 132 /* Size of buffer used to copy data from the input file to the output |
119 file in function unexec_copy. */ | 133 file in function unexec_copy. */ |
162 struct mach_header mh; | 176 struct mach_header mh; |
163 | 177 |
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 |
173 int in_dumped_exec = 0; | 189 int in_dumped_exec = 0; |
174 | 190 |
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 |
182 /* Read N bytes from infd into memory starting at address DEST. | 198 /* Read N bytes from infd into memory starting at address DEST. |
183 Return true if successful, false otherwise. */ | 199 Return true if successful, false otherwise. */ |
284 | 300 |
285 static void | 301 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); |
293 putchar ('\n'); | 309 putchar ('\n'); |
294 } | 310 } |
410 printf ("--- List of Regions to be Dumped ---\n"); | 426 printf ("--- List of Regions to be Dumped ---\n"); |
411 print_region_list (); | 427 print_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]; |
419 | 435 |
420 static void | 436 static void |
422 vm_range_t *ranges, unsigned num) | 438 vm_range_t *ranges, unsigned num) |
423 { | 439 { |
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 |
435 unexec_reader (task_t task, vm_address_t address, vm_size_t size, void **ptr) | 450 unexec_reader (task_t task, vm_address_t address, vm_size_t size, void **ptr) |
436 { | 451 { |
447 MALLOC_PTR_REGION_RANGE_TYPE | 462 MALLOC_PTR_REGION_RANGE_TYPE |
448 | MALLOC_ADMIN_REGION_RANGE_TYPE, | 463 | MALLOC_ADMIN_REGION_RANGE_TYPE, |
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 |
455 unexec_regions_sort_compare (const void *a, const void *b) | 473 unexec_regions_sort_compare (const void *a, const void *b) |
456 { | 474 { |
498 print_load_command_name (int lc) | 516 print_load_command_name (int lc) |
499 { | 517 { |
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 "); |
507 break; | 529 break; |
508 case LC_LOAD_DYLIB: | 530 case LC_LOAD_DYLIB: |
539 struct segment_command *scp; | 561 struct segment_command *scp; |
540 struct section *sectp; | 562 struct section *sectp; |
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 } |
555 else | 577 else |
556 printf ("\n"); | 578 printf ("\n"); |
642 struct segment_command *scp = (struct segment_command *) lc; | 664 struct segment_command *scp = (struct segment_command *) lc; |
643 unsigned long old_fileoff = scp->fileoff; | 665 unsigned long old_fileoff = scp->fileoff; |
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 |
665 curr_header_offset += lc->cmdsize; | 689 curr_header_offset += lc->cmdsize; |
666 } | 690 } |
683 struct segment_command *scp = (struct segment_command *) lc; | 707 struct segment_command *scp = (struct segment_command *) lc; |
684 struct section *sectp; | 708 struct section *sectp; |
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. */ |
697 header_offset = curr_header_offset + sizeof (struct segment_command); | 718 header_offset = curr_header_offset + sizeof (struct segment_command); |
698 | 719 |
699 sectp = (struct section *) (scp + 1); | 720 sectp = (struct section *) (scp + 1); |
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 |
707 other three kinds of sections are just copied from the input | 728 other three kinds of sections are just copied from the input |
708 file. */ | 729 file. */ |
760 unexec_error ("cannot write section %s's header", sectp->sectname); | 781 unexec_error ("cannot write section %s's header", sectp->sectname); |
761 } | 782 } |
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++; |
771 } | 792 } |
772 | 793 |
773 /* The new filesize of the segment is set to its vmsize because data | 794 /* The new filesize of the segment is set to its vmsize because data |
774 blocks for segments must start at region boundaries. Note that | 795 blocks for segments must start at region boundaries. Note that |
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; |
792 | 812 |
793 sc.cmd = LC_SEGMENT; | 813 sc.cmd = LC_SEGMENT; |
794 sc.cmdsize = sizeof (struct segment_command); | 814 sc.cmdsize = sizeof (struct segment_command); |
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"); |
816 curr_header_offset += sc.cmdsize; | 835 curr_header_offset += sc.cmdsize; |
817 mh.ncmds++; | 836 mh.ncmds++; |
819 } | 838 } |
820 | 839 |
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 |
828 stp->symoff += delta; | 847 stp->symoff += delta; |
829 stp->stroff += delta; | 848 stp->stroff += delta; |
896 } | 915 } |
897 | 916 |
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 |
905 unrelocate ("local", dstp->locreloff, dstp->nlocrel); | 924 unrelocate ("local", dstp->locreloff, dstp->nlocrel); |
906 unrelocate ("external", dstp->extreloff, dstp->nextrel); | 925 unrelocate ("external", dstp->extreloff, dstp->nextrel); |
925 } | 944 } |
926 | 945 |
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 |
934 if (tlhp->nhints > 0) { | 953 if (tlhp->nhints > 0) { |
935 tlhp->offset += delta; | 954 tlhp->offset += delta; |
962 header. */ | 981 header. */ |
963 static void | 982 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 |
970 for (i = 0; i < nlc; i++) | 990 for (i = 0; i < nlc; i++) |
971 switch (lca[i]->cmd) | 991 switch (lca[i]->cmd) |
975 struct segment_command *scp = (struct segment_command *) lca[i]; | 995 struct segment_command *scp = (struct segment_command *) lca[i]; |
976 if (strncmp (scp->segname, SEG_DATA, 16) == 0) | 996 if (strncmp (scp->segname, SEG_DATA, 16) == 0) |
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 |
983 copy_data_segment (lca[i]); | 1006 copy_data_segment (lca[i]); |
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]); |
1002 break; | 1033 break; |
1003 } | 1034 } |
1022 void *entry_address) | 1053 void *entry_address) |
1023 { | 1054 { |
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 { |
1030 unexec_error ("cannot open input file `%s'", infile); | 1062 unexec_error ("cannot open input file `%s'", infile); |
1031 } | 1063 } |