comparison src/unexec.c @ 109591:1fb35da4a097

Merge from mainline.
author Katsumi Yamaoka <yamaoka@jpl.org>
date Thu, 29 Jul 2010 23:01:42 +0000
parents 88810df348ab
children
comparison
equal deleted inserted replaced
109590:3c9de3b961fe 109591:1fb35da4a097
46 * The value you specify may be rounded down to a suitable boundary 46 * The value you specify may be rounded down to a suitable boundary
47 * as required by the machine you are using. 47 * as required by the machine you are using.
48 * 48 *
49 * Specifying zero for data_start means the boundary between text and data 49 * Specifying zero for data_start means the boundary between text and data
50 * should not be the same as when the program was loaded. 50 * should not be the same as when the program was loaded.
51 * If NO_REMAP is defined, the argument data_start is ignored and the
52 * segment boundaries are never changed.
53 * 51 *
54 * Bss_start indicates how much of the data segment is to be saved in the 52 * Bss_start indicates how much of the data segment is to be saved in the
55 * a.out file and restored when the program is executed. It gives the lowest 53 * a.out file and restored when the program is executed. It gives the lowest
56 * unsaved address, and is rounded up to a page boundary. The default when 0 54 * unsaved address, and is rounded up to a page boundary. The default when 0
57 * is given assumes that the entire data segment is to be stored, including 55 * is given assumes that the entire data segment is to be stored, including
66 */ 64 */
67 65
68 /* Modified to support SysVr3 shared libraries by James Van Artsdalen 66 /* Modified to support SysVr3 shared libraries by James Van Artsdalen
69 * of Dell Computer Corporation. james@bigtex.cactus.org. 67 * of Dell Computer Corporation. james@bigtex.cactus.org.
70 */ 68 */
71
72 /* There are several compilation parameters affecting unexec:
73
74 * COFF
75
76 Define this if your system uses COFF for executables.
77
78 * NO_REMAP
79
80 Define this if you do not want to try to save Emacs's pure data areas
81 as part of the text segment.
82
83 Saving them as text is good because it allows users to share more.
84
85 However, on machines that locate the text area far from the data area,
86 the boundary cannot feasibly be moved. Such machines require
87 NO_REMAP.
88
89 Also, remapping can cause trouble with the built-in startup routine
90 /lib/crt0.o, which defines `environ' as an initialized variable.
91 Dumping `environ' as pure does not work! So, to use remapping,
92 you must write a startup routine for your machine in Emacs's crt0.c.
93 If NO_REMAP is defined, Emacs uses the system's crt0.o.
94
95 * SECTION_ALIGNMENT
96
97 Some machines that use COFF executables require that each section
98 start on a certain boundary *in the COFF file*. Such machines should
99 define SECTION_ALIGNMENT to a mask of the low-order bits that must be
100 zero on such a boundary. This mask is used to control padding between
101 segments in the COFF file.
102
103 If SECTION_ALIGNMENT is not defined, the segments are written
104 consecutively with no attempt at alignment. This is right for
105 unmodified system V.
106
107 * SEGMENT_MASK
108
109 Some machines require that the beginnings and ends of segments
110 *in core* be on certain boundaries. For most machines, a page
111 boundary is sufficient. That is the default. When a larger
112 boundary is needed, define SEGMENT_MASK to a mask of
113 the bits that must be zero on such a boundary.
114
115 * ADJUST_EXEC_HEADER
116
117 This macro can be used to generate statements to adjust or
118 initialize nonstandard fields in the file header
119
120 */
121 69
122 #ifndef emacs 70 #ifndef emacs
123 #define PERROR(arg) perror (arg); return -1 71 #define PERROR(arg) perror (arg); return -1
124 #else 72 #else
125 #include <config.h> 73 #include <config.h>
262 unsigned int bss_end; 210 unsigned int bss_end;
263 211
264 pagemask = getpagesize () - 1; 212 pagemask = getpagesize () - 1;
265 213
266 /* Adjust text/data boundary. */ 214 /* Adjust text/data boundary. */
267 #ifdef NO_REMAP
268 data_start = (int) start_of_data (); 215 data_start = (int) start_of_data ();
269 #else /* not NO_REMAP */
270 if (!data_start)
271 data_start = (int) start_of_data ();
272 #endif /* not NO_REMAP */
273 data_start = ADDR_CORRECT (data_start); 216 data_start = ADDR_CORRECT (data_start);
274
275 #ifdef SEGMENT_MASK
276 data_start = data_start & ~SEGMENT_MASK; /* (Down) to segment boundary. */
277 #else
278 data_start = data_start & ~pagemask; /* (Down) to page boundary. */ 217 data_start = data_start & ~pagemask; /* (Down) to page boundary. */
279 #endif
280 218
281 bss_end = ADDR_CORRECT (sbrk (0)) + pagemask; 219 bss_end = ADDR_CORRECT (sbrk (0)) + pagemask;
282 bss_end &= ~ pagemask; 220 bss_end &= ~ pagemask;
283 221
284 /* Adjust data/bss boundary. */ 222 /* Adjust data/bss boundary. */
372 310
373 /* Now we alter the contents of all the f_*hdr variables 311 /* Now we alter the contents of all the f_*hdr variables
374 to correspond to what we want to dump. */ 312 to correspond to what we want to dump. */
375 313
376 f_hdr.f_flags |= (F_RELFLG | F_EXEC); 314 f_hdr.f_flags |= (F_RELFLG | F_EXEC);
377 #ifndef NO_REMAP
378 f_ohdr.text_start = (long) start_of_text (); 315 f_ohdr.text_start = (long) start_of_text ();
379 f_ohdr.tsize = data_start - f_ohdr.text_start; 316 f_ohdr.tsize = data_start - f_ohdr.text_start;
380 f_ohdr.data_start = data_start; 317 f_ohdr.data_start = data_start;
381 #endif /* NO_REMAP */
382 f_ohdr.dsize = bss_start - f_ohdr.data_start; 318 f_ohdr.dsize = bss_start - f_ohdr.data_start;
383 f_ohdr.bsize = bss_end - bss_start; 319 f_ohdr.bsize = bss_end - bss_start;
384 /* On some machines, the old values are right.
385 ??? Maybe on all machines with NO_REMAP. */
386 f_thdr.s_size = f_ohdr.tsize; 320 f_thdr.s_size = f_ohdr.tsize;
387 f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr); 321 f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr);
388 f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr)); 322 f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr));
389 lnnoptr = f_thdr.s_lnnoptr; 323 lnnoptr = f_thdr.s_lnnoptr;
390 #ifdef SECTION_ALIGNMENT
391 /* Some systems require special alignment
392 of the sections in the file itself. */
393 f_thdr.s_scnptr
394 = (f_thdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
395 #endif /* SECTION_ALIGNMENT */
396 text_scnptr = f_thdr.s_scnptr; 324 text_scnptr = f_thdr.s_scnptr;
397 f_dhdr.s_paddr = f_ohdr.data_start; 325 f_dhdr.s_paddr = f_ohdr.data_start;
398 f_dhdr.s_vaddr = f_ohdr.data_start; 326 f_dhdr.s_vaddr = f_ohdr.data_start;
399 f_dhdr.s_size = f_ohdr.dsize; 327 f_dhdr.s_size = f_ohdr.dsize;
400 f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size; 328 f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size;
401 #ifdef SECTION_ALIGNMENT
402 /* Some systems require special alignment
403 of the sections in the file itself. */
404 f_dhdr.s_scnptr
405 = (f_dhdr.s_scnptr + SECTION_ALIGNMENT) & ~SECTION_ALIGNMENT;
406 #endif /* SECTION_ALIGNMENT */
407 #ifdef DATA_SECTION_ALIGNMENT
408 /* Some systems require special alignment
409 of the data section only. */
410 f_dhdr.s_scnptr
411 = (f_dhdr.s_scnptr + DATA_SECTION_ALIGNMENT) & ~DATA_SECTION_ALIGNMENT;
412 #endif /* DATA_SECTION_ALIGNMENT */
413 data_scnptr = f_dhdr.s_scnptr; 329 data_scnptr = f_dhdr.s_scnptr;
414 f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize; 330 f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize;
415 f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize; 331 f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
416 f_bhdr.s_size = f_ohdr.bsize; 332 f_bhdr.s_size = f_ohdr.bsize;
417 f_bhdr.s_scnptr = 0L; 333 f_bhdr.s_scnptr = 0L;
424 340
425 if (f_thdr.s_lnnoptr > 0L) 341 if (f_thdr.s_lnnoptr > 0L)
426 { 342 {
427 f_thdr.s_lnnoptr += bias; 343 f_thdr.s_lnnoptr += bias;
428 } 344 }
429
430 #ifdef ADJUST_EXEC_HEADER
431 ADJUST_EXEC_HEADER;
432 #endif /* ADJUST_EXEC_HEADER */
433 345
434 if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) 346 if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
435 { 347 {
436 PERROR (new_name); 348 PERROR (new_name);
437 } 349 }