Mercurial > hg > xemacs-beta
comparison src/unexcw.c @ 278:90d73dddcdc4 r21-0b37
Import from CVS: tag r21-0b37
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:31:29 +0200 |
parents | b2472a1930f2 |
children | 4711e16a8e49 |
comparison
equal
deleted
inserted
replaced
277:cfdf3ff11843 | 278:90d73dddcdc4 |
---|---|
65 unsigned long data_size = UNINIT_LONG; | 65 unsigned long data_size = UNINIT_LONG; |
66 | 66 |
67 /* Cached info about the .bss section in the executable. */ | 67 /* Cached info about the .bss section in the executable. */ |
68 void* bss_start = UNINIT_PTR; | 68 void* bss_start = UNINIT_PTR; |
69 unsigned long bss_size = UNINIT_LONG; | 69 unsigned long bss_size = UNINIT_LONG; |
70 int sections_reversed = 0; | |
70 FILHDR f_hdr; | 71 FILHDR f_hdr; |
71 PEAOUTHDR f_ohdr; | 72 PEAOUTHDR f_ohdr; |
72 SCNHDR f_data, f_bss, f_text, f_nextdata; | 73 SCNHDR f_data, f_bss, f_text, f_nextdata; |
73 | 74 |
74 #define PERROR(arg) perror(arg);exit(-1) | 75 #define PERROR(arg) perror(arg);exit(-1) |
153 if (read (a_out, &f_ohdr, AOUTSZ) != AOUTSZ) | 154 if (read (a_out, &f_ohdr, AOUTSZ) != AOUTSZ) |
154 { | 155 { |
155 PERROR (a_name); | 156 PERROR (a_name); |
156 } | 157 } |
157 } | 158 } |
158 /* Loop through .data & .bss section headers, copying them in */ | 159 /* Loop through .data & .bss section headers, copying them in. |
160 With newer lds these are reversed so we have to cope with both */ | |
159 lseek (a_out, sizeof (f_hdr) + f_hdr.f_opthdr, 0); | 161 lseek (a_out, sizeof (f_hdr) + f_hdr.f_opthdr, 0); |
160 | 162 |
161 if (read (a_out, &f_text, sizeof (f_text)) != sizeof (f_text) | 163 if (read (a_out, &f_text, sizeof (f_text)) != sizeof (f_text) |
162 && | 164 || |
163 strcmp (f_text.s_name, ".text")) | 165 strcmp (f_text.s_name, ".text")) |
164 { | 166 { |
165 PERROR ("no .text section"); | 167 PERROR ("no .text section"); |
166 } | 168 } |
167 | 169 |
168 /* The .bss section. */ | 170 /* The .bss section. */ |
169 if (read (a_out, &f_bss, sizeof (f_bss)) != sizeof (f_bss) | 171 if (read (a_out, &f_bss, sizeof (f_bss)) != sizeof (f_bss) |
170 && | 172 || |
171 strcmp (f_bss.s_name, ".bss")) | 173 (strcmp (f_bss.s_name, ".bss") && strcmp (f_bss.s_name, ".data"))) |
172 { | 174 { |
173 PERROR ("no .bss section"); | 175 PERROR ("no .bss / .data section"); |
174 } | 176 } |
175 | 177 |
178 /* check for reversed .bss and .data */ | |
179 if (!strcmp(f_bss.s_name, ".data")) | |
180 { | |
181 printf(".data and .bss reversed\n"); | |
182 sections_reversed = 1; | |
183 memcpy(&f_data, &f_bss, sizeof(f_bss)); | |
184 } | |
185 | |
186 /* The .data section. */ | |
187 if (!sections_reversed) | |
188 { | |
189 if (read (a_out, &f_data, sizeof (f_data)) != sizeof (f_data) | |
190 || | |
191 strcmp (f_data.s_name, ".data")) | |
192 { | |
193 PERROR ("no .data section"); | |
194 } | |
195 } | |
196 else | |
197 { | |
198 if (read (a_out, &f_bss, sizeof (f_bss)) != sizeof (f_bss) | |
199 || | |
200 strcmp (f_bss.s_name, ".bss")) | |
201 { | |
202 PERROR ("no .bss section"); | |
203 } | |
204 } | |
205 | |
176 bss_start = (void *) ((char*)f_ohdr.ImageBase + f_bss.s_vaddr); | 206 bss_start = (void *) ((char*)f_ohdr.ImageBase + f_bss.s_vaddr); |
177 bss_size = (unsigned long)((char*)&my_ebss-(char*)bss_start); | 207 bss_size = (unsigned long)((char*)&my_ebss-(char*)bss_start); |
178 | 208 |
179 /* must keep bss data that we want to be blank as blank */ | 209 /* must keep bss data that we want to be blank as blank */ |
180 printf("found bss - keeping %lx of %lx bytes\n", bss_size, f_ohdr.bsize); | 210 printf("found bss - keeping %lx of %lx bytes\n", bss_size, f_ohdr.bsize); |
181 | 211 |
182 /* The .data section. */ | 212 /* The .data section. */ |
183 if (read (a_out, &f_data, sizeof (f_data)) != sizeof (f_data) | |
184 && | |
185 strcmp (f_data.s_name, ".data")) | |
186 { | |
187 PERROR ("no .data section"); | |
188 } | |
189 | |
190 /* The .data section. */ | |
191 data_start_va = (void *) ((char*)f_ohdr.ImageBase + f_data.s_vaddr); | 213 data_start_va = (void *) ((char*)f_ohdr.ImageBase + f_data.s_vaddr); |
192 | 214 |
193 /* We want to only write Emacs data back to the executable, | 215 /* We want to only write Emacs data back to the executable, |
194 not any of the library data (if library data is included, | 216 not any of the library data (if library data is included, |
195 then a dumped Emacs won't run on system versions other | 217 then a dumped Emacs won't run on system versions other |
196 than the one Emacs was dumped on). */ | 218 than the one Emacs was dumped on). */ |
197 data_size = (unsigned long)my_edata - (unsigned long)data_start_va; | 219 data_size = (unsigned long)my_edata - (unsigned long)data_start_va; |
198 | 220 printf("found data - keeping %lx of %lx bytes\n", data_size, f_ohdr.dsize); |
199 /* The following data section. */ | 221 |
222 /* The following data section - often .idata */ | |
200 if (read (a_out, &f_nextdata, sizeof (f_nextdata)) != sizeof (f_nextdata) | 223 if (read (a_out, &f_nextdata, sizeof (f_nextdata)) != sizeof (f_nextdata) |
201 && | 224 && |
202 strcmp (&f_nextdata.s_name[2], "data")) | 225 strcmp (&f_nextdata.s_name[2], "data")) |
203 { | 226 { |
204 PERROR ("no other data section"); | 227 PERROR ("no other data section"); |
209 | 232 |
210 static void | 233 static void |
211 copy_executable_and_dump_data_section (int a_out, int a_new) | 234 copy_executable_and_dump_data_section (int a_out, int a_new) |
212 { | 235 { |
213 long size=0; | 236 long size=0; |
214 unsigned long new_data_size, new_bss_size, f_data_s_vaddr, | 237 unsigned long new_data_size, new_bss_size, |
215 file_sz_change, f_data_s_scnptr, bss_padding; | 238 bss_padding, file_sz_change, data_padding=0, |
239 f_data_s_vaddr = f_data.s_vaddr, | |
240 f_data_s_scnptr = f_data.s_scnptr, | |
241 f_bss_s_vaddr = f_bss.s_vaddr, | |
242 f_nextdata_s_scnptr = f_nextdata.s_scnptr; | |
243 | |
216 int i; | 244 int i; |
217 void* empty_space; | 245 void* empty_space; |
218 extern int static_heap_dumped; | 246 extern int static_heap_dumped; |
219 SCNHDR section; | 247 SCNHDR section; |
220 /* calculate new sizes f_ohdr.dsize is the total initalized data | 248 /* calculate new sizes f_ohdr.dsize is the total initalized data |
228 bsize is now 0 since subsumed into .data | 256 bsize is now 0 since subsumed into .data |
229 dsize is dsize + (f_data.s_vaddr - f_bss.s_vaddr) | 257 dsize is dsize + (f_data.s_vaddr - f_bss.s_vaddr) |
230 f_data.s_vaddr is f_bss.s_vaddr | 258 f_data.s_vaddr is f_bss.s_vaddr |
231 f_data.s_size is new dsize maybe. | 259 f_data.s_size is new dsize maybe. |
232 what about s_paddr & s_scnptr? */ | 260 what about s_paddr & s_scnptr? */ |
261 | |
233 /* this is the amount the file increases in size */ | 262 /* this is the amount the file increases in size */ |
234 new_bss_size=f_data.s_vaddr - f_bss.s_vaddr; | 263 if (!sections_reversed) |
235 file_sz_change=new_bss_size; | 264 { |
236 new_data_size=f_ohdr.dsize + new_bss_size; | 265 new_bss_size = f_data.s_vaddr - f_bss.s_vaddr; |
237 f_data_s_scnptr = f_data.s_scnptr; | 266 data_padding = 0; |
238 f_data_s_vaddr = f_data.s_vaddr; | 267 } |
239 f_data.s_vaddr = f_bss.s_vaddr; | 268 else |
240 f_data.s_paddr += new_bss_size; | 269 { |
270 new_bss_size = f_nextdata.s_vaddr - f_bss.s_vaddr; | |
271 data_padding = (f_bss.s_vaddr - f_data.s_vaddr) - f_data.s_size; | |
272 } | |
273 | |
274 file_sz_change=new_bss_size + data_padding; | |
275 new_data_size=f_ohdr.dsize + file_sz_change; | |
276 | |
277 if (!sections_reversed) | |
278 { | |
279 f_data.s_vaddr = f_bss.s_vaddr; | |
280 } | |
281 f_data.s_paddr += file_sz_change; | |
241 #if 0 | 282 #if 0 |
242 if (f_data.s_size + f_nextdata.s_size != f_ohdr.dsize) | 283 if (f_data.s_size + f_nextdata.s_size != f_ohdr.dsize) |
243 { | 284 { |
244 printf("section size doesn't tally with dsize %lx != %lx\n", | 285 printf("section size doesn't tally with dsize %lx != %lx\n", |
245 f_data.s_size + f_nextdata.s_size, f_ohdr.dsize); | 286 f_data.s_size + f_nextdata.s_size, f_ohdr.dsize); |
246 } | 287 } |
247 #endif | 288 #endif |
248 f_data.s_size += new_bss_size; | 289 f_data.s_size += file_sz_change; |
249 lseek (a_new, 0, SEEK_SET); | 290 lseek (a_new, 0, SEEK_SET); |
250 /* write file header */ | 291 /* write file header */ |
251 f_hdr.f_symptr += file_sz_change; | 292 f_hdr.f_symptr += file_sz_change; |
252 f_hdr.f_nscns--; | 293 f_hdr.f_nscns--; |
253 printf("writing file header\n"); | 294 printf("writing file header\n"); |
329 size); | 370 size); |
330 dup_file_area(a_out, a_new, size); | 371 dup_file_area(a_out, a_new, size); |
331 | 372 |
332 CHECK_AOUT_POS(f_data_s_scnptr); | 373 CHECK_AOUT_POS(f_data_s_scnptr); |
333 | 374 |
334 /* dump bss + padding between sections */ | 375 if (!sections_reversed) |
335 printf ("dumping .bss into executable... %lx bytes\n", bss_size); | 376 { |
336 if (write(a_new, bss_start, bss_size) != (int)bss_size) | 377 /* dump bss + padding between sections */ |
337 { | 378 printf ("dumping .bss into executable... %lx bytes\n", bss_size); |
338 PERROR("failed to write bss section"); | 379 if (write(a_new, bss_start, bss_size) != (int)bss_size) |
339 } | 380 { |
340 | 381 PERROR("failed to write bss section"); |
341 /* pad, needs to be zero */ | 382 } |
342 bss_padding = new_bss_size - bss_size; | 383 |
343 printf ("padding .bss ... %lx bytes\n", bss_padding); | 384 /* pad, needs to be zero */ |
344 empty_space = malloc(bss_padding); | 385 bss_padding = new_bss_size - bss_size; |
345 memset(empty_space, 0, bss_padding); | 386 printf ("padding .bss ... %lx bytes\n", bss_padding); |
346 if (write(a_new, empty_space, bss_padding) != (int)bss_padding) | 387 empty_space = malloc(bss_padding); |
347 { | 388 memset(empty_space, 0, bss_padding); |
348 PERROR("failed to write bss section"); | 389 if (write(a_new, empty_space, bss_padding) != (int)bss_padding) |
349 } | 390 { |
350 free(empty_space); | 391 PERROR("failed to write bss section"); |
392 } | |
393 free(empty_space); | |
394 } | |
351 | 395 |
352 /* tell dumped version not to free pure heap */ | 396 /* tell dumped version not to free pure heap */ |
353 static_heap_dumped = 1; | 397 static_heap_dumped = 1; |
354 /* Get a pointer to the raw data in our address space. */ | 398 /* Get a pointer to the raw data in our address space. */ |
355 printf ("dumping .data section... %lx bytes\n", data_size); | 399 printf ("dumping .data section... %lx bytes\n", data_size); |
359 } | 403 } |
360 /* were going to use free again ... */ | 404 /* were going to use free again ... */ |
361 static_heap_dumped = 0; | 405 static_heap_dumped = 0; |
362 | 406 |
363 size = lseek(a_out, f_data_s_scnptr + data_size, SEEK_SET); | 407 size = lseek(a_out, f_data_s_scnptr + data_size, SEEK_SET); |
364 size = f_nextdata.s_scnptr - size; | 408 |
365 dup_file_area(a_out, a_new, size); | 409 if (!sections_reversed) |
366 | 410 { |
367 // lseek(a_out, f_nextdata.s_scnptr, SEEK_CUR); | 411 size = f_nextdata_s_scnptr - size; |
368 CHECK_AOUT_POS(f_nextdata.s_scnptr); | 412 dup_file_area(a_out, a_new, size); |
413 } | |
414 else | |
415 { | |
416 /* need to bad to bss with data in file */ | |
417 printf ("padding .data ... %lx bytes\n", data_padding); | |
418 size = (f_bss_s_vaddr - f_data_s_vaddr) - data_size; | |
419 dup_file_area(a_out, a_new, size); | |
420 | |
421 /* dump bss + padding between sections */ | |
422 printf ("dumping .bss into executable... %lx bytes\n", bss_size); | |
423 if (write(a_new, bss_start, bss_size) != (int)bss_size) | |
424 { | |
425 PERROR("failed to write bss section"); | |
426 } | |
427 | |
428 /* pad, needs to be zero */ | |
429 bss_padding = new_bss_size - bss_size; | |
430 printf ("padding .bss ... %lx bytes\n", bss_padding); | |
431 empty_space = malloc(bss_padding); | |
432 memset(empty_space, 0, bss_padding); | |
433 if (write(a_new, empty_space, bss_padding) != (int)bss_padding) | |
434 { | |
435 PERROR("failed to write bss section"); | |
436 } | |
437 free(empty_space); | |
438 if (lseek(a_new, 0, SEEK_CUR) != f_nextdata.s_scnptr) | |
439 { | |
440 printf("at %lx should be at %lx\n", | |
441 lseek(a_new, 0, SEEK_CUR), | |
442 f_nextdata.s_scnptr); | |
443 PERROR("file positioning error\n"); | |
444 } | |
445 lseek(a_out, f_nextdata_s_scnptr, SEEK_SET); | |
446 } | |
447 | |
448 CHECK_AOUT_POS(f_nextdata_s_scnptr); | |
449 | |
369 /* now dump - nextdata don't need to do this cygwin ds is in .data! */ | 450 /* now dump - nextdata don't need to do this cygwin ds is in .data! */ |
370 printf ("dumping following data section... %lx bytes\n", f_nextdata.s_size); | 451 printf ("dumping following data section... %lx bytes\n", f_nextdata.s_size); |
371 | 452 |
372 dup_file_area(a_out,a_new,f_nextdata.s_size); | 453 dup_file_area(a_out,a_new,f_nextdata.s_size); |
373 | 454 |
374 /* write rest of file */ | 455 /* write rest of file */ |
375 printf ("writing rest of file\n"); | 456 printf ("writing rest of file\n"); |
376 size = lseek(a_out, 0, SEEK_END); | 457 size = lseek(a_out, 0, SEEK_END); |
377 size = size - (f_nextdata.s_scnptr + f_nextdata.s_size); /* length remaining in a_out */ | 458 size = size - (f_nextdata_s_scnptr + f_nextdata.s_size); /* length remaining in a_out */ |
378 lseek(a_out, f_nextdata.s_scnptr + f_nextdata.s_size, SEEK_SET); | 459 lseek(a_out, f_nextdata_s_scnptr + f_nextdata.s_size, SEEK_SET); |
379 | 460 |
380 dup_file_area(a_out, a_new, size); | 461 dup_file_area(a_out, a_new, size); |
381 } | 462 } |
382 | 463 |
383 /* | 464 /* |