Mercurial > hg > xemacs-beta
annotate src/unexcw.c @ 5781:0853e1ec8529
Use alloca_{rawbytes,ibytes} in #'copy-file, #'insert-file-contents-internal
src/ChangeLog addition:
2014-01-20 Aidan Kehoe <kehoea@parhasard.net>
* fileio.c (Fcopy_file, Finsert_file_contents_internal):
Use alloca_{rawbytes,ibytes} here instead of the implicit alloca
on the stack; doesn't change where the buffers are allocated for
these two functions, but does mean that decisions about alloca
vs. malloc based on buffer size are made in the same place
(ultimately, the ALLOCA() macro).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Mon, 20 Jan 2014 17:53:07 +0000 |
parents | 4dee0387b9de |
children | 574f0cded429 |
rev | line source |
---|---|
613 | 1 /* unexec for XEmacs on Cygwin32. |
428 | 2 Copyright (C) 1994, 1998 Free Software Foundation, Inc. |
3 | |
4 This file is part of XEmacs. | |
5 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4854
diff
changeset
|
6 XEmacs is free software: you can redistribute it and/or modify it |
428 | 7 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4854
diff
changeset
|
8 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4854
diff
changeset
|
9 option) any later version. |
428 | 10 |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4854
diff
changeset
|
17 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 18 |
19 /* This is a complete rewrite, some code snarfed from unexnt.c and | |
20 unexec.c, Andy Piper (andy@xemacs.org) 13-1-98 */ | |
21 | |
448 | 22 #include <config.h> |
23 #include "lisp.h" | |
24 | |
428 | 25 #include "sysfile.h" |
442 | 26 |
546 | 27 #define PERROR(arg) \ |
28 do { \ | |
29 perror (arg); \ | |
30 exit (-1); \ | |
31 } while (0) | |
428 | 32 |
546 | 33 #if !defined (HAVE_A_OUT_H) && !defined (WIN32_NATIVE) |
428 | 34 unexec (char *, char *, void *, void *, void *) |
35 { | |
647 | 36 PERROR ("cannot unexec() a.out.h not installed"); |
428 | 37 } |
38 #else | |
39 | |
546 | 40 #ifdef MINGW |
41 #include <../../include/a.out.h> | |
42 #else | |
428 | 43 #include <a.out.h> |
546 | 44 #endif |
428 | 45 |
1198 | 46 #define STACK_SIZE 0x800000 |
428 | 47 #define ALLOC_UNIT 0xFFFF |
647 | 48 #define ALLOC_MASK ~((unsigned long) (ALLOC_UNIT)) |
428 | 49 #define ALIGN_ALLOC(addr) \ |
647 | 50 ((((unsigned long) addr) + ALLOC_UNIT) & ALLOC_MASK) |
444 | 51 /* Note that all sections must be aligned on a 0x1000 boundary so |
52 this is the minimum size that our dummy bss can be. */ | |
448 | 53 #ifndef NO_DEBUG |
444 | 54 #define BSS_PAD_SIZE 0x1000 |
446 | 55 #else |
56 #define BSS_PAD_SIZE 0 | |
57 #endif | |
428 | 58 |
59 /* To prevent zero-initialized variables from being placed into the bss | |
60 section, use non-zero values to represent an uninitialized state. */ | |
61 #define UNINIT_PTR ((void *) 0xF0A0F0A0) | |
62 #define UNINIT_LONG (0xF0A0F0A0L) | |
63 | |
64 static void get_section_info (int a_out, char* a_name); | |
65 static void copy_executable_and_dump_data_section (int a_out, int a_new); | |
647 | 66 static void dup_file_area (int a_out, int a_new, long size); |
428 | 67 #if 0 |
647 | 68 static void write_int_to_bss (int a_out, int a_new, void* va, void* newval); |
428 | 69 #endif |
70 | |
71 /* Cached info about the .data section in the executable. */ | |
647 | 72 void *data_start_va = UNINIT_PTR; |
73 long data_size = UNINIT_LONG; | |
428 | 74 |
75 /* Cached info about the .bss section in the executable. */ | |
647 | 76 void *bss_start = UNINIT_PTR; |
77 long bss_size = UNINIT_LONG; | |
428 | 78 int sections_reversed = 0; |
79 FILHDR f_hdr; | |
80 PEAOUTHDR f_ohdr; | |
81 SCNHDR f_data, f_bss, f_text, f_nextdata; | |
82 | |
1685 | 83 #define CHECK_AOUT_POS(a) \ |
84 do { \ | |
85 if (lseek (a_out, 0, SEEK_CUR) != a) \ | |
86 { \ | |
87 printf ("we are at %lx, should be at %lx\n", \ | |
88 (unsigned long) lseek (a_out, 0, SEEK_CUR), \ | |
89 (unsigned long) (a)); \ | |
90 exit (-1); \ | |
91 } \ | |
647 | 92 } while (0) |
428 | 93 |
94 /* Dump out .data and .bss sections into a new executable. */ | |
448 | 95 int |
2286 | 96 unexec (char *out_name, char *in_name, uintptr_t UNUSED (start_data), |
97 uintptr_t UNUSED (d1), uintptr_t UNUSED (d2)) | |
428 | 98 { |
99 /* ugly nt hack - should be in lisp */ | |
100 int a_new, a_out = -1; | |
4854 | 101 char new_name[PATH_MAX_TCHAR], a_name[PATH_MAX_TCHAR]; |
428 | 102 char *ptr; |
103 | |
104 /* Make sure that the input and output filenames have the | |
105 ".exe" extension...patch them up if they don't. */ | |
106 strcpy (a_name, in_name); | |
107 ptr = a_name + strlen (a_name) - 4; | |
108 if (strcmp (ptr, ".exe")) | |
109 strcat (a_name, ".exe"); | |
110 | |
111 strcpy (new_name, out_name); | |
112 ptr = new_name + strlen (new_name) - 4; | |
113 if (strcmp (ptr, ".exe")) | |
114 strcat (new_name, ".exe"); | |
115 | |
116 /* We need to round off our heap to NT's allocation unit (64KB). */ | |
117 /* round_heap (get_allocation_unit ()); */ | |
118 | |
119 if (a_name && (a_out = open (a_name, O_RDONLY | OPEN_BINARY)) < 0) | |
558 | 120 PERROR (a_name); |
428 | 121 |
122 if ((a_new = open (new_name, O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, | |
446 | 123 0755)) < 0) |
558 | 124 PERROR (new_name); |
428 | 125 |
126 /* Get the interesting section info, like start and size of .bss... */ | |
127 get_section_info (a_out, a_name); | |
128 | |
129 copy_executable_and_dump_data_section (a_out, a_new); | |
130 | |
647 | 131 close (a_out); |
132 close (a_new); | |
448 | 133 return 0; |
428 | 134 } |
135 | |
136 /* Flip through the executable and cache the info necessary for dumping. */ | |
558 | 137 static void |
138 get_section_info (int a_out, char* a_name) | |
428 | 139 { |
448 | 140 extern char my_ebss[]; |
428 | 141 /* From lastfile.c */ |
142 extern char my_edata[]; | |
143 | |
144 if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) | |
558 | 145 PERROR (a_name); |
428 | 146 |
147 if (f_hdr.e_magic != DOSMAGIC) | |
647 | 148 PERROR ("unknown exe header"); |
428 | 149 |
150 /* Check the NT header signature ... */ | |
151 if (f_hdr.nt_signature != NT_SIGNATURE) | |
647 | 152 PERROR ("invalid nt header"); |
428 | 153 |
154 /* Flip through the sections for .data and .bss ... */ | |
155 if (f_hdr.f_opthdr > 0) | |
156 { | |
157 if (read (a_out, &f_ohdr, AOUTSZ) != AOUTSZ) | |
558 | 158 PERROR (a_name); |
428 | 159 } |
160 /* Loop through .data & .bss section headers, copying them in. | |
161 With newer lds these are reversed so we have to cope with both */ | |
162 lseek (a_out, sizeof (f_hdr) + f_hdr.f_opthdr, 0); | |
163 | |
164 if (read (a_out, &f_text, sizeof (f_text)) != sizeof (f_text) | |
558 | 165 || strcmp (f_text.s_name, ".text")) |
166 PERROR ("no .text section"); | |
428 | 167 |
168 /* The .bss section. */ | |
169 if (read (a_out, &f_bss, sizeof (f_bss)) != sizeof (f_bss) | |
558 | 170 || (strcmp (f_bss.s_name, ".bss") && strcmp (f_bss.s_name, ".data"))) |
171 PERROR ("no .bss / .data section"); | |
428 | 172 |
173 /* check for reversed .bss and .data */ | |
647 | 174 if (!strcmp (f_bss.s_name, ".data")) |
428 | 175 { |
647 | 176 printf (".data and .bss reversed\n"); |
428 | 177 sections_reversed = 1; |
647 | 178 memcpy (&f_data, &f_bss, sizeof (f_bss)); |
428 | 179 } |
180 | |
181 /* The .data section. */ | |
182 if (!sections_reversed) | |
183 { | |
184 if (read (a_out, &f_data, sizeof (f_data)) != sizeof (f_data) | |
558 | 185 || strcmp (f_data.s_name, ".data")) |
186 PERROR ("no .data section"); | |
428 | 187 } |
188 else | |
189 { | |
190 if (read (a_out, &f_bss, sizeof (f_bss)) != sizeof (f_bss) | |
558 | 191 || strcmp (f_bss.s_name, ".bss")) |
192 PERROR ("no .bss section"); | |
428 | 193 } |
194 | |
195 bss_start = (void *) ((char*)f_ohdr.ImageBase + f_bss.s_vaddr); | |
196 bss_size = (unsigned long)((char*)&my_ebss-(char*)bss_start); | |
197 | |
198 /* must keep bss data that we want to be blank as blank */ | |
647 | 199 printf ("found bss - keeping %lx of %lx bytes\n", bss_size, f_ohdr.bsize); |
428 | 200 |
201 /* The .data section. */ | |
202 data_start_va = (void *) ((char*)f_ohdr.ImageBase + f_data.s_vaddr); | |
203 | |
204 /* We want to only write Emacs data back to the executable, | |
205 not any of the library data (if library data is included, | |
206 then a dumped Emacs won't run on system versions other | |
207 than the one Emacs was dumped on). */ | |
208 data_size = (unsigned long)my_edata - (unsigned long)data_start_va; | |
647 | 209 printf ("found data - keeping %lx of %lx bytes\n", data_size, f_ohdr.dsize); |
428 | 210 |
211 /* The following data section - often .idata */ | |
212 if (read (a_out, &f_nextdata, sizeof (f_nextdata)) != sizeof (f_nextdata) | |
647 | 213 && strcmp (&f_nextdata.s_name[2], "data")) |
558 | 214 PERROR ("no other data section"); |
428 | 215 } |
216 | |
217 /* The dump routines. */ | |
218 | |
219 static void | |
220 copy_executable_and_dump_data_section (int a_out, int a_new) | |
221 { | |
647 | 222 long size = 0; |
223 /* NOTE: Some of these were previously declared as unsigned long, | |
224 but the ones changed to long represent file sizes or pointers, | |
225 which can't reasonably get above 2G. (A 2G executable???) | |
226 Furthermore, some were even being compared as in if (x < 0) ... */ | |
227 long new_data_size, new_bss_size, bss_padding, file_sz_change; | |
228 long data_padding = 0; | |
229 long f_data_s_scnptr = f_data.s_scnptr; | |
230 long f_nextdata_s_scnptr = f_nextdata.s_scnptr; | |
231 unsigned long f_data_s_vaddr = f_data.s_vaddr; | |
232 unsigned long f_bss_s_vaddr = f_bss.s_vaddr; | |
428 | 233 |
234 int i; | |
235 void* empty_space; | |
236 extern int static_heap_dumped; | |
237 SCNHDR section; | |
444 | 238 /* calculate new sizes: |
558 | 239 |
444 | 240 f_ohdr.dsize is the total initialized data size on disk which is |
241 f_data.s_size + f_idata.s_size. | |
558 | 242 |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
4854
diff
changeset
|
243 f_ohdr.data_start is the base address of all data and so should |
444 | 244 not be changed. |
245 | |
246 *.s_vaddr is the virtual address of the start of the section | |
247 *normalized from f_ohdr.ImageBase. | |
558 | 248 |
444 | 249 *.s_paddr appears to be the number of bytes in the section |
250 *actually used (whereas *.s_size is aligned). | |
558 | 251 |
428 | 252 bsize is now 0 since subsumed into .data |
253 dsize is dsize + (f_data.s_vaddr - f_bss.s_vaddr) | |
254 f_data.s_vaddr is f_bss.s_vaddr | |
255 f_data.s_size is new dsize maybe. | |
256 what about s_paddr & s_scnptr? */ | |
257 | |
258 /* this is the amount the file increases in size */ | |
259 if (!sections_reversed) | |
260 { | |
261 new_bss_size = f_data.s_vaddr - f_bss.s_vaddr; | |
262 data_padding = 0; | |
263 } | |
264 else | |
265 { | |
266 new_bss_size = f_nextdata.s_vaddr - f_bss.s_vaddr; | |
267 data_padding = (f_bss.s_vaddr - f_data.s_vaddr) - f_data.s_size; | |
268 } | |
269 | |
448 | 270 if ((new_bss_size - bss_size) < BSS_PAD_SIZE) |
558 | 271 PERROR (".bss free space too small"); |
448 | 272 |
647 | 273 file_sz_change = (new_bss_size + data_padding) - BSS_PAD_SIZE; |
274 new_data_size = f_ohdr.dsize + file_sz_change; | |
428 | 275 |
276 if (!sections_reversed) | |
558 | 277 f_data.s_vaddr = f_bss.s_vaddr; |
428 | 278 f_data.s_paddr += file_sz_change; |
279 #if 0 | |
280 if (f_data.s_size + f_nextdata.s_size != f_ohdr.dsize) | |
647 | 281 printf ("section size doesn't tally with dsize %lx != %lx\n", |
558 | 282 f_data.s_size + f_nextdata.s_size, f_ohdr.dsize); |
428 | 283 #endif |
284 f_data.s_size += file_sz_change; | |
285 lseek (a_new, 0, SEEK_SET); | |
286 /* write file header */ | |
287 f_hdr.f_symptr += file_sz_change; | |
448 | 288 #ifdef NO_DEBUG |
446 | 289 f_hdr.f_nscns--; |
290 #endif | |
444 | 291 |
647 | 292 printf ("writing file header\n"); |
293 if (write (a_new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) | |
294 PERROR ("failed to write file header"); | |
428 | 295 /* write optional header fixing dsize & bsize*/ |
647 | 296 printf ("writing optional header\n"); |
297 printf ("new data size is %lx, >= %lx\n", new_data_size, | |
428 | 298 f_ohdr.dsize + f_ohdr.bsize); |
647 | 299 if (new_data_size < (long) (f_ohdr.dsize + f_ohdr.bsize)) |
300 printf ("warning: new data size is < approx\n"); | |
428 | 301 f_ohdr.dsize=new_data_size; |
444 | 302 f_ohdr.bsize=BSS_PAD_SIZE; |
1198 | 303 /* Prevent stack overflow with regexp usage. */ |
304 f_ohdr.SizeOfStackReserve = STACK_SIZE; | |
305 | |
647 | 306 if (write (a_new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) |
307 PERROR ("failed to write optional header"); | |
428 | 308 /* write text as is */ |
647 | 309 printf ("writing text header (unchanged)\n"); |
428 | 310 |
647 | 311 if (write (a_new, &f_text, sizeof (f_text)) != sizeof (f_text)) |
312 PERROR ("failed to write text header"); | |
448 | 313 #ifndef NO_DEBUG |
444 | 314 /* Write small bss section. */ |
315 if (!sections_reversed) | |
316 { | |
317 f_bss.s_size = BSS_PAD_SIZE; | |
318 f_bss.s_paddr = BSS_PAD_SIZE; | |
319 f_bss.s_vaddr = f_data.s_vaddr - BSS_PAD_SIZE; | |
647 | 320 if (write (a_new, &f_bss, sizeof (f_bss)) != sizeof (f_bss)) |
321 PERROR ("failed to write bss header"); | |
444 | 322 } |
446 | 323 #endif |
428 | 324 /* write new data header */ |
647 | 325 printf ("writing .data header\n"); |
428 | 326 |
647 | 327 if (write (a_new, &f_data, sizeof (f_data)) != sizeof (f_data)) |
328 PERROR ("failed to write data header"); | |
448 | 329 #ifndef NO_DEBUG |
444 | 330 /* Write small bss section. */ |
331 if (sections_reversed) | |
332 { | |
333 f_bss.s_size = BSS_PAD_SIZE; | |
334 f_bss.s_paddr = BSS_PAD_SIZE; | |
335 f_bss.s_vaddr = f_nextdata.s_vaddr - BSS_PAD_SIZE; | |
647 | 336 if (write (a_new, &f_bss, sizeof (f_bss)) != sizeof (f_bss)) |
337 PERROR ("failed to write bss header"); | |
444 | 338 } |
446 | 339 #endif |
647 | 340 printf ("writing following data header\n"); |
428 | 341 f_nextdata.s_scnptr += file_sz_change; |
342 if (f_nextdata.s_lnnoptr != 0) f_nextdata.s_lnnoptr += file_sz_change; | |
343 if (f_nextdata.s_relptr != 0) f_nextdata.s_relptr += file_sz_change; | |
647 | 344 if (write (a_new, &f_nextdata, sizeof (f_nextdata)) != sizeof (f_nextdata)) |
345 PERROR ("failed to write nextdata header"); | |
428 | 346 |
347 /* copy other section headers adjusting the file offset */ | |
348 for (i=0; i<(f_hdr.f_nscns-3); i++) | |
349 { | |
350 if (read (a_out, §ion, sizeof (section)) != sizeof (section)) | |
558 | 351 PERROR ("no .data section"); |
428 | 352 |
353 section.s_scnptr += file_sz_change; | |
354 if (section.s_lnnoptr != 0) section.s_lnnoptr += file_sz_change; | |
355 if (section.s_relptr != 0) section.s_relptr += file_sz_change; | |
356 | |
647 | 357 if (write (a_new, §ion, sizeof (section)) != sizeof (section)) |
358 PERROR ("failed to write data header"); | |
428 | 359 } |
448 | 360 #ifdef NO_DEBUG |
446 | 361 /* dump bss to maintain offsets */ |
647 | 362 memset (&f_bss, 0, sizeof (f_bss)); |
363 if (write (a_new, &f_bss, sizeof (f_bss)) != sizeof (f_bss)) | |
364 PERROR ("failed to write bss header"); | |
446 | 365 #endif |
647 | 366 size = lseek (a_new, 0, SEEK_CUR); |
367 CHECK_AOUT_POS (size); | |
428 | 368 |
369 /* copy eveything else until start of data */ | |
370 size = f_data_s_scnptr - lseek (a_out, 0, SEEK_CUR); | |
371 | |
372 printf ("copying executable up to data section ... %lx bytes\n", | |
373 size); | |
647 | 374 dup_file_area (a_out, a_new, size); |
428 | 375 |
647 | 376 CHECK_AOUT_POS (f_data_s_scnptr); |
428 | 377 |
378 if (!sections_reversed) | |
379 { | |
444 | 380 /* dump bss + padding between sections, sans small bss pad */ |
428 | 381 printf ("dumping .bss into executable... %lx bytes\n", bss_size); |
647 | 382 if (write (a_new, bss_start, bss_size) != bss_size) |
428 | 383 { |
647 | 384 PERROR ("failed to write bss section"); |
428 | 385 } |
386 | |
387 /* pad, needs to be zero */ | |
444 | 388 bss_padding = (new_bss_size - bss_size) - BSS_PAD_SIZE; |
389 if (bss_padding < 0) | |
647 | 390 PERROR ("padded .bss too small"); |
428 | 391 printf ("padding .bss ... %lx bytes\n", bss_padding); |
647 | 392 empty_space = malloc (bss_padding); |
393 memset (empty_space, 0, bss_padding); | |
394 if (write (a_new, empty_space, bss_padding) != bss_padding) | |
395 PERROR ("failed to write bss section"); | |
396 free (empty_space); | |
428 | 397 } |
398 | |
399 /* tell dumped version not to free pure heap */ | |
400 static_heap_dumped = 1; | |
401 /* Get a pointer to the raw data in our address space. */ | |
402 printf ("dumping .data section... %lx bytes\n", data_size); | |
647 | 403 if (write (a_new, data_start_va, data_size) != data_size) |
404 PERROR ("failed to write data section"); | |
428 | 405 /* were going to use free again ... */ |
406 static_heap_dumped = 0; | |
407 | |
647 | 408 size = lseek (a_out, f_data_s_scnptr + data_size, SEEK_SET); |
428 | 409 |
410 if (!sections_reversed) | |
411 { | |
412 size = f_nextdata_s_scnptr - size; | |
647 | 413 dup_file_area (a_out, a_new, size); |
428 | 414 } |
415 else | |
416 { | |
444 | 417 /* need to pad to bss with data in file */ |
428 | 418 printf ("padding .data ... %lx bytes\n", data_padding); |
419 size = (f_bss_s_vaddr - f_data_s_vaddr) - data_size; | |
647 | 420 dup_file_area (a_out, a_new, size); |
428 | 421 |
422 /* dump bss + padding between sections */ | |
423 printf ("dumping .bss into executable... %lx bytes\n", bss_size); | |
647 | 424 if (write (a_new, bss_start, bss_size) != bss_size) |
425 PERROR ("failed to write bss section"); | |
428 | 426 |
427 /* pad, needs to be zero */ | |
444 | 428 bss_padding = (new_bss_size - bss_size) - BSS_PAD_SIZE; |
429 if (bss_padding < 0) | |
647 | 430 PERROR ("padded .bss too small"); |
428 | 431 printf ("padding .bss ... %lx bytes\n", bss_padding); |
647 | 432 empty_space = malloc (bss_padding); |
433 memset (empty_space, 0, bss_padding); | |
434 if (write (a_new, empty_space, bss_padding) != bss_padding) | |
435 PERROR ("failed to write bss section"); | |
436 free (empty_space); | |
437 if (lseek (a_new, 0, SEEK_CUR) != (long) f_nextdata.s_scnptr) | |
428 | 438 { |
647 | 439 printf ("at %lx should be at %lx\n", |
1685 | 440 (unsigned long) lseek (a_new, 0, SEEK_CUR), |
441 (unsigned long) f_nextdata.s_scnptr); | |
647 | 442 PERROR ("file positioning error\n"); |
428 | 443 } |
647 | 444 lseek (a_out, f_nextdata_s_scnptr, SEEK_SET); |
428 | 445 } |
446 | |
647 | 447 CHECK_AOUT_POS (f_nextdata_s_scnptr); |
428 | 448 |
449 /* now dump - nextdata don't need to do this cygwin ds is in .data! */ | |
450 printf ("dumping following data section... %lx bytes\n", f_nextdata.s_size); | |
451 | |
647 | 452 dup_file_area (a_out,a_new,f_nextdata.s_size); |
428 | 453 |
454 /* write rest of file */ | |
455 printf ("writing rest of file\n"); | |
647 | 456 size = lseek (a_out, 0, SEEK_END); |
428 | 457 size = size - (f_nextdata_s_scnptr + f_nextdata.s_size); /* length remaining in a_out */ |
647 | 458 lseek (a_out, f_nextdata_s_scnptr + f_nextdata.s_size, SEEK_SET); |
428 | 459 |
647 | 460 dup_file_area (a_out, a_new, size); |
428 | 461 } |
462 | |
463 /* | |
464 * copy from aout to anew | |
465 */ | |
647 | 466 static void |
467 dup_file_area (int a_out, int a_new, long size) | |
428 | 468 { |
469 char page[BUFSIZ]; | |
470 long n; | |
471 for (; size > 0; size -= sizeof (page)) | |
472 { | |
1111 | 473 n = size > (long) sizeof (page) ? (long) sizeof (page) : size; |
428 | 474 if (read (a_out, page, n) != n || write (a_new, page, n) != n) |
558 | 475 PERROR ("dump_out()"); |
428 | 476 } |
477 } | |
478 | |
479 #if 0 | |
647 | 480 static void |
481 write_int_to_bss (int a_out, int a_new, void* va, void* newval) | |
428 | 482 { |
483 int cpos; | |
484 | |
647 | 485 cpos = lseek (a_new, 0, SEEK_CUR); |
428 | 486 if (va < bss_start || va > bss_start + f_data.s_size) |
647 | 487 PERROR ("address not in data space\n"); |
488 lseek (a_new, f_data.s_scnptr + ((unsigned long)va - | |
428 | 489 (unsigned long)bss_start), SEEK_SET); |
647 | 490 if (write (a_new, newval, sizeof (int)) != (int) sizeof (int)) |
491 PERROR ("failed to write int value"); | |
492 lseek (a_new, cpos, SEEK_SET); | |
428 | 493 } |
494 #endif | |
495 | |
496 #endif /* HAVE_A_OUT_H */ |