annotate nt/preprep.c @ 36150:46e59561af4c

Display Vars node renamed Display Custom. Include info there about customizing cursor appearance. Clean up aggressive scrolling. Clarify horizontal scrolling discussion. Fix index entries for line number mode.
author Richard M. Stallman <rms@gnu.org>
date Sat, 17 Feb 2001 16:45:37 +0000
parents cdc16c6e33be
children 23a1cea22d13
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
24363
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
1 /* Pro-process emacs.exe for profiling by MSVC.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
2 Copyright (C) 1999 Free Software Foundation, Inc.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
3
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
4 This file is part of GNU Emacs.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
5
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
6 GNU Emacs is free software; you can redistribute it and/or modify
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
8 the Free Software Foundation; either version 2, or (at your option)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
9 any later version.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
10
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
11 GNU Emacs is distributed in the hope that it will be useful,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
14 GNU General Public License for more details.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
15
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
17 along with GNU Emacs; see the file COPYING. If not, write to
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
19 Boston, MA 02111-1307, USA.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
20
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
21 Andrew Innes <andrewi@harlequin.co.uk> 16-Jan-1999
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
22 based on code from addsection.c
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
23 */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
24
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
25 #include <stdlib.h>
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
26 #include <stdio.h>
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
27 #include <fcntl.h>
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
28 #include <time.h>
31347
cdc16c6e33be (_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents: 31088
diff changeset
29 #ifdef __GNUC__
cdc16c6e33be (_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents: 31088
diff changeset
30 #define _ANONYMOUS_UNION
cdc16c6e33be (_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents: 31088
diff changeset
31 #define _ANONYMOUS_STRUCT
cdc16c6e33be (_ANONYMOUS_UNION) [__GNUC__]: New define.
Andrew Innes <andrewi@gnu.org>
parents: 31088
diff changeset
32 #endif
24363
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
33 #include <windows.h>
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
34
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
35 /* Include relevant definitions from IMAGEHLP.H, which can be found
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
36 in \\win32sdk\mstools\samples\image\include\imagehlp.h. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
37
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
38 PIMAGE_NT_HEADERS
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
39 (__stdcall * pfnCheckSumMappedFile) (LPVOID BaseAddress,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
40 DWORD FileLength,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
41 LPDWORD HeaderSum,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
42 LPDWORD CheckSum);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
43
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
44 #undef min
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
45 #undef max
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
46 #define min(x, y) (((x) < (y)) ? (x) : (y))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
47 #define max(x, y) (((x) > (y)) ? (x) : (y))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
48
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
49
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
50 /* File handling. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
51
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
52 typedef struct file_data {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
53 char *name;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
54 unsigned long size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
55 HANDLE file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
56 HANDLE file_mapping;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
57 unsigned char *file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
58 } file_data;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
59
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
60 int
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
61 open_input_file (file_data *p_file, char *filename)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
62 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
63 HANDLE file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
64 HANDLE file_mapping;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
65 void *file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
66 unsigned long size, upper_size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
67
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
68 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
69 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
70 if (file == INVALID_HANDLE_VALUE)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
71 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
72
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
73 size = GetFileSize (file, &upper_size);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
74 file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
75 0, size, NULL);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
76 if (!file_mapping)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
77 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
78
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
79 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
80 if (file_base == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
81 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
82
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
83 p_file->name = filename;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
84 p_file->size = size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
85 p_file->file = file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
86 p_file->file_mapping = file_mapping;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
87 p_file->file_base = file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
88
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
89 return TRUE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
90 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
91
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
92 int
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
93 open_output_file (file_data *p_file, char *filename, unsigned long size)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
94 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
95 HANDLE file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
96 HANDLE file_mapping;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
97 void *file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
98
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
99 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
100 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
101 if (file == INVALID_HANDLE_VALUE)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
102 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
103
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
104 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
105 0, size, NULL);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
106 if (!file_mapping)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
107 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
108
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
109 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
110 if (file_base == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
111 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
112
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
113 p_file->name = filename;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
114 p_file->size = size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
115 p_file->file = file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
116 p_file->file_mapping = file_mapping;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
117 p_file->file_base = file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
118
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
119 return TRUE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
120 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
121
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
122 int
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
123 open_inout_file (file_data *p_file, char *filename)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
124 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
125 HANDLE file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
126 HANDLE file_mapping;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
127 void *file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
128 unsigned long size, upper_size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
129
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
130 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
131 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
132 if (file == INVALID_HANDLE_VALUE)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
133 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
134
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
135 size = GetFileSize (file, &upper_size);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
136 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
137 0, size, NULL);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
138 if (!file_mapping)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
139 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
140
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
141 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
142 if (file_base == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
143 return FALSE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
144
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
145 p_file->name = filename;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
146 p_file->size = size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
147 p_file->file = file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
148 p_file->file_mapping = file_mapping;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
149 p_file->file_base = file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
150
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
151 return TRUE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
152 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
153
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
154 /* Close the system structures associated with the given file. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
155 void
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
156 close_file_data (file_data *p_file)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
157 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
158 UnmapViewOfFile (p_file->file_base);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
159 CloseHandle (p_file->file_mapping);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
160 /* For the case of output files, set final size. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
161 SetFilePointer (p_file->file, p_file->size, NULL, FILE_BEGIN);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
162 SetEndOfFile (p_file->file);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
163 CloseHandle (p_file->file);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
164 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
165
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
166
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
167 /* Routines to manipulate NT executable file sections. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
168
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
169 unsigned long
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
170 get_unrounded_section_size (PIMAGE_SECTION_HEADER p_section)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
171 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
172 /* The true section size, before rounding, for an initialized data or
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
173 code section. (Supposedly some linkers swap the meaning of these
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
174 two values.) */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
175 return min (p_section->SizeOfRawData,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
176 p_section->Misc.VirtualSize);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
177 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
178
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
179 /* Return pointer to section header for named section. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
180 IMAGE_SECTION_HEADER *
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
181 find_section (char * name, IMAGE_NT_HEADERS * nt_header)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
182 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
183 PIMAGE_SECTION_HEADER section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
184 int i;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
185
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
186 section = IMAGE_FIRST_SECTION (nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
187
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
188 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
189 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
190 if (strcmp (section->Name, name) == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
191 return section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
192 section++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
193 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
194 return NULL;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
195 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
196
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
197 /* Return pointer to section header for section containing the given
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
198 relative virtual address. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
199 IMAGE_SECTION_HEADER *
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
200 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
201 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
202 PIMAGE_SECTION_HEADER section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
203 int i;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
204
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
205 section = IMAGE_FIRST_SECTION (nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
206
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
207 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
208 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
209 /* Some linkers (eg. the NT SDK linker I believe) swapped the
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
210 meaning of these two values - or rather, they ignored
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
211 VirtualSize entirely and always set it to zero. This affects
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
212 some very old exes (eg. gzip dated Dec 1993). Since
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
213 w32_executable_type relies on this function to work reliably,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
214 we need to cope with this. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
215 DWORD real_size = max (section->SizeOfRawData,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
216 section->Misc.VirtualSize);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
217 if (rva >= section->VirtualAddress
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
218 && rva < section->VirtualAddress + real_size)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
219 return section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
220 section++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
221 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
222 return NULL;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
223 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
224
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
225 /* Return pointer to section header for section containing the given
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
226 offset in its raw data area. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
227 IMAGE_SECTION_HEADER *
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
228 offset_to_section (DWORD offset, IMAGE_NT_HEADERS * nt_header)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
229 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
230 PIMAGE_SECTION_HEADER section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
231 int i;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
232
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
233 section = IMAGE_FIRST_SECTION (nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
234
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
235 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
236 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
237 if (offset >= section->PointerToRawData
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
238 && offset < section->PointerToRawData + section->SizeOfRawData)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
239 return section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
240 section++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
241 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
242 return NULL;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
243 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
244
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
245 /* Return offset to an object in dst, given offset in src. We assume
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
246 there is at least one section in both src and dst images, and that
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
247 the some sections may have been added to dst (after sections in src). */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
248 static DWORD
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
249 relocate_offset (DWORD offset,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
250 IMAGE_NT_HEADERS * src_nt_header,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
251 IMAGE_NT_HEADERS * dst_nt_header)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
252 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
253 PIMAGE_SECTION_HEADER src_section = IMAGE_FIRST_SECTION (src_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
254 PIMAGE_SECTION_HEADER dst_section = IMAGE_FIRST_SECTION (dst_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
255 int i = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
256
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
257 while (offset >= src_section->PointerToRawData)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
258 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
259 if (offset < src_section->PointerToRawData + src_section->SizeOfRawData)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
260 break;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
261 i++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
262 if (i == src_nt_header->FileHeader.NumberOfSections)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
263 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
264 /* Handle offsets after the last section. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
265 dst_section = IMAGE_FIRST_SECTION (dst_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
266 dst_section += dst_nt_header->FileHeader.NumberOfSections - 1;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
267 while (dst_section->PointerToRawData == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
268 dst_section--;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
269 while (src_section->PointerToRawData == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
270 src_section--;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
271 return offset
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
272 + (dst_section->PointerToRawData + dst_section->SizeOfRawData)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
273 - (src_section->PointerToRawData + src_section->SizeOfRawData);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
274 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
275 src_section++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
276 dst_section++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
277 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
278 return offset +
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
279 (dst_section->PointerToRawData - src_section->PointerToRawData);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
280 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
281
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
282 #define OFFSET_TO_RVA(offset, section) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
283 (section->VirtualAddress + ((DWORD)(offset) - section->PointerToRawData))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
284
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
285 #define RVA_TO_OFFSET(rva, section) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
286 (section->PointerToRawData + ((DWORD)(rva) - section->VirtualAddress))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
287
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
288 #define RVA_TO_SECTION_OFFSET(rva, section) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
289 ((DWORD)(rva) - section->VirtualAddress)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
290
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
291 #define RVA_TO_PTR(var,section,filedata) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
292 ((void *)(RVA_TO_OFFSET(var,section) + (filedata)->file_base))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
293
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
294 /* Convert address in executing image to RVA. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
295 #define PTR_TO_RVA(ptr) ((DWORD)(ptr) - (DWORD) GetModuleHandle (NULL))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
296
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
297 #define PTR_TO_OFFSET(ptr, pfile_data) \
31088
24c78d0ab986 (PTR_TO_OFFSET): Cast ptr to unsigned char *.
Andrew Innes <andrewi@gnu.org>
parents: 24805
diff changeset
298 ((unsigned char *)(ptr) - (pfile_data)->file_base)
24363
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
299
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
300 #define OFFSET_TO_PTR(offset, pfile_data) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
301 ((pfile_data)->file_base + (DWORD)(offset))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
302
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
303 #define ROUND_UP(p, align) (((DWORD)(p) + (align)-1) & ~((align)-1))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
304 #define ROUND_DOWN(p, align) ((DWORD)(p) & ~((align)-1))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
305
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
306
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
307 /* The MSVC prep program generates a ._xe file from .exe, where relevant
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
308 function calls etc have been patched to go through thunks (generated
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
309 by prep) that record timing/call information. Because the thunks
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
310 need to make references to functions imported from profile.dll, the
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
311 import table must be expanded; the end result is that all the
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
312 sections following .rdata are relocated to higher RVAs (add a final
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
313 code section is added holding all the thunks). The .reloc section is
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
314 also expanded, so that the thunks themselves are relocatable.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
315
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
316 It is this relocation which kills emacs._xe, because the dumped heap
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
317 pointers aren't relocated, because there is no relocation data for
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
318 either the relevant global/static variables or the heap section
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
319 itself, both of which contain pointers into the heap. [Note that
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
320 static variables which aren't initialized during linking may become
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
321 initialized with heap pointers, or even pointers to other static
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
322 variables, because of dumping.]
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
323
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
324 We could potentially generate the relocation data ourselves by making
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
325 two versions of temacs, one with an extra dummmy section before
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
326 EMHEAP to offset it, and then compare the dumped executables from
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
327 both. That is a lot of work though, and it doesn't solve the problem
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
328 of dumped pointers to static variables, which also can be relocated.
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
329
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
330 A better solution is to pre-process emacs.exe so that the .rdata and
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
331 .reloc sections are moved to the end of the section table, and thus
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
332 prep won't relocate anything else. (Of course, we leave "dead"
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
333 copies of these two sections in place, so that the virtual address of
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
334 everything else is unaffected.) Relocating the .reloc data is
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
335 trivial - we just update the IMAGE_BASE_RELOCATION address in the
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
336 header (the data itself doesn't change). Relocating the import table
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
337 is more complicated though, because the calls to imported functions
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
338 must be patched up. That requires us to selectively apply the base
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
339 relocations when we encounter references to imported functions (or
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
340 variables) in other sections, but at least the base relocations are
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
341 easy to parse. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
342
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
343 static void
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
344 copy_executable_and_move_sections (file_data *p_infile,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
345 file_data *p_outfile)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
346 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
347 unsigned char *dst;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
348 PIMAGE_DOS_HEADER dos_header;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
349 PIMAGE_NT_HEADERS nt_header;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
350 PIMAGE_NT_HEADERS dst_nt_header;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
351 PIMAGE_SECTION_HEADER section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
352 PIMAGE_SECTION_HEADER dst_section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
353 PIMAGE_SECTION_HEADER import_section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
354 PIMAGE_SECTION_HEADER reloc_section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
355 PIMAGE_DATA_DIRECTORY import_dir;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
356 PIMAGE_DATA_DIRECTORY reloc_dir;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
357 DWORD import_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
358 DWORD reloc_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
359 DWORD offset;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
360 int i;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
361
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
362 #define COPY_CHUNK(message, src, size) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
363 do { \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
364 unsigned char *s = (void *)(src); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
365 unsigned long count = (size); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
366 printf ("%s\n", (message)); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
367 printf ("\t0x%08x Offset in input file.\n", s - p_infile->file_base); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
368 printf ("\t0x%08x Offset in output file.\n", dst - p_outfile->file_base); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
369 printf ("\t0x%08x Size in bytes.\n", count); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
370 memcpy (dst, s, count); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
371 dst += count; \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
372 } while (0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
373
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
374 #define DST_TO_OFFSET() PTR_TO_OFFSET (dst, p_outfile)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
375 #define ROUND_UP_DST_AND_ZERO(align) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
376 do { \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
377 unsigned char *newdst = p_outfile->file_base \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
378 + ROUND_UP (DST_TO_OFFSET (), (align)); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
379 /* Zero the alignment slop; it may actually initialize real data. */ \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
380 memset (dst, 0, newdst - dst); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
381 dst = newdst; \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
382 } while (0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
383
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
384 /* Copy the source image sequentially, ie. section by section after
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
385 copying the headers and section table, to simplify the process of
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
386 relocating the .rdata and .reloc section table entries (which might
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
387 force the raw section data to be relocated).
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
388
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
389 Note that dst is updated implicitly by each COPY_CHUNK. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
390
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
391 dos_header = (PIMAGE_DOS_HEADER) p_infile->file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
392 nt_header = (PIMAGE_NT_HEADERS) (((unsigned long) dos_header) +
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
393 dos_header->e_lfanew);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
394 section = IMAGE_FIRST_SECTION (nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
395
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
396 import_dir = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
397 import_section = rva_to_section (import_dir->VirtualAddress, nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
398
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
399 reloc_dir = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
400 reloc_section = rva_to_section (reloc_dir->VirtualAddress, nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
401 if (!reloc_section)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
402 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
403 printf ("No relocation data, cannot prepare for profile prepping.\n");
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
404 exit (1);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
405 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
406
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
407 dst = (unsigned char *) p_outfile->file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
408
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
409 COPY_CHUNK ("Copying DOS header...", dos_header,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
410 (DWORD) nt_header - (DWORD) dos_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
411 dst_nt_header = (PIMAGE_NT_HEADERS) dst;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
412 COPY_CHUNK ("Copying NT header...", nt_header,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
413 (DWORD) section - (DWORD) nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
414 dst_section = (PIMAGE_SECTION_HEADER) dst;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
415 COPY_CHUNK ("Copying section table...", section,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
416 nt_header->FileHeader.NumberOfSections * sizeof (*section));
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
417
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
418 /* Leave room for extra section table entries; filled in below. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
419 dst += 2 * sizeof (*section);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
420
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
421 /* Align the first section's raw data area, and set the header size
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
422 field accordingly. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
423 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
424 dst_nt_header->OptionalHeader.SizeOfHeaders = DST_TO_OFFSET ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
425
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
426 for (i = 0; i < nt_header->FileHeader.NumberOfSections;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
427 i++, section++, dst_section++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
428 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
429 char msg[100];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
430 sprintf (msg, "Copying raw data for %s...", section->Name);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
431
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
432 /* "Blank out" the two sections being relocated. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
433 if (section == import_section || section == reloc_section)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
434 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
435 dst_section->Name[0] = 'X';
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
436 dst_section->Misc.VirtualSize =
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
437 ROUND_UP (dst_section->Misc.VirtualSize,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
438 dst_nt_header->OptionalHeader.SectionAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
439 dst_section->PointerToRawData = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
440 dst_section->SizeOfRawData = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
441 dst_section->Characteristics &= ~IMAGE_SCN_CNT_INITIALIZED_DATA;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
442 dst_section->Characteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
443 dst_section->Characteristics &= ~IMAGE_SCN_MEM_WRITE;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
444 continue;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
445 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
446
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
447 /* Update the file-relative offset for this section's raw data (if
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
448 it has any) in case things have been relocated; we will update
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
449 the other offsets below once we know where everything is. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
450 if (dst_section->PointerToRawData)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
451 dst_section->PointerToRawData = DST_TO_OFFSET ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
452
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
453 /* Copy the original raw data. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
454 COPY_CHUNK
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
455 (msg, OFFSET_TO_PTR (section->PointerToRawData, p_infile),
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
456 section->SizeOfRawData);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
457
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
458 /* Round up the raw data size to the new alignment. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
459 dst_section->SizeOfRawData =
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
460 ROUND_UP (dst_section->SizeOfRawData,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
461 dst_nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
462
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
463 /* Align the next section's raw data area. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
464 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
465 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
466
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
467 /* Add the extra section entries, copying the raw data we skipped
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
468 earlier. We'll patch up the data itself below. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
469 if (import_section != NULL)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
470 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
471 dst_nt_header->FileHeader.NumberOfSections++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
472 dst_nt_header->OptionalHeader.SizeOfImage +=
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
473 ROUND_UP (import_section->Misc.VirtualSize,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
474 dst_nt_header->OptionalHeader.SectionAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
475 *dst_section = *import_section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
476 dst_section->VirtualAddress =
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
477 dst_section[-1].VirtualAddress
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
478 + ROUND_UP (dst_section[-1].Misc.VirtualSize,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
479 dst_nt_header->OptionalHeader.SectionAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
480 dst_section->PointerToRawData = DST_TO_OFFSET ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
481 /* Remember delta applied to import section. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
482 import_delta_rva = dst_section->VirtualAddress - import_section->VirtualAddress;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
483 COPY_CHUNK
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
484 ("Relocating import directory",
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
485 OFFSET_TO_PTR (import_section->PointerToRawData, p_infile),
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
486 import_section->SizeOfRawData);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
487 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
488 dst_section++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
489 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
490 if (reloc_section != NULL)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
491 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
492 dst_nt_header->FileHeader.NumberOfSections++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
493 dst_nt_header->OptionalHeader.SizeOfImage +=
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
494 ROUND_UP (reloc_section->Misc.VirtualSize,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
495 dst_nt_header->OptionalHeader.SectionAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
496 *dst_section = *reloc_section;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
497 dst_section->VirtualAddress =
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
498 dst_section[-1].VirtualAddress
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
499 + ROUND_UP (dst_section[-1].Misc.VirtualSize,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
500 dst_nt_header->OptionalHeader.SectionAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
501 dst_section->PointerToRawData = DST_TO_OFFSET ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
502 /* Remember delta applied to reloc section. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
503 reloc_delta_rva = dst_section->VirtualAddress - reloc_section->VirtualAddress;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
504 COPY_CHUNK
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
505 ("Relocating base relocations directory",
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
506 OFFSET_TO_PTR (reloc_section->PointerToRawData, p_infile),
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
507 reloc_section->SizeOfRawData);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
508 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
509 reloc_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
510 reloc_dir->VirtualAddress += reloc_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
511 dst_section++;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
512 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
513
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
514 /* Copy remainder of source image. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
515 section--;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
516 offset = ROUND_UP (section->PointerToRawData + section->SizeOfRawData,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
517 nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
518 COPY_CHUNK
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
519 ("Copying remainder of executable...",
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
520 OFFSET_TO_PTR (offset, p_infile),
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
521 p_infile->size - offset);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
522
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
523 /* Final size for new image. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
524 p_outfile->size = DST_TO_OFFSET ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
525
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
526 /* Now patch up remaining file-relative offsets. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
527 printf ("Patching up raw data offsets...\n");
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
528
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
529 section = IMAGE_FIRST_SECTION (nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
530 dst_section = IMAGE_FIRST_SECTION (dst_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
531
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
532 #define ADJUST_OFFSET(var) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
533 do { \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
534 if ((var) != 0) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
535 (var) = relocate_offset ((var), nt_header, dst_nt_header); \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
536 } while (0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
537
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
538 #define ADJUST_IMPORT_RVA(var) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
539 do { \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
540 if ((var) != 0) \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
541 *((DWORD *)&(var)) += import_delta_rva; \
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
542 } while (0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
543
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
544 dst_nt_header->OptionalHeader.SizeOfInitializedData = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
545 dst_nt_header->OptionalHeader.SizeOfUninitializedData = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
546 for (i = 0; i < dst_nt_header->FileHeader.NumberOfSections; i++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
547 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
548 /* Recompute data sizes for completeness. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
549 if (dst_section[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
550 dst_nt_header->OptionalHeader.SizeOfInitializedData +=
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
551 ROUND_UP (dst_section[i].Misc.VirtualSize, dst_nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
552 else if (dst_section[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
553 dst_nt_header->OptionalHeader.SizeOfUninitializedData +=
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
554 ROUND_UP (dst_section[i].Misc.VirtualSize, dst_nt_header->OptionalHeader.FileAlignment);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
555
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
556 ADJUST_OFFSET (dst_section[i].PointerToLinenumbers);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
557 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
558
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
559 ADJUST_OFFSET (dst_nt_header->FileHeader.PointerToSymbolTable);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
560
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
561 /* Update offsets in debug directory entries. Note that the debug
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
562 directory may be in the same section as the import table, so its
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
563 RVA may need to be adjusted too. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
564 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
565 PIMAGE_DATA_DIRECTORY debug_dir =
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
566 &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
567 PIMAGE_DEBUG_DIRECTORY debug_entry;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
568
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
569 /* Update debug_dir if part of import_section. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
570 if (rva_to_section (debug_dir->VirtualAddress, nt_header) == import_section)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
571 debug_dir->VirtualAddress += import_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
572
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
573 section = rva_to_section (debug_dir->VirtualAddress, dst_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
574 if (section)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
575 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
576 int size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
577
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
578 debug_entry = RVA_TO_PTR (debug_dir->VirtualAddress, section, p_outfile);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
579 size = debug_dir->Size / sizeof (IMAGE_DEBUG_DIRECTORY);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
580
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
581 for (i = 0; i < size; i++, debug_entry++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
582 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
583 /* The debug data itself is normally not part of any
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
584 section, but stored after all the raw section data. So
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
585 let relocate_offset do the work. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
586 ADJUST_OFFSET (debug_entry->PointerToRawData);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
587 ADJUST_IMPORT_RVA (debug_entry->AddressOfRawData);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
588 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
589 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
590 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
591
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
592 /* Update RVAs in import directory entries. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
593 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
594 PIMAGE_IMPORT_DESCRIPTOR imports;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
595 PIMAGE_THUNK_DATA import_thunks;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
596
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
597 import_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
598 import_dir->VirtualAddress += import_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
599
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
600 section = rva_to_section (import_dir->VirtualAddress, dst_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
601 imports = RVA_TO_PTR (import_dir->VirtualAddress, section, p_outfile);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
602
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
603 for ( ; imports->Name != 0; imports++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
604 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
605 ADJUST_IMPORT_RVA (imports->OriginalFirstThunk);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
606 ADJUST_IMPORT_RVA (imports->FirstThunk);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
607 ADJUST_IMPORT_RVA (imports->Name);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
608
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
609 for (import_thunks = RVA_TO_PTR (imports->OriginalFirstThunk, section, p_outfile);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
610 import_thunks->u1.Function != 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
611 import_thunks++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
612 if ((import_thunks->u1.Ordinal >> 31) == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
613 ADJUST_IMPORT_RVA (import_thunks->u1.Ordinal);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
614
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
615 for (import_thunks = RVA_TO_PTR (imports->FirstThunk, section, p_outfile);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
616 import_thunks->u1.Function != 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
617 import_thunks++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
618 if ((import_thunks->u1.Ordinal >> 31) == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
619 ADJUST_IMPORT_RVA (import_thunks->u1.Ordinal);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
620 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
621
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
622 import_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
623 import_dir->VirtualAddress += import_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
624 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
625
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
626 /* Fix up references to the import section. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
627 printf ("Applying fixups to import references...\n");
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
628
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
629 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
630 IMAGE_BASE_RELOCATION *relocs, *block, *start_block, *end_block;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
631 DWORD import_start = import_section->VirtualAddress + dst_nt_header->OptionalHeader.ImageBase;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
632 DWORD import_end = import_start + import_section->Misc.VirtualSize;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
633 DWORD len_import_relocs;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
634 DWORD len_remaining_relocs;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
635 int seen_high = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
636 WORD * high_word;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
637 void * holder;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
638
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
639 reloc_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
640 reloc_section = rva_to_section (reloc_dir->VirtualAddress, dst_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
641 relocs = RVA_TO_PTR (reloc_dir->VirtualAddress, reloc_section, p_outfile);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
642
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
643 /* Move the base relocations for the import section, if there are
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
644 any; the profiler needs to be able to patch RVAs in the import
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
645 section itself. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
646 for (block = relocs, start_block = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
647 (DWORD) block - (DWORD) relocs < reloc_dir->Size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
648 block = (void *)((DWORD) block + block->SizeOfBlock))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
649 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
650 if (block->VirtualAddress >= import_section->VirtualAddress + import_section->Misc.VirtualSize)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
651 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
652 end_block = block;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
653 break;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
654 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
655 if (block->VirtualAddress >= import_section->VirtualAddress)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
656 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
657 if (start_block == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
658 start_block = block;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
659 block->VirtualAddress += import_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
660 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
661 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
662 if (start_block)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
663 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
664 len_import_relocs = (DWORD) end_block - (DWORD) start_block;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
665 len_remaining_relocs = (DWORD) relocs + reloc_dir->Size - (DWORD) end_block;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
666 holder = malloc (len_import_relocs);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
667 if (holder == 0)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
668 abort ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
669 memcpy (holder, start_block, len_import_relocs);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
670 memcpy (start_block, end_block, len_remaining_relocs);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
671 memcpy ((char *) start_block + len_remaining_relocs, holder, len_import_relocs);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
672 free (holder);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
673 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
674
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
675 /* Walk up the list of base relocations, checking for references
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
676 to the old import section location, and patching them to
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
677 reference the new location. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
678 for (block = relocs;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
679 (DWORD) block - (DWORD) relocs < reloc_dir->Size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
680 block = (void *)((DWORD) block + block->SizeOfBlock))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
681 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
682 DWORD page_rva = block->VirtualAddress;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
683 DWORD page_offset;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
684 union {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
685 WORD word;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
686 DWORD dword;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
687 } * ploc;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
688 WORD *fixup;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
689
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
690 section = rva_to_section (page_rva, dst_nt_header);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
691 /* Don't apply fixups to the blanked sections. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
692 if (section->Name[0] == 'X')
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
693 continue;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
694
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
695 for (fixup = (WORD *) &block[1];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
696 (DWORD) fixup - (DWORD) block < block->SizeOfBlock;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
697 fixup++)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
698 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
699 page_offset = (*fixup) & 0xfff;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
700 ploc = RVA_TO_PTR (page_rva + page_offset, section, p_outfile);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
701
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
702 /* Unless our assumption is wrong, all low word fixups
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
703 should immediately follow a high fixup. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
704 if (seen_high && ((*fixup) >> 12) != IMAGE_REL_BASED_LOW)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
705 abort ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
706
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
707 switch ((*fixup) >> 12)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
708 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
709 case IMAGE_REL_BASED_ABSOLUTE:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
710 break;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
711 case IMAGE_REL_BASED_HIGH:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
712 /* We must assume that high and low fixups occur in
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
713 pairs, specifically a low fixup immediately follows a
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
714 high fixup (normally separated by two bytes). We
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
715 have to process the two fixups together, to find out
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
716 the full pointer value and decide whether to apply
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
717 the fixup. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
718 seen_high = 1;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
719 high_word = &ploc->word;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
720 break;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
721 case IMAGE_REL_BASED_LOW:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
722 offset = (*high_word << 16) + ploc->word;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
723 if (offset >= import_start && offset < import_end)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
724 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
725 (*high_word) += import_delta_rva >> 16;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
726 ploc->dword += import_delta_rva & 0xffff;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
727 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
728 seen_high = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
729 break;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
730 case IMAGE_REL_BASED_HIGHLOW:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
731 /* Docs imply two words in big-endian order, so perhaps
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
732 this is only used on big-endian platforms, in which
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
733 case the obvious code will work. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
734 if (ploc->dword >= import_start && ploc->dword < import_end)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
735 ploc->dword += import_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
736 break;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
737 case IMAGE_REL_BASED_HIGHADJ:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
738 /* Docs don't say, but I guess this is the equivalent
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
739 for little-endian platforms. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
740 if (ploc->dword >= import_start && ploc->dword < import_end)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
741 ploc->dword += import_delta_rva;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
742 break;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
743 case IMAGE_REL_BASED_MIPS_JMPADDR:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
744 /* Don't know how to handle this; MIPS support has been
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
745 dropped from NT4 anyway. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
746 abort ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
747 break;
24805
eb5e287ff675 Fix typo.
Andrew Innes <andrewi@gnu.org>
parents: 24666
diff changeset
748 #ifdef IMAGE_REL_BASED_SECTION
24363
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
749 case IMAGE_REL_BASED_SECTION:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
750 case IMAGE_REL_BASED_REL32:
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
751 /* Docs don't say what these values mean. */
24666
239ee0e7b828 (copy_executable_and_move_sections): Ifdef out a
Andrew Innes <andrewi@gnu.org>
parents: 24363
diff changeset
752 #endif
239ee0e7b828 (copy_executable_and_move_sections): Ifdef out a
Andrew Innes <andrewi@gnu.org>
parents: 24363
diff changeset
753 default:
24363
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
754 abort ();
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
755 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
756 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
757 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
758 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
759 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
760
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
761
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
762 int
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
763 main (int argc, char **argv)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
764 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
765 PIMAGE_DOS_HEADER dos_header;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
766 PIMAGE_NT_HEADERS nt_header;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
767 file_data in_file, out_file;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
768 char out_filename[MAX_PATH], in_filename[MAX_PATH];
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
769 char *ptr;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
770
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
771 strcpy (in_filename, argv[1]);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
772 strcpy (out_filename, argv[2]);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
773
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
774 printf ("Preparing %s for profile prepping\n", out_filename);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
775
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
776 /* Open the original (dumped) executable file for reference. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
777 if (!open_input_file (&in_file, in_filename))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
778 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
779 printf ("Failed to open %s (%d)...bailing.\n",
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
780 in_filename, GetLastError ());
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
781 exit (1);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
782 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
783
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
784 /* Create a new image that can be prepped; we don't expect the size to
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
785 change because we are only adding two new section table entries,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
786 which should fit in the alignment slop. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
787 if (!open_output_file (&out_file, out_filename, in_file.size))
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
788 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
789 printf ("Failed to open %s (%d)...bailing.\n",
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
790 out_filename, GetLastError ());
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
791 exit (1);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
792 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
793
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
794 copy_executable_and_move_sections (&in_file, &out_file);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
795
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
796 /* Patch up header fields; profiler is picky about this. */
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
797 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
798 HANDLE hImagehelp = LoadLibrary ("imagehlp.dll");
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
799 DWORD headersum;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
800 DWORD checksum;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
801
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
802 dos_header = (PIMAGE_DOS_HEADER) out_file.file_base;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
803 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
804
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
805 nt_header->OptionalHeader.CheckSum = 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
806 // nt_header->FileHeader.TimeDateStamp = time (NULL);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
807 // dos_header->e_cp = size / 512;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
808 // nt_header->OptionalHeader.SizeOfImage = size;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
809
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
810 pfnCheckSumMappedFile = (void *) GetProcAddress (hImagehelp, "CheckSumMappedFile");
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
811 if (pfnCheckSumMappedFile)
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
812 {
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
813 // nt_header->FileHeader.TimeDateStamp = time (NULL);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
814 pfnCheckSumMappedFile (out_file.file_base,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
815 out_file.size,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
816 &headersum,
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
817 &checksum);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
818 nt_header->OptionalHeader.CheckSum = checksum;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
819 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
820 FreeLibrary (hImagehelp);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
821 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
822
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
823 close_file_data (&out_file);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
824 close_file_data (&in_file);
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
825
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
826 return 0;
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
827 }
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
828
b7ccfe3bfb94 Initial revision
Andrew Innes <andrewi@gnu.org>
parents:
diff changeset
829 /* eof */