Mercurial > emacs
annotate src/unexw32.c @ 20578:7eb29ad824eb
(file-cache-minibuffer-complete): Accept a prefix arg.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 03 Jan 1998 00:04:35 +0000 |
parents | 9fa57c73882d |
children | c0496e62b737 |
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 |
12245 | 50 /* Basically, our "initialized" flag. */ |
51 BOOL need_to_recreate_heap = FALSE; | |
52 | |
53 /* So we can find our heap in the file to recreate it. */ | |
54 unsigned long heap_index_in_executable = 0; | |
55 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
56 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
|
57 int open_output_file (file_data *p_file, char *name, unsigned long size); |
12245 | 58 void close_file_data (file_data *p_file); |
59 | |
60 void get_section_info (file_data *p_file); | |
61 void copy_executable_and_dump_data_section (file_data *, file_data *); | |
62 void dump_bss_and_heap (file_data *p_infile, file_data *p_outfile); | |
63 | |
64 /* Cached info about the .data section in the executable. */ | |
65 PUCHAR data_start_va = 0; | |
66 DWORD data_start_file = 0; | |
67 DWORD data_size = 0; | |
68 | |
69 /* Cached info about the .bss section in the executable. */ | |
70 PUCHAR bss_start = 0; | |
71 DWORD bss_size = 0; | |
72 | |
13423
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
73 #ifdef HAVE_NTGUI |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
74 HINSTANCE hinst = NULL; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
75 HINSTANCE hprevinst = NULL; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
76 LPSTR lpCmdLine = ""; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
77 int nCmdShow = 0; |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
78 #endif /* HAVE_NTGUI */ |
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
79 |
12245 | 80 /* Startup code for running on NT. When we are running as the dumped |
81 version, we need to bootstrap our heap and .bss section into our | |
82 address space before we can actually hand off control to the startup | |
83 code supplied by NT (primarily because that code relies upon malloc ()). */ | |
84 void | |
85 _start (void) | |
86 { | |
87 extern void mainCRTStartup (void); | |
88 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
89 #if 0 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
90 /* 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
|
91 running under the MSVC profiler. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
92 if (GetEnvironmentVariable ("EMACS_DEBUG", NULL, 0) > 0) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
93 DebugBreak (); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
94 #endif |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
95 |
12245 | 96 /* Cache system info, e.g., the NT page size. */ |
97 cache_system_info (); | |
98 | |
99 /* If we're a dumped version of emacs then we need to recreate | |
100 our heap and play tricks with our .bss section. Do this before | |
101 start up. (WARNING: Do not put any code before this section | |
102 that relies upon malloc () and runs in the dumped version. It | |
103 won't work.) */ | |
104 if (need_to_recreate_heap) | |
105 { | |
106 char executable_path[MAX_PATH]; | |
107 | |
108 if (GetModuleFileName (NULL, executable_path, MAX_PATH) == 0) | |
109 { | |
110 printf ("Failed to find path for executable.\n"); | |
111 exit (1); | |
112 } | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
113 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
114 #if 1 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
115 /* 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
|
116 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
|
117 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
|
118 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
|
119 .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
|
120 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
|
121 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
122 char * p = strrchr (executable_path, '.'); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
123 if (p && p[1] == '_') |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
124 p[1] = 'e'; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
125 } |
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 /* 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
|
128 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
129 char * p = strrchr (executable_path, '\\'); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
130 strcpy (p, "\\emacs.exe"); |
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 #endif |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
133 |
12245 | 134 recreate_heap (executable_path); |
135 need_to_recreate_heap = FALSE; | |
136 } | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
137 else |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
138 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
139 /* 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
|
140 sbrk (0); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
141 } |
12245 | 142 |
143 /* The default behavior is to treat files as binary and patch up | |
144 text files appropriately, in accordance with the MSDOS code. */ | |
145 _fmode = O_BINARY; | |
146 | |
147 /* This prevents ctrl-c's in shells running while we're suspended from | |
148 having us exit. */ | |
149 SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrl_c_handler, TRUE); | |
150 | |
151 /* Invoke the NT CRT startup routine now that our housecleaning | |
152 is finished. */ | |
13423
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
153 #ifdef HAVE_NTGUI |
15146
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
154 /* determine WinMain args like crt0.c does */ |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
155 hinst = GetModuleHandle(NULL); |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
156 lpCmdLine = GetCommandLine(); |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
157 nCmdShow = SW_SHOWDEFAULT; |
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
158 #endif |
12245 | 159 mainCRTStartup (); |
160 } | |
161 | |
14036 | 162 /* Dump out .data and .bss sections into a new executable. */ |
12245 | 163 void |
164 unexec (char *new_name, char *old_name, void *start_data, void *start_bss, | |
165 void *entry_address) | |
166 { | |
167 file_data in_file, out_file; | |
168 char out_filename[MAX_PATH], in_filename[MAX_PATH]; | |
169 unsigned long size; | |
170 char *ptr; | |
171 | |
172 /* Make sure that the input and output filenames have the | |
173 ".exe" extension...patch them up if they don't. */ | |
174 strcpy (in_filename, old_name); | |
175 ptr = in_filename + strlen (in_filename) - 4; | |
176 if (strcmp (ptr, ".exe")) | |
177 strcat (in_filename, ".exe"); | |
178 | |
179 strcpy (out_filename, new_name); | |
180 ptr = out_filename + strlen (out_filename) - 4; | |
181 if (strcmp (ptr, ".exe")) | |
182 strcat (out_filename, ".exe"); | |
183 | |
184 printf ("Dumping from %s\n", in_filename); | |
185 printf (" to %s\n", out_filename); | |
186 | |
187 /* We need to round off our heap to NT's allocation unit (64KB). */ | |
188 round_heap (get_allocation_unit ()); | |
189 | |
190 /* Open the undumped executable file. */ | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
191 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
|
192 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
193 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
|
194 in_filename, GetLastError ()); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
195 exit (1); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
196 } |
12245 | 197 |
198 /* Get the interesting section info, like start and size of .bss... */ | |
199 get_section_info (&in_file); | |
200 | |
201 /* The size of the dumped executable is the size of the original | |
202 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
|
203 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
|
204 round_to_next ((unsigned char *) in_file.size, get_allocation_unit ()); |
12245 | 205 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
|
206 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
|
207 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
208 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
|
209 out_filename, GetLastError ()); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
210 exit (1); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
211 } |
12245 | 212 |
213 /* Set the flag (before dumping). */ | |
214 need_to_recreate_heap = TRUE; | |
215 | |
216 copy_executable_and_dump_data_section (&in_file, &out_file); | |
217 dump_bss_and_heap (&in_file, &out_file); | |
218 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
219 /* 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
|
220 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
221 PIMAGE_DOS_HEADER dos_header; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
222 PIMAGE_NT_HEADERS nt_header; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
223 HANDLE hImagehelp = LoadLibrary ("imagehlp.dll"); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
224 DWORD headersum; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
225 DWORD checksum; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
226 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
227 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
|
228 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
|
229 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
230 nt_header->OptionalHeader.CheckSum = 0; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
231 // nt_header->FileHeader.TimeDateStamp = time (NULL); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
232 // dos_header->e_cp = size / 512; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
233 // nt_header->OptionalHeader.SizeOfImage = size; |
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 pfnCheckSumMappedFile = (void *) GetProcAddress (hImagehelp, "CheckSumMappedFile"); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
236 if (pfnCheckSumMappedFile) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
237 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
238 // nt_header->FileHeader.TimeDateStamp = time (NULL); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
239 pfnCheckSumMappedFile (out_file.file_base, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
240 out_file.size, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
241 &headersum, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
242 &checksum); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
243 nt_header->OptionalHeader.CheckSum = checksum; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
244 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
245 FreeLibrary (hImagehelp); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
246 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
247 |
12245 | 248 close_file_data (&in_file); |
249 close_file_data (&out_file); | |
250 } | |
251 | |
252 | |
253 /* File handling. */ | |
254 | |
255 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
256 int |
12245 | 257 open_input_file (file_data *p_file, char *filename) |
258 { | |
259 HANDLE file; | |
260 HANDLE file_mapping; | |
261 void *file_base; | |
262 unsigned long size, upper_size; | |
263 | |
264 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
265 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
266 if (file == INVALID_HANDLE_VALUE) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
267 return FALSE; |
12245 | 268 |
269 size = GetFileSize (file, &upper_size); | |
270 file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY, | |
271 0, size, NULL); | |
272 if (!file_mapping) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
273 return FALSE; |
12245 | 274 |
275 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size); | |
276 if (file_base == 0) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
277 return FALSE; |
12245 | 278 |
279 p_file->name = filename; | |
280 p_file->size = size; | |
281 p_file->file = file; | |
282 p_file->file_mapping = file_mapping; | |
283 p_file->file_base = file_base; | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
284 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
285 return TRUE; |
12245 | 286 } |
287 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
288 int |
12245 | 289 open_output_file (file_data *p_file, char *filename, unsigned long size) |
290 { | |
291 HANDLE file; | |
292 HANDLE file_mapping; | |
293 void *file_base; | |
13423
eefa4f720371
[HAVE_NTGUI] (WinMain): New procedure.
Geoff Voelker <voelker@cs.washington.edu>
parents:
12454
diff
changeset
|
294 |
12245 | 295 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, |
296 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |
297 if (file == INVALID_HANDLE_VALUE) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
298 return FALSE; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
299 |
12245 | 300 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE, |
301 0, size, NULL); | |
302 if (!file_mapping) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
303 return FALSE; |
12245 | 304 |
305 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size); | |
306 if (file_base == 0) | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
307 return FALSE; |
12245 | 308 |
309 p_file->name = filename; | |
310 p_file->size = size; | |
311 p_file->file = file; | |
312 p_file->file_mapping = file_mapping; | |
313 p_file->file_base = file_base; | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
314 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
315 return TRUE; |
12245 | 316 } |
317 | |
318 /* 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
|
319 void |
12245 | 320 close_file_data (file_data *p_file) |
321 { | |
322 UnmapViewOfFile (p_file->file_base); | |
323 CloseHandle (p_file->file_mapping); | |
324 CloseHandle (p_file->file); | |
325 } | |
326 | |
327 | |
328 /* Routines to manipulate NT executable file sections. */ | |
329 | |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
330 static void |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
331 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
|
332 DWORD *p_bss_size) |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
333 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
334 int n, start, len; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
335 char map_filename[MAX_PATH]; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
336 char buffer[256]; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
337 FILE *map; |
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 /* 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
|
340 the .map extension. */ |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
341 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
|
342 n = strlen (map_filename) - 3; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
343 strcpy (&map_filename[n], "map"); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
344 |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
345 map = fopen (map_filename, "r"); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
346 if (!map) |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
347 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
348 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
|
349 map_filename, GetLastError ()); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
350 exit (-1); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
351 } |
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 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
|
354 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
355 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
|
356 continue; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
357 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
|
358 if (n != 2) |
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 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
|
361 exit (-1); |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
362 } |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
363 break; |
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 *p_bss_start = (PUCHAR) start; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
366 *p_bss_size = (DWORD) len; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
367 } |
12245 | 368 |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
369 unsigned long |
12245 | 370 get_section_size (PIMAGE_SECTION_HEADER p_section) |
371 { | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
372 /* 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
|
373 meaning of these two values. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
374 return min (p_section->SizeOfRawData, |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
375 p_section->Misc.VirtualSize); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
376 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
377 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
378 /* 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
|
379 IMAGE_SECTION_HEADER * |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
380 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
|
381 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
382 PIMAGE_SECTION_HEADER section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
383 int i; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
384 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
385 section = IMAGE_FIRST_SECTION (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 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) |
12245 | 388 { |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
389 if (strcmp (section->Name, name) == 0) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
390 return section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
391 section++; |
12245 | 392 } |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
393 return NULL; |
12245 | 394 } |
395 | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
396 /* 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
|
397 relative virtual address. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
398 IMAGE_SECTION_HEADER * |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
399 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
|
400 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
401 PIMAGE_SECTION_HEADER section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
402 int i; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
403 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
404 section = IMAGE_FIRST_SECTION (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 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
|
407 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
408 if (rva >= section->VirtualAddress |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
409 && rva < section->VirtualAddress + section->SizeOfRawData) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
410 return section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
411 section++; |
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 return NULL; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
414 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
415 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
416 |
12245 | 417 /* Flip through the executable and cache the info necessary for dumping. */ |
418 static void | |
419 get_section_info (file_data *p_infile) | |
420 { | |
421 PIMAGE_DOS_HEADER dos_header; | |
422 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
|
423 PIMAGE_SECTION_HEADER section, data_section; |
12245 | 424 unsigned char *ptr; |
425 int i; | |
426 | |
427 dos_header = (PIMAGE_DOS_HEADER) p_infile->file_base; | |
428 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) | |
429 { | |
430 printf ("Unknown EXE header in %s...bailing.\n", p_infile->name); | |
431 exit (1); | |
432 } | |
433 nt_header = (PIMAGE_NT_HEADERS) (((unsigned long) dos_header) + | |
434 dos_header->e_lfanew); | |
435 if (nt_header == NULL) | |
436 { | |
437 printf ("Failed to find IMAGE_NT_HEADER in %s...bailing.\n", | |
438 p_infile->name); | |
439 exit (1); | |
440 } | |
441 | |
442 /* Check the NT header signature ... */ | |
443 if (nt_header->Signature != IMAGE_NT_SIGNATURE) | |
444 { | |
445 printf ("Invalid IMAGE_NT_SIGNATURE 0x%x in %s...bailing.\n", | |
446 nt_header->Signature, p_infile->name); | |
447 } | |
448 | |
449 /* Flip through the sections for .data and .bss ... */ | |
450 section = (PIMAGE_SECTION_HEADER) IMAGE_FIRST_SECTION (nt_header); | |
451 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) | |
452 { | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
453 #ifdef SEPARATE_BSS_SECTION |
12245 | 454 if (!strcmp (section->Name, ".bss")) |
455 { | |
456 /* The .bss section. */ | |
457 ptr = (char *) nt_header->OptionalHeader.ImageBase + | |
458 section->VirtualAddress; | |
459 bss_start = ptr; | |
460 bss_size = get_section_size (section); | |
461 } | |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
462 #endif |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
463 #if 0 |
12245 | 464 if (!strcmp (section->Name, ".data")) |
465 { | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
466 /* From lastfile.c */ |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
467 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
|
468 |
12245 | 469 /* The .data section. */ |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
470 data_section = section; |
15146
be6560506cce
(WinMain): Function removed.
Geoff Voelker <voelker@cs.washington.edu>
parents:
14812
diff
changeset
|
471 ptr = (char *) nt_header->OptionalHeader.ImageBase + |
12245 | 472 section->VirtualAddress; |
473 data_start_va = ptr; | |
474 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
|
475 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
476 /* 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
|
477 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
|
478 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
|
479 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
|
480 data_size = my_edata - data_start_va; |
12245 | 481 } |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
482 #else |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
483 if (!strcmp (section->Name, "EMDATA")) |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
484 { |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
485 /* The Emacs initialized data section. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
486 data_section = section; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
487 ptr = (char *) nt_header->OptionalHeader.ImageBase + |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
488 section->VirtualAddress; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
489 data_start_va = ptr; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
490 data_start_file = section->PointerToRawData; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
491 |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
492 /* Write back the full section. */ |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
493 data_size = get_section_size (section); |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
494 } |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
495 #endif |
12245 | 496 section++; |
497 } | |
13830
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
498 |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
499 #ifdef SEPARATE_BSS_SECTION |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
500 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
|
501 { |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
502 /* 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
|
503 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
|
504 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
|
505 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
|
506 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
|
507 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
|
508 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
|
509 .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
|
510 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
|
511 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
|
512 + data_section->VirtualAddress; |
8d30151f4acb
(get_bss_info_from_map_file): New function.
Geoff Voelker <voelker@cs.washington.edu>
parents:
13423
diff
changeset
|
513 } |
19703
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
514 #else |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
515 bss_start = my_begbss; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
516 bss_size = my_endbss - bss_start; |
9fa57c73882d
Include config.h and time.h.
Geoff Voelker <voelker@cs.washington.edu>
parents:
18506
diff
changeset
|
517 #endif |
12245 | 518 } |
519 | |
520 | |
521 /* The dump routines. */ | |
522 | |
523 static void | |
524 copy_executable_and_dump_data_section (file_data *p_infile, | |
525 file_data *p_outfile) | |
526 { | |
527 unsigned char *data_file, *data_va; | |
528 unsigned long size, index; | |
529 | |
530 /* Get a pointer to where the raw data should go in the executable file. */ | |
531 data_file = (char *) p_outfile->file_base + data_start_file; | |
532 | |
533 /* Get a pointer to the raw data in our address space. */ | |
534 data_va = data_start_va; | |
535 | |
536 size = (DWORD) data_file - (DWORD) p_outfile->file_base; | |
537 printf ("Copying executable up to data section...\n"); | |
538 printf ("\t0x%08x Offset in input file.\n", 0); | |
539 printf ("\t0x%08x Offset in output file.\n", 0); | |
540 printf ("\t0x%08x Size in bytes.\n", size); | |
541 memcpy (p_outfile->file_base, p_infile->file_base, size); | |
542 | |
543 size = data_size; | |
544 printf ("Dumping .data section...\n"); | |
545 printf ("\t0x%08x Address in process.\n", data_va); | |
546 printf ("\t0x%08x Offset in output file.\n", | |
547 data_file - p_outfile->file_base); | |
548 printf ("\t0x%08x Size in bytes.\n", size); | |
549 memcpy (data_file, data_va, size); | |
550 | |
551 index = (DWORD) data_file + size - (DWORD) p_outfile->file_base; | |
552 size = p_infile->size - index; | |
553 printf ("Copying rest of executable...\n"); | |
554 printf ("\t0x%08x Offset in input file.\n", index); | |
555 printf ("\t0x%08x Offset in output file.\n", index); | |
556 printf ("\t0x%08x Size in bytes.\n", size); | |
557 memcpy ((char *) p_outfile->file_base + index, | |
558 (char *) p_infile->file_base + index, size); | |
559 } | |
560 | |
561 static void | |
562 dump_bss_and_heap (file_data *p_infile, file_data *p_outfile) | |
563 { | |
564 unsigned char *heap_data, *bss_data; | |
565 unsigned long size, index; | |
566 | |
567 printf ("Dumping heap into executable...\n"); | |
568 | |
569 index = heap_index_in_executable; | |
570 size = get_committed_heap_size (); | |
571 heap_data = get_heap_start (); | |
572 | |
573 printf ("\t0x%08x Heap start in process.\n", heap_data); | |
574 printf ("\t0x%08x Heap offset in executable.\n", index); | |
575 printf ("\t0x%08x Heap size in bytes.\n", size); | |
576 | |
577 memcpy ((PUCHAR) p_outfile->file_base + index, heap_data, size); | |
578 | |
579 printf ("Dumping .bss into executable...\n"); | |
580 | |
581 index += size; | |
582 size = bss_size; | |
583 bss_data = bss_start; | |
584 | |
585 printf ("\t0x%08x BSS start in process.\n", bss_data); | |
586 printf ("\t0x%08x BSS offset in executable.\n", index); | |
587 printf ("\t0x%08x BSS size in bytes.\n", size); | |
588 memcpy ((char *) p_outfile->file_base + index, bss_data, size); | |
589 } | |
590 | |
591 | |
592 /* Reload and remap routines. */ | |
593 | |
594 | |
595 /* Load the dumped .bss section into the .bss area of our address space. */ | |
596 void | |
597 read_in_bss (char *filename) | |
598 { | |
599 HANDLE file; | |
600 unsigned long size, index, n_read, total_read; | |
601 char buffer[512], *bss; | |
602 int i; | |
603 | |
604 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
605 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
606 if (file == INVALID_HANDLE_VALUE) | |
607 { | |
608 i = GetLastError (); | |
609 exit (1); | |
610 } | |
611 | |
612 /* Seek to where the .bss section is tucked away after the heap... */ | |
613 index = heap_index_in_executable + get_committed_heap_size (); | |
614 if (SetFilePointer (file, index, NULL, FILE_BEGIN) == 0xFFFFFFFF) | |
615 { | |
616 i = GetLastError (); | |
617 exit (1); | |
618 } | |
619 | |
620 | |
621 /* Ok, read in the saved .bss section and initialize all | |
622 uninitialized variables. */ | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
623 if (!ReadFile (file, bss_start, bss_size, &n_read, NULL)) |
12245 | 624 { |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
625 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
626 exit (1); |
12245 | 627 } |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
628 |
12245 | 629 CloseHandle (file); |
630 } | |
631 | |
632 /* Map the heap dumped into the executable file into our address space. */ | |
633 void | |
634 map_in_heap (char *filename) | |
635 { | |
636 HANDLE file; | |
637 HANDLE file_mapping; | |
638 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
|
639 unsigned long size, upper_size, n_read; |
12245 | 640 int i; |
641 | |
642 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
643 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
644 if (file == INVALID_HANDLE_VALUE) | |
645 { | |
646 i = GetLastError (); | |
647 exit (1); | |
648 } | |
649 | |
650 size = GetFileSize (file, &upper_size); | |
651 file_mapping = CreateFileMapping (file, NULL, PAGE_WRITECOPY, | |
652 0, size, NULL); | |
653 if (!file_mapping) | |
654 { | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
655 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
656 exit (1); |
12245 | 657 } |
658 | |
659 size = get_committed_heap_size (); | |
660 file_base = MapViewOfFileEx (file_mapping, FILE_MAP_COPY, 0, | |
661 heap_index_in_executable, size, | |
662 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
|
663 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
|
664 { |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
665 return; |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
666 } |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
667 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
668 /* 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
|
669 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
|
670 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
671 CloseHandle (file_mapping); |
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 (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
|
674 MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) == NULL) |
12245 | 675 { |
676 i = GetLastError (); | |
677 exit (1); | |
678 } | |
12454
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
679 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
680 /* 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
|
681 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
|
682 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
|
683 { |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
684 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
685 exit (1); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
686 } |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
687 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
688 /* 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
|
689 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
|
690 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
|
691 { |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
692 i = GetLastError (); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
693 exit (1); |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
694 } |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
695 |
3f4da17a7cd8
(get_section_info): Set the end of the data region
Geoff Voelker <voelker@cs.washington.edu>
parents:
12245
diff
changeset
|
696 CloseHandle (file); |
12245 | 697 } |