Mercurial > emacs
annotate src/unexw32.c @ 21539:b9606d56f91f
Revert erroneous 1998-04-08 change.
author | Dave Love <fx@gnu.org> |
---|---|
date | Tue, 14 Apr 1998 21:02:17 +0000 |
parents | c0496e62b737 |
children | 104277bc1444 |
rev | line source |
---|---|
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
1 /* unexec for GNU Emacs on Windows NT. |
12245 | 2 Copyright (C) 1994 Free Software Foundation, Inc. |
3 | |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
4 This file is part of GNU Emacs. |
12245 | 5 |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
6 GNU Emacs is free software; you can redistribute it and/or modify |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
7 it under the terms of the GNU General Public License as published by |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
8 the Free Software Foundation; either version 2, or (at your option) |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
9 any later version. |
12245 | 10 |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
11 GNU Emacs is distributed in the hope that it will be useful, |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
14 GNU General Public License for more details. |
12245 | 15 |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
16 You should have received a copy of the GNU General Public License |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
17 along with GNU Emacs; see the file COPYING. If not, write to |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
14036
diff
changeset
|
19 Boston, MA 02111-1307, USA. |
12245 | 20 |
21 Geoff Voelker (voelker@cs.washington.edu) 8-12-94 | |
22 */ | |
23 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
24 #include <config.h> |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
25 |
12245 | 26 #include <stdlib.h> /* _fmode */ |
27 #include <stdio.h> | |
28 #include <fcntl.h> | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
29 #include <time.h> |
12245 | 30 #include <windows.h> |
31 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
32 /* Include relevant definitions from IMAGEHLP.H, which can be found |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
33 in \\win32sdk\mstools\samples\image\include\imagehlp.h. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
34 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
35 PIMAGE_NT_HEADERS |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
36 (__stdcall * pfnCheckSumMappedFile) (LPVOID BaseAddress, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
37 DWORD FileLength, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
38 LPDWORD HeaderSum, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
39 LPDWORD CheckSum); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
40 |
12245 | 41 extern BOOL ctrl_c_handler (unsigned long type); |
42 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
43 extern char my_begdata[]; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
44 extern char my_edata[]; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
45 extern char my_begbss[]; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
46 extern char my_endbss[]; |
12245 | 47 |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
48 #include "w32heap.h" |
18506
bcc706aedcea
Add pragma to force zero initialized
Geoff Voelker <voelker@cs.washington.edu>
parents:
16593
diff
changeset
|
49 |
21456 | 50 #undef min |
51 #undef max | |
52 #define min(x, y) (((x) < (y)) ? (x) : (y)) | |
53 #define max(x, y) (((x) > (y)) ? (x) : (y)) | |
54 | |
12245 | 55 /* Basically, our "initialized" flag. */ |
56 BOOL need_to_recreate_heap = FALSE; | |
57 | |
58 /* So we can find our heap in the file to recreate it. */ | |
59 unsigned long heap_index_in_executable = 0; | |
60 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
61 int open_input_file (file_data *p_file, char *name); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
62 int open_output_file (file_data *p_file, char *name, unsigned long size); |
12245 | 63 void close_file_data (file_data *p_file); |
64 | |
65 void get_section_info (file_data *p_file); | |
66 void copy_executable_and_dump_data_section (file_data *, file_data *); | |
67 void dump_bss_and_heap (file_data *p_infile, file_data *p_outfile); | |
68 | |
69 /* Cached info about the .data section in the executable. */ | |
70 PUCHAR data_start_va = 0; | |
71 DWORD data_start_file = 0; | |
72 DWORD data_size = 0; | |
73 | |
74 /* Cached info about the .bss section in the executable. */ | |
75 PUCHAR bss_start = 0; | |
76 DWORD bss_size = 0; | |
77 | |
13423
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
78 #ifdef HAVE_NTGUI |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
79 HINSTANCE hinst = NULL; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
80 HINSTANCE hprevinst = NULL; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
81 LPSTR lpCmdLine = ""; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
82 int nCmdShow = 0; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
83 #endif /* HAVE_NTGUI */ |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
84 |
12245 | 85 /* Startup code for running on NT. When we are running as the dumped |
86 version, we need to bootstrap our heap and .bss section into our | |
87 address space before we can actually hand off control to the startup | |
88 code supplied by NT (primarily because that code relies upon malloc ()). */ | |
89 void | |
90 _start (void) | |
91 { | |
92 extern void mainCRTStartup (void); | |
93 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
94 #if 0 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
95 /* Give us a way to debug problems with crashes on startup when |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
96 running under the MSVC profiler. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
97 if (GetEnvironmentVariable ("EMACS_DEBUG", NULL, 0) > 0) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
98 DebugBreak (); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
99 #endif |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
100 |
12245 | 101 /* Cache system info, e.g., the NT page size. */ |
102 cache_system_info (); | |
103 | |
104 /* If we're a dumped version of emacs then we need to recreate | |
105 our heap and play tricks with our .bss section. Do this before | |
106 start up. (WARNING: Do not put any code before this section | |
107 that relies upon malloc () and runs in the dumped version. It | |
108 won't work.) */ | |
109 if (need_to_recreate_heap) | |
110 { | |
111 char executable_path[MAX_PATH]; | |
112 | |
113 if (GetModuleFileName (NULL, executable_path, MAX_PATH) == 0) | |
114 { | |
115 printf ("Failed to find path for executable.\n"); | |
116 exit (1); | |
117 } | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
118 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
119 #if 1 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
120 /* To allow profiling, make sure executable_path names the .exe |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
121 file, not the ._xe file created by the profiler which contains |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
122 extra code that makes the stored exe offsets incorrect. (This |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
123 will not be necessary when unexec properly extends the .bss (or |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
124 .data as appropriate) section to include the dumped bss data, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
125 and dumps the heap into a proper section of its own.) */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
126 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
127 char * p = strrchr (executable_path, '.'); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
128 if (p && p[1] == '_') |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
129 p[1] = 'e'; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
130 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
131 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
132 /* Using HiProf profiler, exe name is different still. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
133 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
134 char * p = strrchr (executable_path, '\\'); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
135 strcpy (p, "\\emacs.exe"); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
136 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
137 #endif |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
138 |
12245 | 139 recreate_heap (executable_path); |
140 need_to_recreate_heap = FALSE; | |
141 } | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
142 else |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
143 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
144 /* Grab our malloc arena space now, before CRT starts up. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
145 sbrk (0); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
146 } |
12245 | 147 |
148 /* The default behavior is to treat files as binary and patch up | |
149 text files appropriately, in accordance with the MSDOS code. */ | |
150 _fmode = O_BINARY; | |
151 | |
152 /* This prevents ctrl-c's in shells running while we're suspended from | |
153 having us exit. */ | |
154 SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrl_c_handler, TRUE); | |
155 | |
156 /* Invoke the NT CRT startup routine now that our housecleaning | |
157 is finished. */ | |
13423
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
158 #ifdef HAVE_NTGUI |
15146
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
159 /* determine WinMain args like crt0.c does */ |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
160 hinst = GetModuleHandle(NULL); |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
161 lpCmdLine = GetCommandLine(); |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
162 nCmdShow = SW_SHOWDEFAULT; |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
163 #endif |
12245 | 164 mainCRTStartup (); |
165 } | |
166 | |
14036 | 167 /* Dump out .data and .bss sections into a new executable. */ |
12245 | 168 void |
169 unexec (char *new_name, char *old_name, void *start_data, void *start_bss, | |
170 void *entry_address) | |
171 { | |
172 file_data in_file, out_file; | |
173 char out_filename[MAX_PATH], in_filename[MAX_PATH]; | |
174 unsigned long size; | |
175 char *ptr; | |
176 | |
177 /* Make sure that the input and output filenames have the | |
178 ".exe" extension...patch them up if they don't. */ | |
179 strcpy (in_filename, old_name); | |
180 ptr = in_filename + strlen (in_filename) - 4; | |
181 if (strcmp (ptr, ".exe")) | |
182 strcat (in_filename, ".exe"); | |
183 | |
184 strcpy (out_filename, new_name); | |
185 ptr = out_filename + strlen (out_filename) - 4; | |
186 if (strcmp (ptr, ".exe")) | |
187 strcat (out_filename, ".exe"); | |
188 | |
189 printf ("Dumping from %s\n", in_filename); | |
190 printf (" to %s\n", out_filename); | |
191 | |
192 /* We need to round off our heap to NT's allocation unit (64KB). */ | |
193 round_heap (get_allocation_unit ()); | |
194 | |
195 /* Open the undumped executable file. */ | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
196 if (!open_input_file (&in_file, in_filename)) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
197 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
198 printf ("Failed to open %s (%d)...bailing.\n", |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
199 in_filename, GetLastError ()); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
200 exit (1); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
201 } |
12245 | 202 |
203 /* Get the interesting section info, like start and size of .bss... */ | |
204 get_section_info (&in_file); | |
205 | |
206 /* The size of the dumped executable is the size of the original | |
207 executable plus the size of the heap and the size of the .bss section. */ | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
208 heap_index_in_executable = (unsigned long) |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
209 round_to_next ((unsigned char *) in_file.size, get_allocation_unit ()); |
12245 | 210 size = heap_index_in_executable + get_committed_heap_size () + bss_size; |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
211 if (!open_output_file (&out_file, out_filename, size)) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
212 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
213 printf ("Failed to open %s (%d)...bailing.\n", |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
214 out_filename, GetLastError ()); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
215 exit (1); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
216 } |
12245 | 217 |
218 /* Set the flag (before dumping). */ | |
219 need_to_recreate_heap = TRUE; | |
220 | |
221 copy_executable_and_dump_data_section (&in_file, &out_file); | |
222 dump_bss_and_heap (&in_file, &out_file); | |
223 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
224 /* Patch up header fields; profiler is picky about this. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
225 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
226 PIMAGE_DOS_HEADER dos_header; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
227 PIMAGE_NT_HEADERS nt_header; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
228 HANDLE hImagehelp = LoadLibrary ("imagehlp.dll"); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
229 DWORD headersum; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
230 DWORD checksum; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
231 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
232 dos_header = (PIMAGE_DOS_HEADER) out_file.file_base; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
233 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
234 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
235 nt_header->OptionalHeader.CheckSum = 0; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
236 // nt_header->FileHeader.TimeDateStamp = time (NULL); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
237 // dos_header->e_cp = size / 512; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
238 // nt_header->OptionalHeader.SizeOfImage = size; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
239 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
240 pfnCheckSumMappedFile = (void *) GetProcAddress (hImagehelp, "CheckSumMappedFile"); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
241 if (pfnCheckSumMappedFile) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
242 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
243 // nt_header->FileHeader.TimeDateStamp = time (NULL); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
244 pfnCheckSumMappedFile (out_file.file_base, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
245 out_file.size, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
246 &headersum, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
247 &checksum); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
248 nt_header->OptionalHeader.CheckSum = checksum; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
249 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
250 FreeLibrary (hImagehelp); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
251 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
252 |
12245 | 253 close_file_data (&in_file); |
254 close_file_data (&out_file); | |
255 } | |
256 | |
257 | |
258 /* File handling. */ | |
259 | |
260 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
261 int |
12245 | 262 open_input_file (file_data *p_file, char *filename) |
263 { | |
264 HANDLE file; | |
265 HANDLE file_mapping; | |
266 void *file_base; | |
267 unsigned long size, upper_size; | |
268 | |
269 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
270 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
271 if (file == INVALID_HANDLE_VALUE) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
272 return FALSE; |
12245 | 273 |
274 size = GetFileSize (file, &upper_size); | |
275 file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY, | |
276 0, size, NULL); | |
277 if (!file_mapping) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
278 return FALSE; |
12245 | 279 |
280 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size); | |
281 if (file_base == 0) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
282 return FALSE; |
12245 | 283 |
284 p_file->name = filename; | |
285 p_file->size = size; | |
286 p_file->file = file; | |
287 p_file->file_mapping = file_mapping; | |
288 p_file->file_base = file_base; | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
289 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
290 return TRUE; |
12245 | 291 } |
292 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
293 int |
12245 | 294 open_output_file (file_data *p_file, char *filename, unsigned long size) |
295 { | |
296 HANDLE file; | |
297 HANDLE file_mapping; | |
298 void *file_base; | |
13423
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
299 |
12245 | 300 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, |
301 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |
302 if (file == INVALID_HANDLE_VALUE) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
303 return FALSE; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
304 |
12245 | 305 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE, |
306 0, size, NULL); | |
307 if (!file_mapping) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
308 return FALSE; |
12245 | 309 |
310 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size); | |
311 if (file_base == 0) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
312 return FALSE; |
12245 | 313 |
314 p_file->name = filename; | |
315 p_file->size = size; | |
316 p_file->file = file; | |
317 p_file->file_mapping = file_mapping; | |
318 p_file->file_base = file_base; | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
319 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
320 return TRUE; |
12245 | 321 } |
322 | |
323 /* Close the system structures associated with the given file. */ | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
324 void |
12245 | 325 close_file_data (file_data *p_file) |
326 { | |
327 UnmapViewOfFile (p_file->file_base); | |
328 CloseHandle (p_file->file_mapping); | |
329 CloseHandle (p_file->file); | |
330 } | |
331 | |
332 | |
333 /* Routines to manipulate NT executable file sections. */ | |
334 | |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
335 static void |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
336 get_bss_info_from_map_file (file_data *p_infile, PUCHAR *p_bss_start, |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
337 DWORD *p_bss_size) |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
338 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
339 int n, start, len; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
340 char map_filename[MAX_PATH]; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
341 char buffer[256]; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
342 FILE *map; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
343 |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
344 /* Overwrite the .exe extension on the executable file name with |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
345 the .map extension. */ |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
346 strcpy (map_filename, p_infile->name); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
347 n = strlen (map_filename) - 3; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
348 strcpy (&map_filename[n], "map"); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
349 |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
350 map = fopen (map_filename, "r"); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
351 if (!map) |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
352 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
353 printf ("Failed to open map file %s, error %d...bailing out.\n", |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
354 map_filename, GetLastError ()); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
355 exit (-1); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
356 } |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
357 |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
358 while (fgets (buffer, sizeof (buffer), map)) |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
359 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
360 if (!(strstr (buffer, ".bss") && strstr (buffer, "DATA"))) |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
361 continue; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
362 n = sscanf (buffer, " %*d:%x %x", &start, &len); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
363 if (n != 2) |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
364 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
365 printf ("Failed to scan the .bss section line:\n%s", buffer); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
366 exit (-1); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
367 } |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
368 break; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
369 } |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
370 *p_bss_start = (PUCHAR) start; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
371 *p_bss_size = (DWORD) len; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
372 } |
12245 | 373 |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
374 unsigned long |
12245 | 375 get_section_size (PIMAGE_SECTION_HEADER p_section) |
376 { | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
377 /* The true section size, before rounding. Some linkers swap the |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
378 meaning of these two values. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
379 return min (p_section->SizeOfRawData, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
380 p_section->Misc.VirtualSize); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
381 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
382 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
383 /* Return pointer to section header for named section. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
384 IMAGE_SECTION_HEADER * |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
385 find_section (char * name, IMAGE_NT_HEADERS * nt_header) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
386 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
387 PIMAGE_SECTION_HEADER section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
388 int i; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
389 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
390 section = IMAGE_FIRST_SECTION (nt_header); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
391 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
392 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) |
12245 | 393 { |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
394 if (strcmp (section->Name, name) == 0) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
395 return section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
396 section++; |
12245 | 397 } |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
398 return NULL; |
12245 | 399 } |
400 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
401 /* Return pointer to section header for section containing the given |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
402 relative virtual address. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
403 IMAGE_SECTION_HEADER * |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
404 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
405 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
406 PIMAGE_SECTION_HEADER section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
407 int i; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
408 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
409 section = IMAGE_FIRST_SECTION (nt_header); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
410 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
411 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
412 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
413 if (rva >= section->VirtualAddress |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
414 && rva < section->VirtualAddress + section->SizeOfRawData) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
415 return section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
416 section++; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
417 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
418 return NULL; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
419 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
420 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
421 |
12245 | 422 /* Flip through the executable and cache the info necessary for dumping. */ |
423 static void | |
424 get_section_info (file_data *p_infile) | |
425 { | |
426 PIMAGE_DOS_HEADER dos_header; | |
427 PIMAGE_NT_HEADERS nt_header; | |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
428 PIMAGE_SECTION_HEADER section, data_section; |
12245 | 429 unsigned char *ptr; |
430 int i; | |
431 | |
432 dos_header = (PIMAGE_DOS_HEADER) p_infile->file_base; | |
433 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) | |
434 { | |
435 printf ("Unknown EXE header in %s...bailing.\n", p_infile->name); | |
436 exit (1); | |
437 } | |
438 nt_header = (PIMAGE_NT_HEADERS) (((unsigned long) dos_header) + | |
439 dos_header->e_lfanew); | |
440 if (nt_header == NULL) | |
441 { | |
442 printf ("Failed to find IMAGE_NT_HEADER in %s...bailing.\n", | |
443 p_infile->name); | |
444 exit (1); | |
445 } | |
446 | |
447 /* Check the NT header signature ... */ | |
448 if (nt_header->Signature != IMAGE_NT_SIGNATURE) | |
449 { | |
450 printf ("Invalid IMAGE_NT_SIGNATURE 0x%x in %s...bailing.\n", | |
451 nt_header->Signature, p_infile->name); | |
452 } | |
453 | |
454 /* Flip through the sections for .data and .bss ... */ | |
455 section = (PIMAGE_SECTION_HEADER) IMAGE_FIRST_SECTION (nt_header); | |
456 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) | |
457 { | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
458 #ifdef SEPARATE_BSS_SECTION |
12245 | 459 if (!strcmp (section->Name, ".bss")) |
460 { | |
461 /* The .bss section. */ | |
462 ptr = (char *) nt_header->OptionalHeader.ImageBase + | |
463 section->VirtualAddress; | |
464 bss_start = ptr; | |
465 bss_size = get_section_size (section); | |
466 } | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
467 #endif |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
468 #if 0 |
12245 | 469 if (!strcmp (section->Name, ".data")) |
470 { | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
471 /* From lastfile.c */ |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
472 extern char my_edata[]; |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
473 |
12245 | 474 /* The .data section. */ |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
475 data_section = section; |
15146
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
476 ptr = (char *) nt_header->OptionalHeader.ImageBase + |
12245 | 477 section->VirtualAddress; |
478 data_start_va = ptr; | |
479 data_start_file = section->PointerToRawData; | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
480 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
481 /* We want to only write Emacs data back to the executable, |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
482 not any of the library data (if library data is included, |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
483 then a dumped Emacs won't run on system versions other |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
484 than the one Emacs was dumped on). */ |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
485 data_size = my_edata - data_start_va; |
12245 | 486 } |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
487 #else |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
488 if (!strcmp (section->Name, "EMDATA")) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
489 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
490 /* The Emacs initialized data section. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
491 data_section = section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
492 ptr = (char *) nt_header->OptionalHeader.ImageBase + |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
493 section->VirtualAddress; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
494 data_start_va = ptr; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
495 data_start_file = section->PointerToRawData; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
496 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
497 /* Write back the full section. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
498 data_size = get_section_size (section); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
499 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
500 #endif |
12245 | 501 section++; |
502 } | |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
503 |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
504 #ifdef SEPARATE_BSS_SECTION |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
505 if (bss_start == UNINIT_PTR && bss_size == UNINIT_LONG) |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
506 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
507 /* Starting with MSVC 4.0, the .bss section has been eliminated |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
508 and appended virtually to the end of the .data section. Our |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
509 only hint about where the .bss section starts in the address |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
510 comes from the SizeOfRawData field in the .data section |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
511 header. Unfortunately, this field is only approximate, as it |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
512 is a rounded number and is typically rounded just beyond the |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
513 start of the .bss section. To find the start and size of the |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
514 .bss section exactly, we have to peek into the map file. */ |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
515 get_bss_info_from_map_file (p_infile, &ptr, &bss_size); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
516 bss_start = ptr + nt_header->OptionalHeader.ImageBase |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
517 + data_section->VirtualAddress; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
518 } |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
519 #else |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
520 bss_start = my_begbss; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
521 bss_size = my_endbss - bss_start; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
522 #endif |
12245 | 523 } |
524 | |
525 | |
526 /* The dump routines. */ | |
527 | |
528 static void | |
529 copy_executable_and_dump_data_section (file_data *p_infile, | |
530 file_data *p_outfile) | |
531 { | |
532 unsigned char *data_file, *data_va; | |
533 unsigned long size, index; | |
534 | |
535 /* Get a pointer to where the raw data should go in the executable file. */ | |
536 data_file = (char *) p_outfile->file_base + data_start_file; | |
537 | |
538 /* Get a pointer to the raw data in our address space. */ | |
539 data_va = data_start_va; | |
540 | |
541 size = (DWORD) data_file - (DWORD) p_outfile->file_base; | |
542 printf ("Copying executable up to data section...\n"); | |
543 printf ("\t0x%08x Offset in input file.\n", 0); | |
544 printf ("\t0x%08x Offset in output file.\n", 0); | |
545 printf ("\t0x%08x Size in bytes.\n", size); | |
546 memcpy (p_outfile->file_base, p_infile->file_base, size); | |
547 | |
548 size = data_size; | |
549 printf ("Dumping .data section...\n"); | |
550 printf ("\t0x%08x Address in process.\n", data_va); | |
551 printf ("\t0x%08x Offset in output file.\n", | |
552 data_file - p_outfile->file_base); | |
553 printf ("\t0x%08x Size in bytes.\n", size); | |
554 memcpy (data_file, data_va, size); | |
555 | |
556 index = (DWORD) data_file + size - (DWORD) p_outfile->file_base; | |
557 size = p_infile->size - index; | |
558 printf ("Copying rest of executable...\n"); | |
559 printf ("\t0x%08x Offset in input file.\n", index); | |
560 printf ("\t0x%08x Offset in output file.\n", index); | |
561 printf ("\t0x%08x Size in bytes.\n", size); | |
562 memcpy ((char *) p_outfile->file_base + index, | |
563 (char *) p_infile->file_base + index, size); | |
564 } | |
565 | |
566 static void | |
567 dump_bss_and_heap (file_data *p_infile, file_data *p_outfile) | |
568 { | |
569 unsigned char *heap_data, *bss_data; | |
570 unsigned long size, index; | |
571 | |
572 printf ("Dumping heap into executable...\n"); | |
573 | |
574 index = heap_index_in_executable; | |
575 size = get_committed_heap_size (); | |
576 heap_data = get_heap_start (); | |
577 | |
578 printf ("\t0x%08x Heap start in process.\n", heap_data); | |
579 printf ("\t0x%08x Heap offset in executable.\n", index); | |
580 printf ("\t0x%08x Heap size in bytes.\n", size); | |
581 | |
582 memcpy ((PUCHAR) p_outfile->file_base + index, heap_data, size); | |
583 | |
584 printf ("Dumping .bss into executable...\n"); | |
585 | |
586 index += size; | |
587 size = bss_size; | |
588 bss_data = bss_start; | |
589 | |
590 printf ("\t0x%08x BSS start in process.\n", bss_data); | |
591 printf ("\t0x%08x BSS offset in executable.\n", index); | |
592 printf ("\t0x%08x BSS size in bytes.\n", size); | |
593 memcpy ((char *) p_outfile->file_base + index, bss_data, size); | |
594 } | |
595 | |
596 | |
597 /* Reload and remap routines. */ | |
598 | |
599 | |
600 /* Load the dumped .bss section into the .bss area of our address space. */ | |
601 void | |
602 read_in_bss (char *filename) | |
603 { | |
604 HANDLE file; | |
605 unsigned long size, index, n_read, total_read; | |
606 char buffer[512], *bss; | |
607 int i; | |
608 | |
609 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
610 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
611 if (file == INVALID_HANDLE_VALUE) | |
612 { | |
613 i = GetLastError (); | |
614 exit (1); | |
615 } | |
616 | |
617 /* Seek to where the .bss section is tucked away after the heap... */ | |
618 index = heap_index_in_executable + get_committed_heap_size (); | |
619 if (SetFilePointer (file, index, NULL, FILE_BEGIN) == 0xFFFFFFFF) | |
620 { | |
621 i = GetLastError (); | |
622 exit (1); | |
623 } | |
624 | |
625 | |
626 /* Ok, read in the saved .bss section and initialize all | |
627 uninitialized variables. */ | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
628 if (!ReadFile (file, bss_start, bss_size, &n_read, NULL)) |
12245 | 629 { |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
630 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
631 exit (1); |
12245 | 632 } |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
633 |
12245 | 634 CloseHandle (file); |
635 } | |
636 | |
637 /* Map the heap dumped into the executable file into our address space. */ | |
638 void | |
639 map_in_heap (char *filename) | |
640 { | |
641 HANDLE file; | |
642 HANDLE file_mapping; | |
643 void *file_base; | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
644 unsigned long size, upper_size, n_read; |
12245 | 645 int i; |
646 | |
647 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
648 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
649 if (file == INVALID_HANDLE_VALUE) | |
650 { | |
651 i = GetLastError (); | |
652 exit (1); | |
653 } | |
654 | |
655 size = GetFileSize (file, &upper_size); | |
656 file_mapping = CreateFileMapping (file, NULL, PAGE_WRITECOPY, | |
657 0, size, NULL); | |
658 if (!file_mapping) | |
659 { | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
660 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
661 exit (1); |
12245 | 662 } |
663 | |
664 size = get_committed_heap_size (); | |
665 file_base = MapViewOfFileEx (file_mapping, FILE_MAP_COPY, 0, | |
666 heap_index_in_executable, size, | |
667 get_heap_start ()); | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
668 if (file_base != 0) |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
669 { |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
670 return; |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
671 } |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
672 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
673 /* If we don't succeed with the mapping, then copy from the |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
674 data into the heap. */ |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
675 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
676 CloseHandle (file_mapping); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
677 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
678 if (VirtualAlloc (get_heap_start (), get_committed_heap_size (), |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
679 MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) == NULL) |
12245 | 680 { |
681 i = GetLastError (); | |
682 exit (1); | |
683 } | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
684 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
685 /* Seek to the location of the heap data in the executable. */ |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
686 i = heap_index_in_executable; |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
687 if (SetFilePointer (file, i, NULL, FILE_BEGIN) == 0xFFFFFFFF) |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
688 { |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
689 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
690 exit (1); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
691 } |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
692 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
693 /* Read in the data. */ |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
694 if (!ReadFile (file, get_heap_start (), |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
695 get_committed_heap_size (), &n_read, NULL)) |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
696 { |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
697 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
698 exit (1); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
699 } |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
700 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
701 CloseHandle (file); |
12245 | 702 } |