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