annotate nt/addsection.c @ 24206:d3649b38bb37

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