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 /*