1 2 3 4 5 6 7 8 9 10 11
12
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
51
52 #ifdef emacs
53 #include <config.h>
54 #endif
55
56 #include <stdio.h>
57 #include <fcntl.h>
58 #include <errno.h>
59
60 #include <a.out.h>
61
62 #include <dl.h>
63
64 65
66 static long brk_on_dump = 0;
67
68
69 int
70 run_time_remap (ignored)
71 char *ignored;
72 {
73 brk ((char *) brk_on_dump);
74 }
75
76 #undef roundup
77 #define roundup(x,n) (((x) + ((n) - 1)) & ~((n) - 1))
78 #define min(x,y) (((x) < (y)) ? (x) : (y))
79
80
81
82
83 unexec (new_name, old_name, new_end_of_text, dummy1, dummy2)
84 char new_name[];
85 char old_name[];
86 char *new_end_of_text;
87 int dummy1, dummy2;
88 {
89 int old, new;
90 int old_size, new_size;
91 struct header hdr;
92 struct som_exec_auxhdr auxhdr;
93 long i;
94
95 96 97 98 99 100
101
102
103 old = open (old_name, O_RDONLY);
104 if (old < 0)
105 { perror (old_name); exit (1); }
106 new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777);
107 if (new < 0)
108 { perror (new_name); exit (1); }
109
110
111 read_header (old, &hdr, &auxhdr);
112
113 brk_on_dump = (long) sbrk (0);
114
115
116 old_size = auxhdr.exec_dsize;
117 118
119 i = (long) sbrk (0);
120 new_size = i - auxhdr.exec_dmem;
121
122
123 lseek (old, 0, 0);
124 copy_file (old, new, auxhdr.exec_dfile);
125
126
127 lseek (old, old_size, 1);
128 save_data_space (new, &hdr, &auxhdr, new_size);
129
130
131 copy_rest (old, new);
132
133
134 update_file_ptrs (new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size);
135
136
137 write_header (new, &hdr, &auxhdr);
138
139
140 close (old);
141 close (new);
142 return 0;
143 }
144
145
146
147 save_data_space (file, hdr, auxhdr, size)
148 int file;
149 struct header *hdr;
150 struct som_exec_auxhdr *auxhdr;
151 int size;
152 {
153
154 if (write (file, auxhdr->exec_dmem, size) != size)
155 { perror ("Can't save new data space"); exit (1); }
156
157
158 auxhdr->exec_dsize = size;
159 auxhdr->exec_bsize = 0;
160 }
161
162
163
164 update_file_ptrs (file, hdr, auxhdr, location, offset)
165 int file;
166 struct header *hdr;
167 struct som_exec_auxhdr *auxhdr;
168 unsigned int location;
169 int offset;
170 {
171 struct subspace_dictionary_record subspace;
172 int i;
173
174
175 hdr->som_length += offset;
176
177
178 #define update(ptr) if (ptr > location) ptr = ptr + offset
179 update (hdr->aux_header_location);
180 update (hdr->space_strings_location);
181 update (hdr->init_array_location);
182 update (hdr->compiler_location);
183 update (hdr->symbol_location);
184 update (hdr->fixup_request_location);
185 update (hdr->symbol_strings_location);
186 update (hdr->unloadable_sp_location);
187 update (auxhdr->exec_tfile);
188 update (auxhdr->exec_dfile);
189
190
191 lseek (file, hdr->subspace_location, 0);
192 for (i = 0; i < hdr->subspace_total; i++)
193 {
194 if (read (file, &subspace, sizeof (subspace)) != sizeof (subspace))
195 { perror ("Can't read subspace record"); exit (1); }
196
197
198 if (subspace.initialization_length > 0
199 && subspace.file_loc_init_value > location)
200 {
201 subspace.file_loc_init_value += offset;
202 lseek (file, -sizeof (subspace), 1);
203 if (write (file, &subspace, sizeof (subspace)) != sizeof (subspace))
204 { perror ("Can't update subspace record"); exit (1); }
205 }
206 }
207
208
209
210 #undef update
211 }
212
213
214
215 read_header (file, hdr, auxhdr)
216 int file;
217 struct header *hdr;
218 struct som_exec_auxhdr *auxhdr;
219 {
220
221
222 lseek (file, 0, 0);
223 if (read (file, hdr, sizeof (*hdr)) != sizeof (*hdr))
224 { perror ("Couldn't read header from a.out file"); exit (1); }
225
226 if (hdr->a_magic != EXEC_MAGIC && hdr->a_magic != SHARE_MAGIC
227 && hdr->a_magic != DEMAND_MAGIC)
228 {
229 fprintf (stderr, "a.out file doesn't have valid magic number\n");
230 exit (1);
231 }
232
233 lseek (file, hdr->aux_header_location, 0);
234 if (read (file, auxhdr, sizeof (*auxhdr)) != sizeof (*auxhdr))
235 {
236 perror ("Couldn't read auxiliary header from a.out file");
237 exit (1);
238 }
239 }
240
241
242
243 write_header (file, hdr, auxhdr)
244 int file;
245 struct header *hdr;
246 struct som_exec_auxhdr *auxhdr;
247 {
248
249 hdr->checksum = calculate_checksum (hdr);
250
251
252 lseek (file, 0, 0);
253 if (write (file, hdr, sizeof (*hdr)) != sizeof (*hdr))
254 { perror ("Couldn't write header to a.out file"); exit (1); }
255 lseek (file, hdr->aux_header_location, 0);
256 if (write (file, auxhdr, sizeof (*auxhdr)) != sizeof (*auxhdr))
257 { perror ("Couldn't write auxiliary header to a.out file"); exit (1); }
258 }
259
260
261
262 calculate_checksum (hdr)
263 struct header *hdr;
264 {
265 int checksum, i, *ptr;
266
267 checksum = 0; ptr = (int *) hdr;
268
269 for (i = 0; i < sizeof (*hdr) / sizeof (int) - 1; i++)
270 checksum ^= ptr[i];
271
272 return (checksum);
273 }
274
275
276
277 copy_file (old, new, size)
278 int new, old;
279 int size;
280 {
281 int len;
282 int buffer[8192];
283
284 for (; size > 0; size -= len)
285 {
286 len = min (size, sizeof (buffer));
287 if (read (old, buffer, len) != len)
288 { perror ("Read failure on a.out file"); exit (1); }
289 if (write (new, buffer, len) != len)
290 { perror ("Write failure in a.out file"); exit (1); }
291 }
292 }
293
294
295
296 copy_rest (old, new)
297 int new, old;
298 {
299 int buffer[4096];
300 int len;
301
302
303 while ((len = read (old, buffer, sizeof (buffer))) > 0)
304 if (write (new, buffer, len) != len) break;
305
306 if (len != 0)
307 { perror ("Unable to copy the rest of the file"); exit (1); }
308 }
309
310 #ifdef DEBUG
311 display_header (hdr, auxhdr)
312 struct header *hdr;
313 struct som_exec_auxhdr *auxhdr;
314 {
315
316 printf ("\n\nFILE HEADER\n");
317 printf ("magic number %d \n", hdr->a_magic);
318 printf ("text loc %.8x size %d \n", auxhdr->exec_tmem, auxhdr->exec_tsize);
319 printf ("data loc %.8x size %d \n", auxhdr->exec_dmem, auxhdr->exec_dsize);
320 printf ("entry %x \n", auxhdr->exec_entry);
321 printf ("Bss segment size %u\n", auxhdr->exec_bsize);
322 printf ("\n");
323 printf ("data file loc %d size %d\n",
324 auxhdr->exec_dfile, auxhdr->exec_dsize);
325 printf ("som_length %d\n", hdr->som_length);
326 printf ("unloadable sploc %d size %d\n",
327 hdr->unloadable_sp_location, hdr->unloadable_sp_size);
328 }
329 #endif
330
331 332