54844
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
1 /* unexec() support for Cygwin;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
2 complete rewrite of xemacs Cygwin unexec() code
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
3
|
75348
|
4 Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
54844
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
5
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
6 This file is part of GNU Emacs.
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
7
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
8 GNU Emacs is free software; you can redistribute it and/or modify
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
9 it under the terms of the GNU General Public License as published by
|
78260
|
10 the Free Software Foundation; either version 3, or (at your option)
|
54844
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
11 any later version.
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
12
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
13 GNU Emacs is distributed in the hope that it will be useful,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
16 GNU General Public License for more details.
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
17
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
18 You should have received a copy of the GNU General Public License
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
19 along with GNU Emacs; see the file COPYING. If not, write to
|
64084
|
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
21 Boston, MA 02110-1301, USA. */
|
54844
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
22
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
23 #include <config.h>
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
24 #include <lisp.h>
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
25 #include <stdio.h>
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
26 #include <fcntl.h>
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
27 #include <a.out.h>
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
28 #include <unistd.h>
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
29 #include <assert.h>
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
30
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
31 #define DOTEXE ".exe"
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
32
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
33 extern int bss_sbrk_did_unexec;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
34
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
35 /* emacs symbols that indicate where bss and data end for emacs internals */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
36 extern char my_endbss[];
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
37 extern char my_edata[];
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
38
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
39 /*
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
40 ** header for Windows executable files
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
41 */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
42 typedef struct
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
43 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
44 FILHDR file_header;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
45 PEAOUTHDR file_optional_header;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
46 SCNHDR section_header[32];
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
47 } exe_header_t;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
48
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
49 int debug_unexcw = 0;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
50
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
51 /*
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
52 ** Read the header from the executable into memory so we can more easily access it.
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
53 */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
54 static exe_header_t *
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
55 read_exe_header (int fd, exe_header_t * exe_header_buffer)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
56 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
57 int i;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
58 int ret;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
59
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
60 assert (fd >= 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
61 assert (exe_header_buffer != 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
62
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
63 ret = lseek (fd, 0L, SEEK_SET);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
64 assert (ret != -1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
65
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
66 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
67 read (fd, &exe_header_buffer->file_header,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
68 sizeof (exe_header_buffer->file_header));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
69 assert (ret == sizeof (exe_header_buffer->file_header));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
70
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
71 assert (exe_header_buffer->file_header.e_magic == 0x5a4d);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
72 assert (exe_header_buffer->file_header.nt_signature == 0x4550);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
73 assert (exe_header_buffer->file_header.f_magic == 0x014c);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
74 assert (exe_header_buffer->file_header.f_nscns > 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
75 assert (exe_header_buffer->file_header.f_nscns <=
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
76 sizeof (exe_header_buffer->section_header) /
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
77 sizeof (exe_header_buffer->section_header[0]));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
78 assert (exe_header_buffer->file_header.f_opthdr > 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
79
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
80 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
81 read (fd, &exe_header_buffer->file_optional_header,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
82 sizeof (exe_header_buffer->file_optional_header));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
83 assert (ret == sizeof (exe_header_buffer->file_optional_header));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
84
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
85 assert (exe_header_buffer->file_optional_header.magic == 0x010b);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
86
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
87 for (i = 0; i < exe_header_buffer->file_header.f_nscns; ++i)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
88 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
89 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
90 read (fd, &exe_header_buffer->section_header[i],
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
91 sizeof (exe_header_buffer->section_header[i]));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
92 assert (ret == sizeof (exe_header_buffer->section_header[i]));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
93 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
94
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
95 return (exe_header_buffer);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
96 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
97
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
98 /*
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
99 ** Fix the dumped emacs executable:
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
100 **
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
101 ** - copy .data section data of interest from running executable into
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
102 ** output .exe file
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
103 **
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
104 ** - convert .bss section into an initialized data section (like
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
105 ** .data) and copy .bss section data of interest from running
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
106 ** executable into output .exe file
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
107 */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
108 static void
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
109 fixup_executable (int fd)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
110 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
111 exe_header_t exe_header_buffer;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
112 exe_header_t *exe_header;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
113 int i;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
114 int ret;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
115 int found_data = 0;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
116 int found_bss = 0;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
117
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
118 exe_header = read_exe_header (fd, &exe_header_buffer);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
119 assert (exe_header != 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
120
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
121 assert (exe_header->file_header.f_nscns > 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
122 for (i = 0; i < exe_header->file_header.f_nscns; ++i)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
123 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
124 unsigned long start_address =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
125 exe_header->section_header[i].s_vaddr +
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
126 exe_header->file_optional_header.ImageBase;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
127 unsigned long end_address =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
128 exe_header->section_header[i].s_vaddr +
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
129 exe_header->file_optional_header.ImageBase +
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
130 exe_header->section_header[i].s_paddr;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
131 if (debug_unexcw)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
132 printf ("%8s start 0x%08x end 0x%08x\n",
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
133 exe_header->section_header[i].s_name,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
134 start_address, end_address);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
135 if (my_edata >= (char *) start_address
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
136 && my_edata < (char *) end_address)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
137 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
138 /* data section */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
139 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
140 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
141 SEEK_SET);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
142 assert (ret != -1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
143 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
144 write (fd, (char *) start_address,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
145 my_edata - (char *) start_address);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
146 assert (ret == my_edata - (char *) start_address);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
147 ++found_data;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
148 if (debug_unexcw)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
149 printf (" .data, mem start 0x%08x mem length %d\n",
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
150 start_address, my_edata - (char *) start_address);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
151 if (debug_unexcw)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
152 printf (" .data, file start %d file length %d\n",
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
153 (int) exe_header->section_header[i].s_scnptr,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
154 (int) exe_header->section_header[i].s_paddr);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
155 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
156 else if (my_endbss >= (char *) start_address
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
157 && my_endbss < (char *) end_address)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
158 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
159 /* bss section */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
160 ++found_bss;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
161 if (exe_header->section_header[i].s_flags & 0x00000080)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
162 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
163 /* convert uninitialized data section to initialized data section */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
164 struct stat statbuf;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
165 ret = fstat (fd, &statbuf);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
166 assert (ret != -1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
167
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
168 exe_header->section_header[i].s_flags &= ~0x00000080;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
169 exe_header->section_header[i].s_flags |= 0x00000040;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
170
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
171 exe_header->section_header[i].s_scnptr =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
172 (statbuf.st_size +
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
173 exe_header->file_optional_header.FileAlignment) /
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
174 exe_header->file_optional_header.FileAlignment *
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
175 exe_header->file_optional_header.FileAlignment;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
176
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
177 exe_header->section_header[i].s_size =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
178 (exe_header->section_header[i].s_paddr +
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
179 exe_header->file_optional_header.FileAlignment) /
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
180 exe_header->file_optional_header.FileAlignment *
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
181 exe_header->file_optional_header.FileAlignment;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
182
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
183 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
184 lseek (fd,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
185 (long) (exe_header->section_header[i].s_scnptr +
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
186 exe_header->section_header[i].s_size - 1),
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
187 SEEK_SET);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
188 assert (ret != -1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
189 ret = write (fd, "", 1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
190 assert (ret == 1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
191
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
192 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
193 lseek (fd,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
194 (long) ((char *) &exe_header->section_header[i] -
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
195 (char *) exe_header), SEEK_SET);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
196 assert (ret != -1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
197 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
198 write (fd, &exe_header->section_header[i],
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
199 sizeof (exe_header->section_header[i]));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
200 assert (ret == sizeof (exe_header->section_header[i]));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
201 if (debug_unexcw)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
202 printf (" seek to %ld, write %d\n",
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
203 (long) ((char *) &exe_header->section_header[i] -
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
204 (char *) exe_header),
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
205 sizeof (exe_header->section_header[i]));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
206 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
207 /* write initialized data section */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
208 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
209 lseek (fd, (long) (exe_header->section_header[i].s_scnptr),
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
210 SEEK_SET);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
211 assert (ret != -1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
212 ret =
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
213 write (fd, (char *) start_address,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
214 my_endbss - (char *) start_address);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
215 assert (ret == (my_endbss - (char *) start_address));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
216 if (debug_unexcw)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
217 printf (" .bss, mem start 0x%08x mem length %d\n",
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
218 start_address, my_endbss - (char *) start_address);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
219 if (debug_unexcw)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
220 printf (" .bss, file start %d file length %d\n",
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
221 (int) exe_header->section_header[i].s_scnptr,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
222 (int) exe_header->section_header[i].s_paddr);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
223 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
224 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
225 assert (found_bss == 1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
226 assert (found_data == 1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
227 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
228
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
229 /*
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
230 ** Windows likes .exe suffixes on executables.
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
231 */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
232 static char *
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
233 add_exe_suffix_if_necessary (const char *name, char *modified)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
234 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
235 int i = strlen (name);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
236 if (i <= (sizeof (DOTEXE) - 1))
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
237 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
238 sprintf (modified, "%s%s", name, DOTEXE);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
239 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
240 else if (!strcasecmp (name + i - (sizeof (DOTEXE) - 1), DOTEXE))
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
241 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
242 strcpy (modified, name);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
243 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
244 else
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
245 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
246 sprintf (modified, "%s%s", name, DOTEXE);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
247 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
248 return (modified);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
249 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
250
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
251 int
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
252 unexec (char *outfile, char *infile, unsigned start_data, unsigned d1,
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
253 unsigned d2)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
254 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
255 char infile_buffer[FILENAME_MAX];
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
256 char outfile_buffer[FILENAME_MAX];
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
257 int fd_in;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
258 int fd_out;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
259 int ret;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
260 int ret2;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
261
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
262 if (bss_sbrk_did_unexec)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
263 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
264 /* can only dump once */
|
73688
|
265 printf ("You can only dump Emacs once on this platform.\n");
|
54844
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
266 return (1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
267 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
268
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
269 report_sheap_usage (1);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
270
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
271 infile = add_exe_suffix_if_necessary (infile, infile_buffer);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
272 outfile = add_exe_suffix_if_necessary (outfile, outfile_buffer);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
273
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
274 fd_in = open (infile, O_RDONLY | O_BINARY);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
275 assert (fd_in >= 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
276 fd_out = open (outfile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0755);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
277 assert (fd_out >= 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
278 for (;;)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
279 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
280 char buffer[4096];
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
281 ret = read (fd_in, buffer, sizeof (buffer));
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
282 if (ret == 0)
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
283 {
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
284 /* eof */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
285 break;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
286 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
287 assert (ret > 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
288 /* data */
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
289 ret2 = write (fd_out, buffer, ret);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
290 assert (ret2 == ret);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
291 }
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
292 ret = close (fd_in);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
293 assert (ret == 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
294
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
295 bss_sbrk_did_unexec = 1;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
296 fixup_executable (fd_out);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
297 bss_sbrk_did_unexec = 0;
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
298
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
299 ret = close (fd_out);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
300 assert (ret == 0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
301
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
302 return (0);
|
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
diff
changeset
|
303 }
|
54858
|
304
|
|
305 /* arch-tag: fc44f6c3-ca0a-45e0-a5a2-58b6101b1e65
|
|
306 (do not change this comment) */
|