Mercurial > emacs
annotate nt/addsection.c @ 61263:56619c3aaf99
(fancy-splash-text): Shorten default text of
"Emacs Tutorial" line. Also, if the current language env
indicates an available tutorial file other than TUTORIAL,
extract its title and append it to the line in parentheses.
(fancy-splash-insert): If arg is a thunk, funcall it.
author | Thien-Thi Nguyen <ttn@gnuvola.org> |
---|---|
date | Mon, 04 Apr 2005 07:41:58 +0000 |
parents | 695cf19ef79e |
children | c16acb8501d2 375f2633d815 |
rev | line source |
---|---|
24097 | 1 /* Add an uninitialized data section to an executable. |
2 Copyright (C) 1999 Free Software Foundation, Inc. | |
3 | |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2, or (at your option) | |
9 any later version. | |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 Boston, MA 02111-1307, USA. | |
20 | |
21 Andrew Innes <andrewi@harlequin.co.uk> 04-Jan-1999 | |
22 based on code from unexw32.c | |
23 */ | |
24 | |
25 #include <stdlib.h> | |
26 #include <stdio.h> | |
27 #include <fcntl.h> | |
28 #include <time.h> | |
31347
cdc16c6e33be
(_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents:
31085
diff
changeset
|
29 #ifdef __GNUC__ |
cdc16c6e33be
(_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents:
31085
diff
changeset
|
30 #define _ANONYMOUS_UNION |
cdc16c6e33be
(_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents:
31085
diff
changeset
|
31 #define _ANONYMOUS_STRUCT |
cdc16c6e33be
(_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents:
31085
diff
changeset
|
32 #endif |
24097 | 33 #include <windows.h> |
34 | |
35 /* Include relevant definitions from IMAGEHLP.H, which can be found | |
36 in \\win32sdk\mstools\samples\image\include\imagehlp.h. */ | |
37 | |
38 PIMAGE_NT_HEADERS | |
39 (__stdcall * pfnCheckSumMappedFile) (LPVOID BaseAddress, | |
40 DWORD FileLength, | |
41 LPDWORD HeaderSum, | |
42 LPDWORD CheckSum); | |
43 | |
44 #undef min | |
45 #undef max | |
46 #define min(x, y) (((x) < (y)) ? (x) : (y)) | |
47 #define max(x, y) (((x) > (y)) ? (x) : (y)) | |
48 | |
49 | |
50 /* File handling. */ | |
51 | |
52 typedef struct file_data { | |
53 char *name; | |
54 unsigned long size; | |
55 HANDLE file; | |
56 HANDLE file_mapping; | |
57 unsigned char *file_base; | |
58 } file_data; | |
59 | |
60 int | |
61 open_input_file (file_data *p_file, char *filename) | |
62 { | |
63 HANDLE file; | |
64 HANDLE file_mapping; | |
65 void *file_base; | |
66 unsigned long size, upper_size; | |
67 | |
68 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, | |
69 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
70 if (file == INVALID_HANDLE_VALUE) |
24097 | 71 return FALSE; |
72 | |
73 size = GetFileSize (file, &upper_size); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
74 file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY, |
24097 | 75 0, size, NULL); |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
76 if (!file_mapping) |
24097 | 77 return FALSE; |
78 | |
79 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
80 if (file_base == 0) |
24097 | 81 return FALSE; |
82 | |
83 p_file->name = filename; | |
84 p_file->size = size; | |
85 p_file->file = file; | |
86 p_file->file_mapping = file_mapping; | |
87 p_file->file_base = file_base; | |
88 | |
89 return TRUE; | |
90 } | |
91 | |
92 int | |
93 open_output_file (file_data *p_file, char *filename, unsigned long size) | |
94 { | |
95 HANDLE file; | |
96 HANDLE file_mapping; | |
97 void *file_base; | |
98 | |
99 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, | |
100 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
101 if (file == INVALID_HANDLE_VALUE) |
24097 | 102 return FALSE; |
103 | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
104 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE, |
24097 | 105 0, size, NULL); |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
106 if (!file_mapping) |
24097 | 107 return FALSE; |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
108 |
24097 | 109 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size); |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
110 if (file_base == 0) |
24097 | 111 return FALSE; |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
112 |
24097 | 113 p_file->name = filename; |
114 p_file->size = size; | |
115 p_file->file = file; | |
116 p_file->file_mapping = file_mapping; | |
117 p_file->file_base = file_base; | |
118 | |
119 return TRUE; | |
120 } | |
121 | |
122 /* Close the system structures associated with the given file. */ | |
123 void | |
124 close_file_data (file_data *p_file) | |
125 { | |
126 UnmapViewOfFile (p_file->file_base); | |
127 CloseHandle (p_file->file_mapping); | |
128 /* For the case of output files, set final size. */ | |
129 SetFilePointer (p_file->file, p_file->size, NULL, FILE_BEGIN); | |
130 SetEndOfFile (p_file->file); | |
131 CloseHandle (p_file->file); | |
132 } | |
133 | |
134 | |
135 /* Routines to manipulate NT executable file sections. */ | |
136 | |
137 unsigned long | |
138 get_unrounded_section_size (PIMAGE_SECTION_HEADER p_section) | |
139 { | |
140 /* The true section size, before rounding, for an initialized data or | |
141 code section. (Supposedly some linkers swap the meaning of these | |
142 two values.) */ | |
143 return min (p_section->SizeOfRawData, | |
144 p_section->Misc.VirtualSize); | |
145 } | |
146 | |
147 /* Return pointer to section header for named section. */ | |
148 IMAGE_SECTION_HEADER * | |
149 find_section (char * name, IMAGE_NT_HEADERS * nt_header) | |
150 { | |
151 PIMAGE_SECTION_HEADER section; | |
152 int i; | |
153 | |
154 section = IMAGE_FIRST_SECTION (nt_header); | |
155 | |
156 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) | |
157 { | |
158 if (strcmp (section->Name, name) == 0) | |
159 return section; | |
160 section++; | |
161 } | |
162 return NULL; | |
163 } | |
164 | |
165 /* Return pointer to section header for section containing the given | |
166 relative virtual address. */ | |
167 IMAGE_SECTION_HEADER * | |
168 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header) | |
169 { | |
170 PIMAGE_SECTION_HEADER section; | |
171 int i; | |
172 | |
173 section = IMAGE_FIRST_SECTION (nt_header); | |
174 | |
175 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) | |
176 { | |
177 /* Some linkers (eg. the NT SDK linker I believe) swapped the | |
178 meaning of these two values - or rather, they ignored | |
179 VirtualSize entirely and always set it to zero. This affects | |
180 some very old exes (eg. gzip dated Dec 1993). Since | |
181 w32_executable_type relies on this function to work reliably, | |
182 we need to cope with this. */ | |
183 DWORD real_size = max (section->SizeOfRawData, | |
184 section->Misc.VirtualSize); | |
185 if (rva >= section->VirtualAddress | |
186 && rva < section->VirtualAddress + real_size) | |
187 return section; | |
188 section++; | |
189 } | |
190 return NULL; | |
191 } | |
192 | |
193 /* Return pointer to section header for section containing the given | |
194 offset in its raw data area. */ | |
195 IMAGE_SECTION_HEADER * | |
196 offset_to_section (DWORD offset, IMAGE_NT_HEADERS * nt_header) | |
197 { | |
198 PIMAGE_SECTION_HEADER section; | |
199 int i; | |
200 | |
201 section = IMAGE_FIRST_SECTION (nt_header); | |
202 | |
203 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) | |
204 { | |
205 if (offset >= section->PointerToRawData | |
206 && offset < section->PointerToRawData + section->SizeOfRawData) | |
207 return section; | |
208 section++; | |
209 } | |
210 return NULL; | |
211 } | |
212 | |
213 /* Return offset to an object in dst, given offset in src. We assume | |
214 there is at least one section in both src and dst images, and that | |
215 the some sections may have been added to dst (after sections in src). */ | |
216 static DWORD | |
217 relocate_offset (DWORD offset, | |
218 IMAGE_NT_HEADERS * src_nt_header, | |
219 IMAGE_NT_HEADERS * dst_nt_header) | |
220 { | |
221 PIMAGE_SECTION_HEADER src_section = IMAGE_FIRST_SECTION (src_nt_header); | |
222 PIMAGE_SECTION_HEADER dst_section = IMAGE_FIRST_SECTION (dst_nt_header); | |
223 int i = 0; | |
224 | |
225 while (offset >= src_section->PointerToRawData) | |
226 { | |
227 if (offset < src_section->PointerToRawData + src_section->SizeOfRawData) | |
228 break; | |
229 i++; | |
230 if (i == src_nt_header->FileHeader.NumberOfSections) | |
231 { | |
232 /* Handle offsets after the last section. */ | |
233 dst_section = IMAGE_FIRST_SECTION (dst_nt_header); | |
234 dst_section += dst_nt_header->FileHeader.NumberOfSections - 1; | |
235 while (dst_section->PointerToRawData == 0) | |
236 dst_section--; | |
237 while (src_section->PointerToRawData == 0) | |
238 src_section--; | |
239 return offset | |
240 + (dst_section->PointerToRawData + dst_section->SizeOfRawData) | |
241 - (src_section->PointerToRawData + src_section->SizeOfRawData); | |
242 } | |
243 src_section++; | |
244 dst_section++; | |
245 } | |
246 return offset + | |
247 (dst_section->PointerToRawData - src_section->PointerToRawData); | |
248 } | |
249 | |
250 #define OFFSET_TO_RVA(offset, section) \ | |
251 (section->VirtualAddress + ((DWORD)(offset) - section->PointerToRawData)) | |
252 | |
253 #define RVA_TO_OFFSET(rva, section) \ | |
254 (section->PointerToRawData + ((DWORD)(rva) - section->VirtualAddress)) | |
255 | |
256 #define RVA_TO_SECTION_OFFSET(rva, section) \ | |
257 ((DWORD)(rva) - section->VirtualAddress) | |
258 | |
259 /* Convert address in executing image to RVA. */ | |
260 #define PTR_TO_RVA(ptr) ((DWORD)(ptr) - (DWORD) GetModuleHandle (NULL)) | |
261 | |
262 #define PTR_TO_OFFSET(ptr, pfile_data) \ | |
31085
ab2cd9e121f1
(PTR_TO_OFFSET): Cast ptr to unsigned char*.
Andrew Innes <andrewi@gnu.org>
parents:
24236
diff
changeset
|
263 ((unsigned char *)(ptr) - (pfile_data)->file_base) |
24097 | 264 |
265 #define OFFSET_TO_PTR(offset, pfile_data) \ | |
266 ((pfile_data)->file_base + (DWORD)(offset)) | |
267 | |
268 #define ROUND_UP(p, align) (((DWORD)(p) + (align)-1) & ~((align)-1)) | |
269 #define ROUND_DOWN(p, align) ((DWORD)(p) & ~((align)-1)) | |
270 | |
271 | |
272 static void | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
273 copy_executable_and_add_section (file_data *p_infile, |
24097 | 274 file_data *p_outfile, |
275 char *new_section_name, | |
276 DWORD new_section_size) | |
277 { | |
278 unsigned char *dst; | |
279 PIMAGE_DOS_HEADER dos_header; | |
280 PIMAGE_NT_HEADERS nt_header; | |
281 PIMAGE_NT_HEADERS dst_nt_header; | |
282 PIMAGE_SECTION_HEADER section; | |
283 PIMAGE_SECTION_HEADER dst_section; | |
284 DWORD offset; | |
285 int i; | |
286 | |
287 #define COPY_CHUNK(message, src, size) \ | |
288 do { \ | |
289 unsigned char *s = (void *)(src); \ | |
290 unsigned long count = (size); \ | |
291 printf ("%s\n", (message)); \ | |
292 printf ("\t0x%08x Offset in input file.\n", s - p_infile->file_base); \ | |
293 printf ("\t0x%08x Offset in output file.\n", dst - p_outfile->file_base); \ | |
294 printf ("\t0x%08x Size in bytes.\n", count); \ | |
295 memcpy (dst, s, count); \ | |
296 dst += count; \ | |
297 } while (0) | |
298 | |
299 #define DST_TO_OFFSET() PTR_TO_OFFSET (dst, p_outfile) | |
24236
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
300 #define ROUND_UP_DST_AND_ZERO(align) \ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
301 do { \ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
302 unsigned char *newdst = p_outfile->file_base \ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
303 + ROUND_UP (DST_TO_OFFSET (), (align)); \ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
304 /* Zero the alignment slop; it may actually initialize real data. */ \ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
305 memset (dst, 0, newdst - dst); \ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
306 dst = newdst; \ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
307 } while (0) |
24097 | 308 |
309 /* Copy the source image sequentially, ie. section by section after | |
310 copying the headers and section table, to simplify the process of | |
311 adding an extra section table entry (which might force the raw | |
312 section data to be relocated). | |
313 | |
314 Note that dst is updated implicitly by each COPY_CHUNK. */ | |
315 | |
316 dos_header = (PIMAGE_DOS_HEADER) p_infile->file_base; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
317 nt_header = (PIMAGE_NT_HEADERS) (((unsigned long) dos_header) + |
24097 | 318 dos_header->e_lfanew); |
319 section = IMAGE_FIRST_SECTION (nt_header); | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
320 |
24097 | 321 dst = (unsigned char *) p_outfile->file_base; |
322 | |
323 COPY_CHUNK ("Copying DOS header...", dos_header, | |
324 (DWORD) nt_header - (DWORD) dos_header); | |
325 dst_nt_header = (PIMAGE_NT_HEADERS) dst; | |
326 COPY_CHUNK ("Copying NT header...", nt_header, | |
327 (DWORD) section - (DWORD) nt_header); | |
328 dst_section = (PIMAGE_SECTION_HEADER) dst; | |
329 COPY_CHUNK ("Copying section table...", section, | |
330 nt_header->FileHeader.NumberOfSections * sizeof (*section)); | |
331 | |
332 /* To improve the efficiency of demand loading, make the file | |
333 alignment match the section alignment (VC++ 6.0 does this by | |
334 default anyway). */ | |
335 dst_nt_header->OptionalHeader.FileAlignment = | |
336 dst_nt_header->OptionalHeader.SectionAlignment; | |
337 | |
338 /* Add an uninitialized data section at the end, of the specified name | |
339 and virtual size. */ | |
340 if (find_section (new_section_name, nt_header) == NULL) | |
341 /* Leave room for extra section table entry; filled in below. */ | |
342 dst += sizeof (*section); | |
343 else | |
344 new_section_name = NULL; | |
345 | |
24236
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
346 /* Align the first section's raw data area, and set the header size |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
347 field accordingly. */ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
348 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment); |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
349 dst_nt_header->OptionalHeader.SizeOfHeaders = DST_TO_OFFSET (); |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
350 |
24097 | 351 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++) |
352 { | |
353 char msg[100]; | |
354 sprintf (msg, "Copying raw data for %s...", section->Name); | |
355 | |
356 /* Update the file-relative offset for this section's raw data (if | |
357 it has any) in case things have been relocated; we will update | |
358 the other offsets below once we know where everything is. */ | |
359 if (dst_section->PointerToRawData) | |
360 dst_section->PointerToRawData = DST_TO_OFFSET (); | |
361 | |
362 /* Can always copy the original raw data. */ | |
363 COPY_CHUNK | |
364 (msg, OFFSET_TO_PTR (section->PointerToRawData, p_infile), | |
365 section->SizeOfRawData); | |
366 | |
367 /* Round up the raw data size to the new alignment. */ | |
368 dst_section->SizeOfRawData = | |
369 ROUND_UP (dst_section->SizeOfRawData, | |
370 dst_nt_header->OptionalHeader.FileAlignment); | |
371 | |
24236
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
372 /* Align the next section's raw data area. */ |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
373 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment); |
c83c9b5cc93f
ROUND_UP_DST_AND_ZERO): Renamed from ROUND_UP_DST. Zeroes the
Andrew Innes <andrewi@gnu.org>
parents:
24097
diff
changeset
|
374 |
24097 | 375 section++; |
376 dst_section++; | |
377 } | |
378 | |
379 /* Add the extra section entry (which adds no raw data). */ | |
380 if (new_section_name != NULL) | |
381 { | |
382 dst_nt_header->FileHeader.NumberOfSections++; | |
383 dst_nt_header->OptionalHeader.SizeOfImage += new_section_size; | |
384 strncpy (dst_section->Name, new_section_name, sizeof (dst_section->Name)); | |
385 dst_section->VirtualAddress = | |
386 section[-1].VirtualAddress | |
387 + ROUND_UP (section[-1].Misc.VirtualSize, | |
388 dst_nt_header->OptionalHeader.SectionAlignment); | |
389 dst_section->Misc.VirtualSize = new_section_size; | |
390 dst_section->PointerToRawData = 0; | |
391 dst_section->SizeOfRawData = 0; | |
392 dst_section->Characteristics = | |
393 IMAGE_SCN_CNT_UNINITIALIZED_DATA | |
394 | IMAGE_SCN_MEM_READ | |
395 | IMAGE_SCN_MEM_WRITE; | |
396 } | |
397 | |
398 /* Copy remainder of source image. */ | |
399 section--; | |
400 offset = ROUND_UP (section->PointerToRawData + section->SizeOfRawData, | |
401 nt_header->OptionalHeader.FileAlignment); | |
402 COPY_CHUNK | |
403 ("Copying remainder of executable...", | |
404 OFFSET_TO_PTR (offset, p_infile), | |
405 p_infile->size - offset); | |
406 | |
407 /* Final size for new image. */ | |
408 p_outfile->size = DST_TO_OFFSET (); | |
409 | |
410 /* Now patch up remaining file-relative offsets. */ | |
411 section = IMAGE_FIRST_SECTION (nt_header); | |
412 dst_section = IMAGE_FIRST_SECTION (dst_nt_header); | |
413 | |
414 #define ADJUST_OFFSET(var) \ | |
415 do { \ | |
416 if ((var) != 0) \ | |
417 (var) = relocate_offset ((var), nt_header, dst_nt_header); \ | |
418 } while (0) | |
419 | |
420 dst_nt_header->OptionalHeader.SizeOfInitializedData = 0; | |
421 dst_nt_header->OptionalHeader.SizeOfUninitializedData = 0; | |
422 for (i = 0; i < dst_nt_header->FileHeader.NumberOfSections; i++) | |
423 { | |
424 /* Recompute data sizes for completeness. */ | |
425 if (dst_section[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) | |
426 dst_nt_header->OptionalHeader.SizeOfInitializedData += | |
427 ROUND_UP (dst_section[i].Misc.VirtualSize, dst_nt_header->OptionalHeader.FileAlignment); | |
428 else if (dst_section[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) | |
429 dst_nt_header->OptionalHeader.SizeOfUninitializedData += | |
430 ROUND_UP (dst_section[i].Misc.VirtualSize, dst_nt_header->OptionalHeader.FileAlignment); | |
431 | |
432 ADJUST_OFFSET (dst_section[i].PointerToLinenumbers); | |
433 } | |
434 | |
435 ADJUST_OFFSET (dst_nt_header->FileHeader.PointerToSymbolTable); | |
436 | |
437 /* Update offsets in debug directory entries. */ | |
438 { | |
439 IMAGE_DATA_DIRECTORY debug_dir = | |
440 dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; | |
441 PIMAGE_DEBUG_DIRECTORY debug_entry; | |
442 | |
443 section = rva_to_section (debug_dir.VirtualAddress, dst_nt_header); | |
444 if (section) | |
445 { | |
446 debug_entry = (PIMAGE_DEBUG_DIRECTORY) | |
447 (RVA_TO_OFFSET (debug_dir.VirtualAddress, section) + p_outfile->file_base); | |
448 debug_dir.Size /= sizeof (IMAGE_DEBUG_DIRECTORY); | |
449 | |
450 for (i = 0; i < debug_dir.Size; i++, debug_entry++) | |
451 ADJUST_OFFSET (debug_entry->PointerToRawData); | |
452 } | |
453 } | |
454 } | |
455 | |
456 | |
457 int | |
458 main (int argc, char **argv) | |
459 { | |
460 file_data in_file, out_file; | |
461 char out_filename[MAX_PATH], in_filename[MAX_PATH]; | |
462 unsigned long size; | |
463 PIMAGE_DOS_HEADER dos_header; | |
464 PIMAGE_NT_HEADERS nt_header; | |
465 | |
466 #define OLD_NAME argv[1] | |
467 #define NEW_NAME argv[2] | |
468 #define SECTION_NAME argv[3] | |
469 #define SECTION_SIZE argv[4] | |
470 | |
471 strcpy (in_filename, OLD_NAME); | |
472 strcpy (out_filename, NEW_NAME); | |
473 | |
474 printf ("Dumping from %s\n", in_filename); | |
475 printf (" to %s\n", out_filename); | |
476 | |
477 /* Open the undumped executable file. */ | |
478 if (!open_input_file (&in_file, in_filename)) | |
479 { | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
480 printf ("Failed to open %s (%d)...bailing.\n", |
24097 | 481 in_filename, GetLastError ()); |
482 exit (1); | |
483 } | |
484 dos_header = (PIMAGE_DOS_HEADER) in_file.file_base; | |
485 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew); | |
486 /* Allow for expansion due to increasing file align to section align. | |
487 We can overestimate here, since close_file_data will update the | |
488 size exactly. */ | |
489 size = in_file.size | |
490 + nt_header->OptionalHeader.SectionAlignment | |
491 * nt_header->FileHeader.NumberOfSections; | |
492 if (!open_output_file (&out_file, out_filename, size)) | |
493 { | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
31347
diff
changeset
|
494 printf ("Failed to open %s (%d)...bailing.\n", |
24097 | 495 out_filename, GetLastError ()); |
496 exit (1); | |
497 } | |
498 | |
499 copy_executable_and_add_section (&in_file, &out_file, | |
500 SECTION_NAME, | |
501 atoi (SECTION_SIZE) * 1024 * 1024); | |
502 | |
503 /* Patch up header fields; profiler is picky about this. */ | |
504 { | |
505 HANDLE hImagehelp = LoadLibrary ("imagehlp.dll"); | |
506 DWORD headersum; | |
507 DWORD checksum; | |
508 | |
509 dos_header = (PIMAGE_DOS_HEADER) out_file.file_base; | |
510 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew); | |
511 | |
512 nt_header->OptionalHeader.CheckSum = 0; | |
513 // nt_header->FileHeader.TimeDateStamp = time (NULL); | |
514 // dos_header->e_cp = size / 512; | |
515 // nt_header->OptionalHeader.SizeOfImage = size; | |
516 | |
517 pfnCheckSumMappedFile = (void *) GetProcAddress (hImagehelp, "CheckSumMappedFile"); | |
518 if (pfnCheckSumMappedFile) | |
519 { | |
520 // nt_header->FileHeader.TimeDateStamp = time (NULL); | |
521 pfnCheckSumMappedFile (out_file.file_base, | |
522 out_file.size, | |
523 &headersum, | |
524 &checksum); | |
525 nt_header->OptionalHeader.CheckSum = checksum; | |
526 } | |
527 FreeLibrary (hImagehelp); | |
528 } | |
529 | |
530 close_file_data (&in_file); | |
531 close_file_data (&out_file); | |
532 | |
533 return 0; | |
534 } | |
535 | |
536 /* eof */ | |
52401 | 537 |
538 /* arch-tag: 17e2b0aa-8c17-4bd1-b24b-1cda689245fa | |
539 (do not change this comment) */ |