X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Funexcw.c;h=774c0faa3d52150a9fe63dc103afe5c7dbd79f47;hb=7b4b1b26bb371112bf3e18732864bc08584127b6;hp=6d65e61cb954028fd2716283de55fd290ab92ebc;hpb=77dcef404dc78635f6ffa8f71a803d2bc7cc8921;p=chise%2Fxemacs-chise.git- diff --git a/src/unexcw.c b/src/unexcw.c index 6d65e61..774c0fa 100644 --- a/src/unexcw.c +++ b/src/unexcw.c @@ -21,7 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA */ /* This is a complete rewrite, some code snarfed from unexnt.c and - unexec.c, Andy Piper (andyp@parallax.co.uk) 13-1-98 */ + unexec.c, Andy Piper (andy@xemacs.org) 13-1-98 */ #include #include @@ -29,7 +29,10 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include #include #include + +#define DONT_ENCAPSULATE /* filenames are external in unex*.c */ #include "sysfile.h" + #define PERROR(arg) perror(arg);exit(-1) #ifndef HAVE_A_OUT_H @@ -39,14 +42,22 @@ unexec (char *, char *, void *, void *, void *) } #else -#undef CONST -#include +#ifndef MAX_PATH +#define MAX_PATH 260 +#endif #include #define ALLOC_UNIT 0xFFFF #define ALLOC_MASK ~((unsigned long)(ALLOC_UNIT)) #define ALIGN_ALLOC(addr) \ ((((unsigned long)addr) + ALLOC_UNIT) & ALLOC_MASK) +/* Note that all sections must be aligned on a 0x1000 boundary so + this is the minimum size that our dummy bss can be. */ +#ifdef BROKEN_GDB +#define BSS_PAD_SIZE 0x1000 +#else +#define BSS_PAD_SIZE 0 +#endif /* To prevent zero-initialized variables from being placed into the bss section, use non-zero values to represent an uninitialized state. */ @@ -81,6 +92,9 @@ if (lseek(a_out, 0, SEEK_CUR) != a) \ exit(-1); \ } +void +unexec (char *out_name, char *in_name, void *start_data, + void * d1, void * d2); /* Dump out .data and .bss sections into a new executable. */ void unexec (char *out_name, char *in_name, void *start_data, void * d1, void * d2) @@ -111,7 +125,7 @@ void unexec (char *out_name, char *in_name, void *start_data, } if ((a_new = open (new_name, O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, - CREAT_MODE)) < 0) + 0755)) < 0) { PERROR (new_name); } @@ -245,13 +259,19 @@ copy_executable_and_dump_data_section (int a_out, int a_new) void* empty_space; extern int static_heap_dumped; SCNHDR section; - /* calculate new sizes f_ohdr.dsize is the total initialized data - size on disk which is f_data.s_size + f_idata.s_size. - f_ohdr.data_start is the base addres of all data and so should - not be changed. *.s_vaddr is the virtual address of the start - of the section normalzed from f_ohdr.ImageBase. *.s_paddr - appears to be the number of bytes in the section actually used - (whereas *.s_size is aligned). + /* calculate new sizes: + + f_ohdr.dsize is the total initialized data size on disk which is + f_data.s_size + f_idata.s_size. + + f_ohdr.data_start is the base addres of all data and so should + not be changed. + + *.s_vaddr is the virtual address of the start of the section + *normalized from f_ohdr.ImageBase. + + *.s_paddr appears to be the number of bytes in the section + *actually used (whereas *.s_size is aligned). bsize is now 0 since subsumed into .data dsize is dsize + (f_data.s_vaddr - f_bss.s_vaddr) @@ -271,7 +291,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new) data_padding = (f_bss.s_vaddr - f_data.s_vaddr) - f_data.s_size; } - file_sz_change=new_bss_size + data_padding; + file_sz_change=(new_bss_size + data_padding) - BSS_PAD_SIZE; new_data_size=f_ohdr.dsize + file_sz_change; if (!sections_reversed) @@ -290,7 +310,10 @@ copy_executable_and_dump_data_section (int a_out, int a_new) lseek (a_new, 0, SEEK_SET); /* write file header */ f_hdr.f_symptr += file_sz_change; +#ifndef BROKEN_GDB f_hdr.f_nscns--; +#endif + printf("writing file header\n"); if (write(a_new, &f_hdr, sizeof(f_hdr)) != sizeof(f_hdr)) { @@ -305,7 +328,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new) PERROR("new data size is < approx"); } f_ohdr.dsize=new_data_size; - f_ohdr.bsize=0; + f_ohdr.bsize=BSS_PAD_SIZE; if (write(a_new, &f_ohdr, sizeof(f_ohdr)) != sizeof(f_ohdr)) { PERROR("failed to write optional header"); @@ -317,7 +340,19 @@ copy_executable_and_dump_data_section (int a_out, int a_new) { PERROR("failed to write text header"); } - +#ifdef BROKEN_GDB + /* Write small bss section. */ + if (!sections_reversed) + { + f_bss.s_size = BSS_PAD_SIZE; + f_bss.s_paddr = BSS_PAD_SIZE; + f_bss.s_vaddr = f_data.s_vaddr - BSS_PAD_SIZE; + if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss)) + { + PERROR("failed to write bss header"); + } + } +#endif /* write new data header */ printf("writing .data header\n"); @@ -325,7 +360,19 @@ copy_executable_and_dump_data_section (int a_out, int a_new) { PERROR("failed to write data header"); } - +#ifdef BROKEN_GDB + /* Write small bss section. */ + if (sections_reversed) + { + f_bss.s_size = BSS_PAD_SIZE; + f_bss.s_paddr = BSS_PAD_SIZE; + f_bss.s_vaddr = f_nextdata.s_vaddr - BSS_PAD_SIZE; + if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss)) + { + PERROR("failed to write bss header"); + } + } +#endif printf("writing following data header\n"); f_nextdata.s_scnptr += file_sz_change; if (f_nextdata.s_lnnoptr != 0) f_nextdata.s_lnnoptr += file_sz_change; @@ -352,14 +399,14 @@ copy_executable_and_dump_data_section (int a_out, int a_new) PERROR("failed to write data header"); } } - +#ifndef BROKEN_GDB /* dump bss to maintain offsets */ memset(&f_bss, 0, sizeof(f_bss)); if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss)) { PERROR("failed to write bss header"); } - +#endif size=lseek(a_new, 0, SEEK_CUR); CHECK_AOUT_POS(size); @@ -374,7 +421,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new) if (!sections_reversed) { - /* dump bss + padding between sections */ + /* dump bss + padding between sections, sans small bss pad */ printf ("dumping .bss into executable... %lx bytes\n", bss_size); if (write(a_new, bss_start, bss_size) != (int)bss_size) { @@ -382,7 +429,11 @@ copy_executable_and_dump_data_section (int a_out, int a_new) } /* pad, needs to be zero */ - bss_padding = new_bss_size - bss_size; + bss_padding = (new_bss_size - bss_size) - BSS_PAD_SIZE; + if (bss_padding < 0) + { + PERROR("padded .bss too small"); + } printf ("padding .bss ... %lx bytes\n", bss_padding); empty_space = malloc(bss_padding); memset(empty_space, 0, bss_padding); @@ -413,7 +464,7 @@ copy_executable_and_dump_data_section (int a_out, int a_new) } else { - /* need to bad to bss with data in file */ + /* need to pad to bss with data in file */ printf ("padding .data ... %lx bytes\n", data_padding); size = (f_bss_s_vaddr - f_data_s_vaddr) - data_size; dup_file_area(a_out, a_new, size); @@ -426,7 +477,11 @@ copy_executable_and_dump_data_section (int a_out, int a_new) } /* pad, needs to be zero */ - bss_padding = new_bss_size - bss_size; + bss_padding = (new_bss_size - bss_size) - BSS_PAD_SIZE; + if (bss_padding < 0) + { + PERROR("padded .bss too small"); + } printf ("padding .bss ... %lx bytes\n", bss_padding); empty_space = malloc(bss_padding); memset(empty_space, 0, bss_padding);