*/
/* 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 <config.h>
+#include "lisp.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
-#include <config.h>
#include <string.h>
+
+#define DONT_ENCAPSULATE /* filenames are external in unex*.c */
#include "sysfile.h"
+
#define PERROR(arg) perror(arg);exit(-1)
#ifndef HAVE_A_OUT_H
}
#else
-#undef CONST
-#include <windows.h>
+#ifndef MAX_PATH
+#define MAX_PATH 260
+#endif
#include <a.out.h>
#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. */
+#ifndef NO_DEBUG
+#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. */
}
/* 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)
+int
+unexec (char *out_name, char *in_name, uintptr_t start_data,
+ uintptr_t d1, uintptr_t d2)
{
/* ugly nt hack - should be in lisp */
int a_new, a_out = -1;
}
if ((a_new = open (new_name, O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
- CREAT_MODE)) < 0)
+ 0755)) < 0)
{
PERROR (new_name);
}
close(a_out);
close(a_new);
+ return 0;
}
/* Flip through the executable and cache the info necessary for dumping. */
static void get_section_info (int a_out, char* a_name)
{
- extern int my_ebss;
+ extern char my_ebss[];
/* From lastfile.c */
extern char my_edata[];
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)
data_padding = (f_bss.s_vaddr - f_data.s_vaddr) - f_data.s_size;
}
- file_sz_change=new_bss_size + data_padding;
+ if ((new_bss_size - bss_size) < BSS_PAD_SIZE)
+ {
+ PERROR (".bss free space too small");
+ }
+
+ file_sz_change=(new_bss_size + data_padding) - BSS_PAD_SIZE;
new_data_size=f_ohdr.dsize + file_sz_change;
if (!sections_reversed)
lseek (a_new, 0, SEEK_SET);
/* write file header */
f_hdr.f_symptr += file_sz_change;
+#ifdef NO_DEBUG
f_hdr.f_nscns--;
+#endif
+
printf("writing file header\n");
if (write(a_new, &f_hdr, sizeof(f_hdr)) != sizeof(f_hdr))
{
f_ohdr.dsize + f_ohdr.bsize);
if (new_data_size < f_ohdr.dsize + f_ohdr.bsize )
{
- PERROR("new data size is < approx");
+ printf("warning: new data size is < approx\n");
}
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");
{
PERROR("failed to write text header");
}
-
+#ifndef NO_DEBUG
+ /* 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");
{
PERROR("failed to write data header");
}
-
+#ifndef NO_DEBUG
+ /* 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;
PERROR("failed to write data header");
}
}
-
+#ifdef NO_DEBUG
/* 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);
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)
{
}
/* 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);
}
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);
}
/* 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);