aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2006-11-05 06:12:27 +0000
committerYAMAMOTO Mitsuharu2006-11-05 06:12:27 +0000
commitc57038f815a155fd9ac557785bc44933473bdff2 (patch)
tree5aa13e3fda1ea0566373805619525163e85c7c21 /src
parent60a294e2e92457c71ea42069886cced6614da51e (diff)
downloademacs-c57038f815a155fd9ac557785bc44933473bdff2.tar.gz
emacs-c57038f815a155fd9ac557785bc44933473bdff2.zip
(malloc_cookie): Remove unused variable.
(region_list_head, region_list_tail, lca, nlc, infile_lc_highest_addr) (text_seg_lowest_offset, mh, curr_header_offset, infd, outfd) (emacs_zone, data_segment_old_fileoff, data_segment_scp) (num_unexec_regions, unexec_regions): Make variables static. (print_regions, find_emacs_zone_regions): Make static. (unexec_region_info): New typedef. (unexec_regions): Change type from vm_range_t[] to unexec_region_info[]. All uses changed. (unexec_regions_recorder): Subtract size of trailing null pages from filesize. Show filesize. (unexec_regions_merge): Don't merge if null pages of preceding region is not too small. Use long format in printf. (copy_segment, copy_data_segment): Show filesize. (copy_data_segment): Write filesize bytes of region data. Adjust filesize in segment command accordingly. (dump_it): Use long format in printf.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog20
-rw-r--r--src/unexmacosx.c133
2 files changed, 96 insertions, 57 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2f6cd216af3..20e26952b17 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,23 @@
12006-11-05 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2
3 * unexmacosx.c (malloc_cookie): Remove unused variable.
4 (region_list_head, region_list_tail, lca, nlc, infile_lc_highest_addr)
5 (text_seg_lowest_offset, mh, curr_header_offset, infd, outfd)
6 (emacs_zone, data_segment_old_fileoff, data_segment_scp)
7 (num_unexec_regions, unexec_regions): Make variables static.
8 (print_regions, find_emacs_zone_regions): Make static.
9 (unexec_region_info): New typedef.
10 (unexec_regions): Change type from vm_range_t[] to unexec_region_info[].
11 All uses changed.
12 (unexec_regions_recorder): Subtract size of trailing null pages from
13 filesize. Show filesize.
14 (unexec_regions_merge): Don't merge if null pages of preceding region
15 is not too small. Use long format in printf.
16 (copy_segment, copy_data_segment): Show filesize.
17 (copy_data_segment): Write filesize bytes of region data. Adjust
18 filesize in segment command accordingly.
19 (dump_it): Use long format in printf.
20
12006-11-05 Juanma Barranquero <lekktu@gmail.com> 212006-11-05 Juanma Barranquero <lekktu@gmail.com>
2 22
3 * dosfns.c (Finsert_startup_screen): 23 * dosfns.c (Finsert_startup_screen):
diff --git a/src/unexmacosx.c b/src/unexmacosx.c
index a1950f9445e..e95aa2f2efc 100644
--- a/src/unexmacosx.c
+++ b/src/unexmacosx.c
@@ -69,10 +69,10 @@ Boston, MA 02110-1301, USA. */
69 fact, the earliest one starts a few hundred bytes beyond the end of 69 fact, the earliest one starts a few hundred bytes beyond the end of
70 the last load command. The linker option -headerpad controls the 70 the last load command. The linker option -headerpad controls the
71 minimum size of this padding. Its setting can be changed in 71 minimum size of this padding. Its setting can be changed in
72 s/darwin.h. A value of 0x300, e.g., leaves room for about 15 72 s/darwin.h. A value of 0x690, e.g., leaves room for 30 additional
73 additional load commands for the newly created __DATA segments (at 73 load commands for the newly created __DATA segments (at 56 bytes
74 56 bytes each). Unexec fails if there is not enough room for these 74 each). Unexec fails if there is not enough room for these new
75 new segments. 75 segments.
76 76
77 The __TEXT segment contains the sections __text, __cstring, 77 The __TEXT segment contains the sections __text, __cstring,
78 __picsymbol_stub, and __const and the __DATA segment contains the 78 __picsymbol_stub, and __const and the __DATA segment contains the
@@ -137,9 +137,6 @@ Boston, MA 02110-1301, USA. */
137 mapped to dynamically loaded libraries and will not be dumped. */ 137 mapped to dynamically loaded libraries and will not be dumped. */
138#define VM_DATA_TOP (20 * 1024 * 1024) 138#define VM_DATA_TOP (20 * 1024 * 1024)
139 139
140/* Used by malloc_freezedry and malloc_jumpstart. */
141int malloc_cookie;
142
143/* Type of an element on the list of regions to be dumped. */ 140/* Type of an element on the list of regions to be dumped. */
144struct region_t { 141struct region_t {
145 vm_address_t address; 142 vm_address_t address;
@@ -151,32 +148,32 @@ struct region_t {
151}; 148};
152 149
153/* Head and tail of the list of regions to be dumped. */ 150/* Head and tail of the list of regions to be dumped. */
154struct region_t *region_list_head = 0; 151static struct region_t *region_list_head = 0;
155struct region_t *region_list_tail = 0; 152static struct region_t *region_list_tail = 0;
156 153
157/* Pointer to array of load commands. */ 154/* Pointer to array of load commands. */
158struct load_command **lca; 155static struct load_command **lca;
159 156
160/* Number of load commands. */ 157/* Number of load commands. */
161int nlc; 158static int nlc;
162 159
163/* The highest VM address of segments loaded by the input file. 160/* The highest VM address of segments loaded by the input file.
164 Regions with addresses beyond this are assumed to be allocated 161 Regions with addresses beyond this are assumed to be allocated
165 dynamically and thus require dumping. */ 162 dynamically and thus require dumping. */
166vm_address_t infile_lc_highest_addr = 0; 163static vm_address_t infile_lc_highest_addr = 0;
167 164
168/* The lowest file offset used by the all sections in the __TEXT 165/* The lowest file offset used by the all sections in the __TEXT
169 segments. This leaves room at the beginning of the file to store 166 segments. This leaves room at the beginning of the file to store
170 the Mach-O header. Check this value against header size to ensure 167 the Mach-O header. Check this value against header size to ensure
171 the added load commands for the new __DATA segments did not 168 the added load commands for the new __DATA segments did not
172 overwrite any of the sections in the __TEXT segment. */ 169 overwrite any of the sections in the __TEXT segment. */
173unsigned long text_seg_lowest_offset = 0x10000000; 170static unsigned long text_seg_lowest_offset = 0x10000000;
174 171
175/* Mach header. */ 172/* Mach header. */
176struct mach_header mh; 173static struct mach_header mh;
177 174
178/* Offset at which the next load command should be written. */ 175/* Offset at which the next load command should be written. */
179unsigned long curr_header_offset = sizeof (struct mach_header); 176static unsigned long curr_header_offset = sizeof (struct mach_header);
180 177
181/* Offset at which the next segment should be written. */ 178/* Offset at which the next segment should be written. */
182static unsigned long curr_file_offset = 0; 179static unsigned long curr_file_offset = 0;
@@ -184,16 +181,16 @@ static unsigned long curr_file_offset = 0;
184static unsigned long pagesize; 181static unsigned long pagesize;
185#define ROUNDUP_TO_PAGE_BOUNDARY(x) (((x) + pagesize - 1) & ~(pagesize - 1)) 182#define ROUNDUP_TO_PAGE_BOUNDARY(x) (((x) + pagesize - 1) & ~(pagesize - 1))
186 183
187int infd, outfd; 184static int infd, outfd;
188 185
189int in_dumped_exec = 0; 186static int in_dumped_exec = 0;
190 187
191malloc_zone_t *emacs_zone; 188static malloc_zone_t *emacs_zone;
192 189
193/* file offset of input file's data segment */ 190/* file offset of input file's data segment */
194off_t data_segment_old_fileoff = 0; 191static off_t data_segment_old_fileoff = 0;
195 192
196struct segment_command *data_segment_scp; 193static struct segment_command *data_segment_scp;
197 194
198/* Read N bytes from infd into memory starting at address DEST. 195/* Read N bytes from infd into memory starting at address DEST.
199 Return true if successful, false otherwise. */ 196 Return true if successful, false otherwise. */
@@ -320,7 +317,7 @@ print_region_list ()
320 print_region (r->address, r->size, r->protection, r->max_protection); 317 print_region (r->address, r->size, r->protection, r->max_protection);
321} 318}
322 319
323void 320static void
324print_regions () 321print_regions ()
325{ 322{
326 task_t target_task = mach_task_self (); 323 task_t target_task = mach_task_self ();
@@ -430,18 +427,36 @@ build_region_list ()
430 427
431#define MAX_UNEXEC_REGIONS 400 428#define MAX_UNEXEC_REGIONS 400
432 429
433int num_unexec_regions; 430static int num_unexec_regions;
434vm_range_t unexec_regions[MAX_UNEXEC_REGIONS]; 431typedef struct {
432 vm_range_t range;
433 vm_size_t filesize;
434} unexec_region_info;
435static unexec_region_info unexec_regions[MAX_UNEXEC_REGIONS];
435 436
436static void 437static void
437unexec_regions_recorder (task_t task, void *rr, unsigned type, 438unexec_regions_recorder (task_t task, void *rr, unsigned type,
438 vm_range_t *ranges, unsigned num) 439 vm_range_t *ranges, unsigned num)
439{ 440{
441 vm_address_t p;
442 vm_size_t filesize;
443
440 while (num && num_unexec_regions < MAX_UNEXEC_REGIONS) 444 while (num && num_unexec_regions < MAX_UNEXEC_REGIONS)
441 { 445 {
442 unexec_regions[num_unexec_regions++] = *ranges; 446 /* Subtract the size of trailing null pages from filesize. It
443 printf ("%#8lx (sz: %#8lx)\n", 447 can be smaller than vmsize in segment commands. In such a
444 (long) (ranges->address), (long) (ranges->size)); 448 case, trailing pages are initialized with zeros. */
449 for (p = ranges->address + ranges->size; p > ranges->address;
450 p -= sizeof (int))
451 if (*(((int *) p)-1))
452 break;
453 filesize = ROUNDUP_TO_PAGE_BOUNDARY (p - ranges->address);
454 assert (filesize <= ranges->size);
455
456 unexec_regions[num_unexec_regions].filesize = filesize;
457 unexec_regions[num_unexec_regions++].range = *ranges;
458 printf ("%#10lx (sz: %#8lx/%#8lx)\n", (long) (ranges->address),
459 (long) filesize, (long) (ranges->size));
445 ranges++; num--; 460 ranges++; num--;
446 } 461 }
447} 462}
@@ -453,7 +468,7 @@ unexec_reader (task_t task, vm_address_t address, vm_size_t size, void **ptr)
453 return KERN_SUCCESS; 468 return KERN_SUCCESS;
454} 469}
455 470
456void 471static void
457find_emacs_zone_regions () 472find_emacs_zone_regions ()
458{ 473{
459 num_unexec_regions = 0; 474 num_unexec_regions = 0;
@@ -472,8 +487,8 @@ find_emacs_zone_regions ()
472static int 487static int
473unexec_regions_sort_compare (const void *a, const void *b) 488unexec_regions_sort_compare (const void *a, const void *b)
474{ 489{
475 vm_address_t aa = ((vm_range_t *) a)->address; 490 vm_address_t aa = ((unexec_region_info *) a)->range.address;
476 vm_address_t bb = ((vm_range_t *) b)->address; 491 vm_address_t bb = ((unexec_region_info *) b)->range.address;
477 492
478 if (aa < bb) 493 if (aa < bb)
479 return -1; 494 return -1;
@@ -487,7 +502,7 @@ static void
487unexec_regions_merge () 502unexec_regions_merge ()
488{ 503{
489 int i, n; 504 int i, n;
490 vm_range_t r; 505 unexec_region_info r;
491 506
492 qsort (unexec_regions, num_unexec_regions, sizeof (unexec_regions[0]), 507 qsort (unexec_regions, num_unexec_regions, sizeof (unexec_regions[0]),
493 &unexec_regions_sort_compare); 508 &unexec_regions_sort_compare);
@@ -495,9 +510,11 @@ unexec_regions_merge ()
495 r = unexec_regions[0]; 510 r = unexec_regions[0];
496 for (i = 1; i < num_unexec_regions; i++) 511 for (i = 1; i < num_unexec_regions; i++)
497 { 512 {
498 if (r.address + r.size == unexec_regions[i].address) 513 if (r.range.address + r.range.size == unexec_regions[i].range.address
514 && r.range.size - r.filesize < 2 * pagesize)
499 { 515 {
500 r.size += unexec_regions[i].size; 516 r.filesize = r.range.size + unexec_regions[i].filesize;
517 r.range.size += unexec_regions[i].range.size;
501 } 518 }
502 else 519 else
503 { 520 {
@@ -642,7 +659,7 @@ read_load_commands ()
642 printf ("Highest address of load commands in input file: %#8x\n", 659 printf ("Highest address of load commands in input file: %#8x\n",
643 infile_lc_highest_addr); 660 infile_lc_highest_addr);
644 661
645 printf ("Lowest offset of all sections in __TEXT segment: %#8x\n", 662 printf ("Lowest offset of all sections in __TEXT segment: %#8lx\n",
646 text_seg_lowest_offset); 663 text_seg_lowest_offset);
647 664
648 printf ("--- List of Load Commands in Input File ---\n"); 665 printf ("--- List of Load Commands in Input File ---\n");
@@ -675,9 +692,9 @@ copy_segment (struct load_command *lc)
675 sectp++; 692 sectp++;
676 } 693 }
677 694
678 printf ("Writing segment %-16.16s @ %#8lx (%#8lx @ %#8lx)\n", 695 printf ("Writing segment %-16.16s @ %#8lx (%#8lx/%#8lx @ %#10lx)\n",
679 scp->segname, (long) (scp->fileoff), (long) (scp->vmsize), 696 scp->segname, (long) (scp->fileoff), (long) (scp->filesize),
680 (long) (scp->vmaddr)); 697 (long) (scp->vmsize), (long) (scp->vmaddr));
681 698
682 if (!unexec_copy (scp->fileoff, old_fileoff, scp->filesize)) 699 if (!unexec_copy (scp->fileoff, old_fileoff, scp->filesize))
683 unexec_error ("cannot copy segment from input to output file"); 700 unexec_error ("cannot copy segment from input to output file");
@@ -707,11 +724,18 @@ copy_data_segment (struct load_command *lc)
707 struct segment_command *scp = (struct segment_command *) lc; 724 struct segment_command *scp = (struct segment_command *) lc;
708 struct section *sectp; 725 struct section *sectp;
709 int j; 726 int j;
710 unsigned long header_offset, file_offset, old_file_offset; 727 unsigned long header_offset, old_file_offset;
728
729 /* The new filesize of the segment is set to its vmsize because data
730 blocks for segments must start at region boundaries. Note that
731 this may leave unused locations at the end of the segment data
732 block because the total of the sizes of all sections in the
733 segment is generally smaller than vmsize. */
734 scp->filesize = scp->vmsize;
711 735
712 printf ("Writing segment %-16.16s @ %#8lx (%#8lx @ %#8lx)\n", 736 printf ("Writing segment %-16.16s @ %#8lx (%#8lx/%#8lx @ %#10lx)\n",
713 scp->segname, curr_file_offset, (long)(scp->vmsize), 737 scp->segname, curr_file_offset, (long)(scp->filesize),
714 (long) (scp->vmaddr)); 738 (long)(scp->vmsize), (long) (scp->vmaddr));
715 739
716 /* Offsets in the output file for writing the next section structure 740 /* Offsets in the output file for writing the next section structure
717 and segment data block, respectively. */ 741 and segment data block, respectively. */
@@ -791,16 +815,11 @@ copy_data_segment (struct load_command *lc)
791 sectp++; 815 sectp++;
792 } 816 }
793 817
794 /* The new filesize of the segment is set to its vmsize because data 818 curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (scp->filesize);
795 blocks for segments must start at region boundaries. Note that 819
796 this may leave unused locations at the end of the segment data
797 block because the total of the sizes of all sections in the
798 segment is generally smaller than vmsize. */
799 scp->filesize = scp->vmsize;
800 if (!unexec_write (curr_header_offset, scp, sizeof (struct segment_command))) 820 if (!unexec_write (curr_header_offset, scp, sizeof (struct segment_command)))
801 unexec_error ("cannot write header of __DATA segment"); 821 unexec_error ("cannot write header of __DATA segment");
802 curr_header_offset += lc->cmdsize; 822 curr_header_offset += lc->cmdsize;
803 curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (scp->filesize);
804 823
805 /* Create new __DATA segment load commands for regions on the region 824 /* Create new __DATA segment load commands for regions on the region
806 list that do not corresponding to any segment load commands in 825 list that do not corresponding to any segment load commands in
@@ -813,20 +832,20 @@ copy_data_segment (struct load_command *lc)
813 sc.cmd = LC_SEGMENT; 832 sc.cmd = LC_SEGMENT;
814 sc.cmdsize = sizeof (struct segment_command); 833 sc.cmdsize = sizeof (struct segment_command);
815 strncpy (sc.segname, SEG_DATA, 16); 834 strncpy (sc.segname, SEG_DATA, 16);
816 sc.vmaddr = unexec_regions[j].address; 835 sc.vmaddr = unexec_regions[j].range.address;
817 sc.vmsize = unexec_regions[j].size; 836 sc.vmsize = unexec_regions[j].range.size;
818 sc.fileoff = curr_file_offset; 837 sc.fileoff = curr_file_offset;
819 sc.filesize = unexec_regions[j].size; 838 sc.filesize = unexec_regions[j].filesize;
820 sc.maxprot = VM_PROT_READ | VM_PROT_WRITE; 839 sc.maxprot = VM_PROT_READ | VM_PROT_WRITE;
821 sc.initprot = VM_PROT_READ | VM_PROT_WRITE; 840 sc.initprot = VM_PROT_READ | VM_PROT_WRITE;
822 sc.nsects = 0; 841 sc.nsects = 0;
823 sc.flags = 0; 842 sc.flags = 0;
824 843
825 printf ("Writing segment %-16.16s @ %#8lx (%#8lx @ %#8lx)\n", 844 printf ("Writing segment %-16.16s @ %#8lx (%#8lx/%#8lx @ %#10lx)\n",
826 sc.segname, (long) (sc.fileoff), (long) (sc.vmsize), 845 sc.segname, (long) (sc.fileoff), (long) (sc.filesize),
827 (long) (sc.vmaddr)); 846 (long) (sc.vmsize), (long) (sc.vmaddr));
828 847
829 if (!unexec_write (sc.fileoff, (void *) sc.vmaddr, sc.vmsize)) 848 if (!unexec_write (sc.fileoff, (void *) sc.vmaddr, sc.filesize))
830 unexec_error ("cannot write new __DATA segment"); 849 unexec_error ("cannot write new __DATA segment");
831 curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (sc.filesize); 850 curr_file_offset += ROUNDUP_TO_PAGE_BOUNDARY (sc.filesize);
832 851
@@ -1036,7 +1055,7 @@ dump_it ()
1036 if (curr_header_offset > text_seg_lowest_offset) 1055 if (curr_header_offset > text_seg_lowest_offset)
1037 unexec_error ("not enough room for load commands for new __DATA segments"); 1056 unexec_error ("not enough room for load commands for new __DATA segments");
1038 1057
1039 printf ("%d unused bytes follow Mach-O header\n", 1058 printf ("%ld unused bytes follow Mach-O header\n",
1040 text_seg_lowest_offset - curr_header_offset); 1059 text_seg_lowest_offset - curr_header_offset);
1041 1060
1042 mh.sizeofcmds = curr_header_offset - sizeof (struct mach_header); 1061 mh.sizeofcmds = curr_header_offset - sizeof (struct mach_header);
@@ -1113,8 +1132,8 @@ ptr_in_unexec_regions (void *ptr)
1113 int i; 1132 int i;
1114 1133
1115 for (i = 0; i < num_unexec_regions; i++) 1134 for (i = 0; i < num_unexec_regions; i++)
1116 if ((vm_address_t) ptr - unexec_regions[i].address 1135 if ((vm_address_t) ptr - unexec_regions[i].range.address
1117 < unexec_regions[i].size) 1136 < unexec_regions[i].range.size)
1118 return 1; 1137 return 1;
1119 1138
1120 return 0; 1139 return 0;