Mercurial > emacs
annotate src/unexnext.c @ 24206:d3649b38bb37
(w32_wnd_proc): Fix bug introduced by previous change;
the lwindow, rwindow and apps keys could not be used as function
keys, because they were being passed to TranslateMessage which
ignores them. Also, key was being changed to SPC.
author | Andrew Innes <andrewi@gnu.org> |
---|---|
date | Wed, 27 Jan 1999 21:53:27 +0000 |
parents | 4383d4a532de |
children | 23a1cea22d13 |
rev | line source |
---|---|
1349 | 1 /* Dump Emacs in macho format. |
2660
b70f4760d769
Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents:
1349
diff
changeset
|
2 Copyright (C) 1990, 1993 Free Software Foundation, Inc. |
1349 | 3 Written by Bradley Taylor (btaylor@next.com). |
4 | |
5 This file is part of GNU Emacs. | |
6 | |
7 GNU Emacs is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
2660
b70f4760d769
Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents:
1349
diff
changeset
|
9 the Free Software Foundation; either version 2, or (at your option) |
1349 | 10 any later version. |
11 | |
12 GNU Emacs is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GNU Emacs; see the file COPYING. If not, write to | |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
4598
diff
changeset
|
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
4598
diff
changeset
|
20 Boston, MA 02111-1307, USA. */ |
1349 | 21 |
22 | |
23 #undef __STRICT_BSD__ | |
24 | |
25 #include <stdio.h> | |
26 #include <stdlib.h> | |
27 #include <stdarg.h> | |
2660
b70f4760d769
Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents:
1349
diff
changeset
|
28 #include <mach/mach.h> |
b70f4760d769
Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents:
1349
diff
changeset
|
29 #include <mach-o/loader.h> |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
30 #include <mach-o/reloc.h> |
1349 | 31 #include <sys/file.h> |
32 #include <sys/stat.h> | |
19669
e8e724dad99a
Include unistd.h instead of libc.h.
Richard M. Stallman <rms@gnu.org>
parents:
16853
diff
changeset
|
33 #include <unistd.h> |
19670 | 34 /* Instead of unistd.h, this used to include libc.h. |
35 "Nelson H. F. Beebe" <beebe@math.utah.edu> says that doesn't work | |
36 in system version 3.3. */ | |
1349 | 37 |
38 | |
2660
b70f4760d769
Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents:
1349
diff
changeset
|
39 int malloc_cookie; |
1349 | 40 |
41 /* | |
42 * Kludge: we don't expect any program data beyond VM_HIGHDATA | |
43 * What is really needed is a way to find out from malloc() which | |
44 * pages it vm_allocated and write only those out into the data segment. | |
45 * | |
46 * This kludge may break when we stop using fixed virtual address | |
47 * shared libraries. Actually, emacs will probably continue working, but be | |
48 * much larger on disk than it needs to be (because non-malloced data will | |
49 * be in the file). | |
50 */ | |
51 static const unsigned VM_HIGHDATA = 0x2000000; | |
52 | |
53 typedef struct region_t { | |
54 vm_address_t address; | |
55 vm_size_t size; | |
56 vm_prot_t protection; | |
57 vm_prot_t max_protection; | |
58 vm_inherit_t inheritance; | |
59 boolean_t shared; | |
60 port_t object_name; | |
61 vm_offset_t offset; | |
62 } region_t; | |
63 | |
64 | |
65 static void | |
66 grow( | |
67 struct load_command ***the_commands, | |
68 unsigned *the_commands_len | |
69 ) | |
70 { | |
71 if (*the_commands == NULL) { | |
72 *the_commands_len = 1; | |
73 *the_commands = malloc(sizeof(*the_commands)); | |
74 } else { | |
75 (*the_commands_len)++; | |
76 *the_commands = realloc(*the_commands, | |
77 (*the_commands_len * | |
78 sizeof(**the_commands))); | |
79 } | |
80 } | |
81 | |
82 | |
83 static void | |
84 save_command( | |
85 struct load_command *command, | |
86 struct load_command ***the_commands, | |
87 unsigned *the_commands_len | |
88 ) | |
89 { | |
90 struct load_command **tmp; | |
91 | |
92 grow(the_commands, the_commands_len); | |
93 tmp = &(*the_commands)[*the_commands_len - 1]; | |
94 *tmp = malloc(command->cmdsize); | |
95 bcopy(command, *tmp, command->cmdsize); | |
96 } | |
97 | |
98 static void | |
99 fatal_unexec(char *format, ...) | |
100 { | |
101 va_list ap; | |
102 | |
103 va_start(ap, format); | |
104 fprintf(stderr, "unexec: "); | |
105 vfprintf(stderr, format, ap); | |
106 fprintf(stderr, "\n"); | |
107 va_end(ap); | |
108 } | |
109 | |
110 static int | |
111 read_macho( | |
112 int fd, | |
113 struct mach_header *the_header, | |
114 struct load_command ***the_commands, | |
115 unsigned *the_commands_len | |
116 ) | |
117 { | |
118 struct load_command command; | |
119 struct load_command *buf; | |
120 int i; | |
121 int size; | |
122 | |
123 if (read(fd, the_header, sizeof(*the_header)) != sizeof(*the_header)) { | |
124 fatal_unexec("cannot read macho header"); | |
125 return (0); | |
126 } | |
127 for (i = 0; i < the_header->ncmds; i++) { | |
128 if (read(fd, &command, sizeof(struct load_command)) != | |
129 sizeof(struct load_command)) { | |
130 fatal_unexec("cannot read macho load command header"); | |
131 return (0); | |
132 } | |
133 size = command.cmdsize - sizeof(struct load_command); | |
134 if (size < 0) { | |
135 fatal_unexec("bogus load command size"); | |
136 return (0); | |
137 } | |
138 buf = malloc(command.cmdsize); | |
139 buf->cmd = command.cmd; | |
140 buf->cmdsize = command.cmdsize; | |
141 if (read(fd, ((char *)buf + | |
142 sizeof(struct load_command)), | |
143 size) != size) { | |
144 fatal_unexec("cannot read load command data"); | |
145 return (0); | |
146 } | |
147 save_command(buf, the_commands, the_commands_len); | |
148 } | |
149 return (1); | |
150 } | |
151 | |
152 static int | |
153 filldatagap( | |
154 vm_address_t start_address, | |
155 vm_size_t *size, | |
156 vm_address_t end_address | |
157 ) | |
158 { | |
159 vm_address_t address; | |
160 vm_size_t gapsize; | |
161 | |
162 address = (start_address + *size); | |
163 gapsize = end_address - address; | |
164 *size += gapsize; | |
165 if (vm_allocate(task_self(), &address, gapsize, | |
166 FALSE) != KERN_SUCCESS) { | |
167 fatal_unexec("cannot vm_allocate"); | |
168 return (0); | |
169 } | |
170 return (1); | |
171 } | |
172 | |
173 static int | |
174 get_data_region( | |
175 vm_address_t *address, | |
176 vm_size_t *size | |
177 ) | |
178 { | |
179 region_t region; | |
180 kern_return_t ret; | |
181 struct section *sect; | |
182 | |
4598
cec168152d88
(get_data_region): Add cast to avoid warning.
Richard M. Stallman <rms@gnu.org>
parents:
2660
diff
changeset
|
183 sect = (struct section *) getsectbyname(SEG_DATA, SECT_DATA); |
1349 | 184 region.address = 0; |
185 *address = 0; | |
186 for (;;) { | |
187 ret = vm_region(task_self(), | |
188 ®ion.address, | |
189 ®ion.size, | |
190 ®ion.protection, | |
191 ®ion.max_protection, | |
192 ®ion.inheritance, | |
193 ®ion.shared, | |
194 ®ion.object_name, | |
195 ®ion.offset); | |
196 if (ret != KERN_SUCCESS || region.address >= VM_HIGHDATA) { | |
197 break; | |
198 } | |
199 if (*address != 0) { | |
200 if (region.address > *address + *size) { | |
201 if (!filldatagap(*address, size, | |
202 region.address)) { | |
203 return (0); | |
204 } | |
205 } | |
206 *size += region.size; | |
207 } else { | |
208 if (region.address == sect->addr) { | |
209 *address = region.address; | |
210 *size = region.size; | |
211 } | |
212 } | |
213 region.address += region.size; | |
214 } | |
215 return (1); | |
216 } | |
217 | |
218 static char * | |
219 my_malloc( | |
220 vm_size_t size | |
221 ) | |
222 { | |
223 vm_address_t address; | |
224 | |
225 if (vm_allocate(task_self(), &address, size, TRUE) != KERN_SUCCESS) { | |
226 return (NULL); | |
227 } | |
228 return ((char *)address); | |
229 } | |
230 | |
231 static void | |
232 my_free( | |
233 char *buf, | |
234 vm_size_t size | |
235 ) | |
236 { | |
237 vm_deallocate(task_self(), (vm_address_t)buf, size); | |
238 } | |
239 | |
240 static int | |
241 unexec_doit( | |
242 int infd, | |
243 int outfd | |
244 ) | |
245 { | |
246 int i; | |
247 struct load_command **the_commands = NULL; | |
248 unsigned the_commands_len; | |
249 struct mach_header the_header; | |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
250 int fgrowth = 0; |
1349 | 251 int fdatastart; |
252 int fdatasize; | |
253 int size; | |
254 struct stat st; | |
255 char *buf; | |
256 vm_address_t data_address; | |
257 vm_size_t data_size; | |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
258 vm_size_t vmaddr_growth = 0; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
259 vm_size_t dataseg_vmaddr, dataseg_vmend; |
1349 | 260 |
261 struct segment_command *segment; | |
262 | |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
263 #ifdef NS_TARGET |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
264 unsigned long extreloff = 0; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
265 unsigned long nextrel = 0; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
266 struct dysymtab_command *dysymtab; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
267 struct relocation_info reloc_info; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
268 #endif |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
269 |
1349 | 270 if (!read_macho(infd, &the_header, &the_commands, &the_commands_len)) { |
271 return (0); | |
272 } | |
273 | |
274 | |
2660
b70f4760d769
Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents:
1349
diff
changeset
|
275 malloc_cookie = malloc_freezedry (); |
1349 | 276 if (!get_data_region(&data_address, &data_size)) { |
277 return (0); | |
278 } | |
279 | |
280 | |
281 /* | |
282 * DO NOT USE MALLOC IN THIS SECTION | |
283 */ | |
284 { | |
285 /* | |
286 * Fix offsets | |
287 */ | |
288 for (i = 0; i < the_commands_len; i++) { | |
289 switch (the_commands[i]->cmd) { | |
290 case LC_SEGMENT: | |
291 segment = ((struct segment_command *) | |
292 the_commands[i]); | |
293 if (strcmp(segment->segname, SEG_DATA) == 0) { | |
294 fdatastart = segment->fileoff; | |
295 fdatasize = segment->filesize; | |
296 fgrowth = (data_size - | |
297 segment->filesize); | |
298 segment->vmsize = data_size; | |
299 segment->filesize = data_size; | |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
300 dataseg_vmaddr = segment->vmaddr; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
301 dataseg_vmend = segment->vmaddr + segment->vmsize; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
302 vmaddr_growth = segment->vmaddr + segment->vmsize; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
303 } else { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
304 ((struct segment_command *)the_commands[i])->fileoff += fgrowth; |
1349 | 305 } |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
306 |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
307 if( strcmp( segment->segname, SEG_LINKEDIT ) == 0 ) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
308 segment->vmaddr = vmaddr_growth; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
309 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
310 |
1349 | 311 break; |
312 case LC_SYMTAB: | |
313 ((struct symtab_command *) | |
314 the_commands[i])->symoff += fgrowth; | |
315 ((struct symtab_command *) | |
316 the_commands[i])->stroff += fgrowth; | |
317 break; | |
318 case LC_SYMSEG: | |
319 ((struct symseg_command *) | |
320 the_commands[i])->offset += fgrowth; | |
321 break; | |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
322 #ifdef NS_TARGET |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
323 case LC_DYSYMTAB: |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
324 dysymtab = ((struct dysymtab_command *)the_commands[i]); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
325 extreloff = dysymtab->extreloff; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
326 nextrel = dysymtab->nextrel; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
327 dysymtab->indirectsymoff += fgrowth; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
328 dysymtab->extreloff += fgrowth; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
329 break; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
330 #endif |
1349 | 331 default: |
332 break; | |
333 } | |
334 } | |
335 | |
336 /* | |
337 * Write header | |
338 */ | |
339 if (write(outfd, &the_header, | |
340 sizeof(the_header)) != sizeof(the_header)) { | |
341 fatal_unexec("cannot write output file"); | |
342 return (0); | |
343 } | |
344 | |
345 /* | |
346 * Write commands | |
347 */ | |
348 for (i = 0; i < the_commands_len; i++) { | |
349 if (write(outfd, the_commands[i], | |
350 the_commands[i]->cmdsize) != | |
351 the_commands[i]->cmdsize) { | |
352 fatal_unexec("cannot write output file"); | |
353 return (0); | |
354 } | |
355 } | |
356 | |
357 /* | |
358 * Write original text | |
359 */ | |
360 if (lseek(infd, the_header.sizeofcmds + sizeof(the_header), | |
361 L_SET) < 0) { | |
362 fatal_unexec("cannot seek input file"); | |
363 return (0); | |
364 } | |
365 size = fdatastart - (sizeof(the_header) + | |
366 the_header.sizeofcmds); | |
367 buf = my_malloc(size); | |
368 if (read(infd, buf, size) != size) { | |
369 my_free(buf, size); | |
370 fatal_unexec("cannot read input file"); | |
371 } | |
372 if (write(outfd, buf, size) != size) { | |
373 my_free(buf, size); | |
374 fatal_unexec("cannot write output file"); | |
375 return (0); | |
376 } | |
377 my_free(buf, size); | |
378 | |
379 | |
380 /* | |
381 * Write new data | |
382 */ | |
383 if (write(outfd, (char *)data_address, | |
384 data_size) != data_size) { | |
385 fatal_unexec("cannot write output file"); | |
386 return (0); | |
387 } | |
388 | |
389 } | |
390 | |
391 /* | |
392 * OKAY TO USE MALLOC NOW | |
393 */ | |
394 | |
395 /* | |
396 * Write rest of file | |
397 */ | |
398 fstat(infd, &st); | |
399 if (lseek(infd, fdatasize, L_INCR) < 0) { | |
400 fatal_unexec("cannot seek input file"); | |
401 return (0); | |
402 } | |
403 size = st.st_size - lseek(infd, 0, L_INCR); | |
404 | |
405 buf = malloc(size); | |
406 if (read(infd, buf, size) != size) { | |
407 free(buf); | |
408 fatal_unexec("cannot read input file"); | |
409 return (0); | |
410 } | |
411 if (write(outfd, buf, size) != size) { | |
412 free(buf); | |
413 fatal_unexec("cannot write output file"); | |
414 return (0); | |
415 } | |
416 free(buf); | |
16853
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
417 |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
418 #ifdef NS_TARGET |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
419 /* |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
420 * Fix up relocation entries in the data segment. |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
421 */ |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
422 |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
423 if (lseek(infd, extreloff, L_SET) < 0) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
424 fatal_unexec("cannot seek input file"); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
425 return (0); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
426 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
427 |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
428 for (i = 0; i < nextrel; i++) |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
429 { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
430 long zeroval = 0; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
431 |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
432 if (read(infd, &reloc_info, sizeof (reloc_info)) != sizeof (reloc_info)) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
433 fatal_unexec("cannot read input file"); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
434 return (0); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
435 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
436 if (reloc_info.r_address >= dataseg_vmaddr && reloc_info.r_address < dataseg_vmend) |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
437 { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
438 if (lseek (outfd, fdatastart + reloc_info.r_address - dataseg_vmaddr, L_SET) < 0 ) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
439 fatal_unexec("cannot seek input file"); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
440 return (0); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
441 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
442 switch (reloc_info.r_length) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
443 case 0: |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
444 if (write(outfd, &zeroval, 1) != 1) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
445 fatal_unexec("cannot write output file"); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
446 return (0); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
447 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
448 break; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
449 case 1: |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
450 if (write(outfd, &zeroval, 2) != 2) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
451 fatal_unexec("cannot write output file"); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
452 return (0); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
453 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
454 break; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
455 case 2: |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
456 if (write(outfd, &zeroval, 4) != 4) { |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
457 fatal_unexec("cannot write output file"); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
458 return (0); |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
459 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
460 break; |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
461 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
462 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
463 } |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
464 #endif |
63f2ad395c81
Include <mach-o/reloc.h>.
Richard M. Stallman <rms@gnu.org>
parents:
14186
diff
changeset
|
465 |
1349 | 466 return (1); |
467 } | |
468 | |
469 void | |
470 unexec( | |
471 char *outfile, | |
472 char *infile | |
473 ) | |
474 { | |
475 int infd; | |
476 int outfd; | |
477 char tmpbuf[L_tmpnam]; | |
478 char *tmpfile; | |
479 | |
480 infd = open(infile, O_RDONLY, 0); | |
481 if (infd < 0) { | |
482 fatal_unexec("cannot open input file `%s'", infile); | |
483 exit(1); | |
484 } | |
485 | |
486 tmpnam(tmpbuf); | |
487 tmpfile = rindex(tmpbuf, '/'); | |
488 if (tmpfile == NULL) { | |
489 tmpfile = tmpbuf; | |
490 } else { | |
491 tmpfile++; | |
492 } | |
493 outfd = open(tmpfile, O_WRONLY|O_TRUNC|O_CREAT, 0755); | |
494 if (outfd < 0) { | |
495 close(infd); | |
496 fatal_unexec("cannot open tmp file `%s'", tmpfile); | |
497 exit(1); | |
498 } | |
499 if (!unexec_doit(infd, outfd)) { | |
500 close(infd); | |
501 close(outfd); | |
502 unlink(tmpfile); | |
503 exit(1); | |
504 } | |
505 close(infd); | |
506 close(outfd); | |
507 if (rename(tmpfile, outfile) < 0) { | |
508 unlink(tmpfile); | |
509 fatal_unexec("cannot rename `%s' to `%s'", tmpfile, outfile); | |
510 exit(1); | |
511 } | |
512 } |