13 |
area with the current data area. When the new file is executed, the |
area with the current data area. When the new file is executed, the |
14 |
process will see the same data structures and data values that the |
process will see the same data structures and data values that the |
15 |
original process had when unexec was called. |
original process had when unexec was called. |
16 |
|
|
17 |
Unlike other versions of unexec, this one copies symbol table and |
Unlike other versions of unexec, this one copies symbol table and |
18 |
debug information to the new a.out file. Thus, the new a.out file |
debug information to the new a.out file. Thus, the new a.out file |
19 |
may be debugged with symbolic debuggers. |
may be debugged with symbolic debuggers. |
20 |
|
|
21 |
If you fix any bugs in this, I'd like to incorporate your fixes. |
If you fix any bugs in this, I'd like to incorporate your fixes. |
22 |
Send them to uunet!hpda!hpsemc!jmorris or jmorris%hpsemc@hplabs.HP.COM. |
Send them to uunet!hpda!hpsemc!jmorris or jmorris%hpsemc@hplabs.HP.COM. |
23 |
|
|
24 |
CAVEATS: |
CAVEATS: |
25 |
This routine saves the current value of all static and external |
This routine saves the current value of all static and external |
26 |
variables. This means that any data structure that needs to be |
variables. This means that any data structure that needs to be |
27 |
initialized must be explicitly reset. Variables will not have their |
initialized must be explicitly reset. Variables will not have their |
28 |
expected default values. |
expected default values. |
29 |
|
|
30 |
Unfortunately, the HP-UX signal handler has internal initialization |
Unfortunately, the HP-UX signal handler has internal initialization |
31 |
flags which are not explicitly reset. Thus, for signals to work in |
flags which are not explicitly reset. Thus, for signals to work in |
32 |
conjunction with this routine, the following code must executed when |
conjunction with this routine, the following code must executed when |
33 |
the new process starts up. |
the new process starts up. |
34 |
|
|
35 |
void _sigreturn (); |
void _sigreturn (); |
36 |
... |
... |
37 |
sigsetreturn (_sigreturn); |
sigsetreturn (_sigreturn); |
54 |
/* brk value to restore, stored as a global. |
/* brk value to restore, stored as a global. |
55 |
This is really used only if we used shared libraries. */ |
This is really used only if we used shared libraries. */ |
56 |
static long brk_on_dump = 0; |
static long brk_on_dump = 0; |
57 |
|
|
58 |
/* Called from main, if we use shared libraries. */ |
/* Called from main, if we use shared libraries. */ |
59 |
int |
int |
60 |
run_time_remap (ignored) |
run_time_remap (ignored) |
81 |
struct header hdr; |
struct header hdr; |
82 |
struct som_exec_auxhdr auxhdr; |
struct som_exec_auxhdr auxhdr; |
83 |
long i; |
long i; |
84 |
|
|
85 |
/* For the greatest flexibility, should create a temporary file in |
/* For the greatest flexibility, should create a temporary file in |
86 |
the same directory as the new file. When everything is complete, |
the same directory as the new file. When everything is complete, |
87 |
rename the temp file to the new name. |
rename the temp file to the new name. |
88 |
This way, a program could update its own a.out file even while |
This way, a program could update its own a.out file even while |
89 |
it is still executing. If problems occur, everything is still |
it is still executing. If problems occur, everything is still |
90 |
intact. NOT implemented. */ |
intact. NOT implemented. */ |
91 |
|
|
92 |
/* Open the input and output a.out files */ |
/* Open the input and output a.out files */ |
93 |
old = open (old_name, O_RDONLY); |
old = open (old_name, O_RDONLY); |
94 |
if (old < 0) |
if (old < 0) |
96 |
new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777); |
new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777); |
97 |
if (new < 0) |
if (new < 0) |
98 |
{ perror (new_name); exit (1); } |
{ perror (new_name); exit (1); } |
99 |
|
|
100 |
/* Read the old headers */ |
/* Read the old headers */ |
101 |
read_header (old, &hdr, &auxhdr); |
read_header (old, &hdr, &auxhdr); |
102 |
|
|
103 |
brk_on_dump = (long) sbrk (0); |
brk_on_dump = (long) sbrk (0); |
104 |
|
|
105 |
/* Decide how large the new and old data areas are */ |
/* Decide how large the new and old data areas are */ |
106 |
old_size = auxhdr.exec_dsize; |
old_size = auxhdr.exec_dsize; |
107 |
/* I suspect these two statements are separate |
/* I suspect these two statements are separate |
108 |
to avoid a compiler bug in hpux version 8. */ |
to avoid a compiler bug in hpux version 8. */ |
109 |
i = (long) sbrk (0); |
i = (long) sbrk (0); |
110 |
new_size = i - auxhdr.exec_dmem; |
new_size = i - auxhdr.exec_dmem; |
111 |
|
|
112 |
/* Copy the old file to the new, up to the data space */ |
/* Copy the old file to the new, up to the data space */ |
113 |
lseek (old, 0, 0); |
lseek (old, 0, 0); |
114 |
copy_file (old, new, auxhdr.exec_dfile); |
copy_file (old, new, auxhdr.exec_dfile); |
115 |
|
|
116 |
/* Skip the old data segment and write a new one */ |
/* Skip the old data segment and write a new one */ |
117 |
lseek (old, old_size, 1); |
lseek (old, old_size, 1); |
118 |
save_data_space (new, &hdr, &auxhdr, new_size); |
save_data_space (new, &hdr, &auxhdr, new_size); |
119 |
|
|
120 |
/* Copy the rest of the file */ |
/* Copy the rest of the file */ |
121 |
copy_rest (old, new); |
copy_rest (old, new); |
122 |
|
|
123 |
/* Update file pointers since we probably changed size of data area */ |
/* Update file pointers since we probably changed size of data area */ |
124 |
update_file_ptrs (new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size); |
update_file_ptrs (new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size); |
125 |
|
|
126 |
/* Save the modified header */ |
/* Save the modified header */ |
127 |
write_header (new, &hdr, &auxhdr); |
write_header (new, &hdr, &auxhdr); |
128 |
|
|
129 |
/* Close the binary file */ |
/* Close the binary file */ |
130 |
close (old); |
close (old); |
131 |
close (new); |
close (new); |
143 |
/* Write the entire data space out to the file */ |
/* Write the entire data space out to the file */ |
144 |
if (write (file, auxhdr->exec_dmem, size) != size) |
if (write (file, auxhdr->exec_dmem, size) != size) |
145 |
{ perror ("Can't save new data space"); exit (1); } |
{ perror ("Can't save new data space"); exit (1); } |
146 |
|
|
147 |
/* Update the header to reflect the new data size */ |
/* Update the header to reflect the new data size */ |
148 |
auxhdr->exec_dsize = size; |
auxhdr->exec_dsize = size; |
149 |
auxhdr->exec_bsize = 0; |
auxhdr->exec_bsize = 0; |
160 |
{ |
{ |
161 |
struct subspace_dictionary_record subspace; |
struct subspace_dictionary_record subspace; |
162 |
int i; |
int i; |
163 |
|
|
164 |
/* Increase the overall size of the module */ |
/* Increase the overall size of the module */ |
165 |
hdr->som_length += offset; |
hdr->som_length += offset; |
166 |
|
|
167 |
/* Update the various file pointers in the header */ |
/* Update the various file pointers in the header */ |
168 |
#define update(ptr) if (ptr > location) ptr = ptr + offset |
#define update(ptr) if (ptr > location) ptr = ptr + offset |
169 |
update (hdr->aux_header_location); |
update (hdr->aux_header_location); |
176 |
update (hdr->unloadable_sp_location); |
update (hdr->unloadable_sp_location); |
177 |
update (auxhdr->exec_tfile); |
update (auxhdr->exec_tfile); |
178 |
update (auxhdr->exec_dfile); |
update (auxhdr->exec_dfile); |
179 |
|
|
180 |
/* Do for each subspace dictionary entry */ |
/* Do for each subspace dictionary entry */ |
181 |
lseek (file, hdr->subspace_location, 0); |
lseek (file, hdr->subspace_location, 0); |
182 |
for (i = 0; i < hdr->subspace_total; i++) |
for (i = 0; i < hdr->subspace_total; i++) |
183 |
{ |
{ |
184 |
if (read (file, &subspace, sizeof (subspace)) != sizeof (subspace)) |
if (read (file, &subspace, sizeof (subspace)) != sizeof (subspace)) |
185 |
{ perror ("Can't read subspace record"); exit (1); } |
{ perror ("Can't read subspace record"); exit (1); } |
186 |
|
|
187 |
/* If subspace has a file location, update it */ |
/* If subspace has a file location, update it */ |
188 |
if (subspace.initialization_length > 0 |
if (subspace.initialization_length > 0 |
189 |
&& subspace.file_loc_init_value > location) |
&& subspace.file_loc_init_value > location) |
190 |
{ |
{ |
191 |
subspace.file_loc_init_value += offset; |
subspace.file_loc_init_value += offset; |
193 |
if (write (file, &subspace, sizeof (subspace)) != sizeof (subspace)) |
if (write (file, &subspace, sizeof (subspace)) != sizeof (subspace)) |
194 |
{ perror ("Can't update subspace record"); exit (1); } |
{ perror ("Can't update subspace record"); exit (1); } |
195 |
} |
} |
196 |
} |
} |
197 |
|
|
198 |
/* Do for each initialization pointer record */ |
/* Do for each initialization pointer record */ |
199 |
/* (I don't think it applies to executable files, only relocatables) */ |
/* (I don't think it applies to executable files, only relocatables) */ |
200 |
#undef update |
#undef update |
207 |
struct header *hdr; |
struct header *hdr; |
208 |
struct som_exec_auxhdr *auxhdr; |
struct som_exec_auxhdr *auxhdr; |
209 |
{ |
{ |
210 |
|
|
211 |
/* Read the header in */ |
/* Read the header in */ |
212 |
lseek (file, 0, 0); |
lseek (file, 0, 0); |
213 |
if (read (file, hdr, sizeof (*hdr)) != sizeof (*hdr)) |
if (read (file, hdr, sizeof (*hdr)) != sizeof (*hdr)) |
214 |
{ perror ("Couldn't read header from a.out file"); exit (1); } |
{ perror ("Couldn't read header from a.out file"); exit (1); } |
215 |
|
|
216 |
if (hdr->a_magic != EXEC_MAGIC && hdr->a_magic != SHARE_MAGIC |
if (hdr->a_magic != EXEC_MAGIC && hdr->a_magic != SHARE_MAGIC |
217 |
&& hdr->a_magic != DEMAND_MAGIC) |
&& hdr->a_magic != DEMAND_MAGIC) |
218 |
{ |
{ |
219 |
fprintf (stderr, "a.out file doesn't have legal magic number\n"); |
fprintf (stderr, "a.out file doesn't have legal magic number\n"); |
220 |
exit (1); |
exit (1); |
221 |
} |
} |
222 |
|
|
223 |
lseek (file, hdr->aux_header_location, 0); |
lseek (file, hdr->aux_header_location, 0); |
224 |
if (read (file, auxhdr, sizeof (*auxhdr)) != sizeof (*auxhdr)) |
if (read (file, auxhdr, sizeof (*auxhdr)) != sizeof (*auxhdr)) |
225 |
{ |
{ |
226 |
perror ("Couldn't read auxiliary header from a.out file"); |
perror ("Couldn't read auxiliary header from a.out file"); |
227 |
exit (1); |
exit (1); |
228 |
} |
} |
229 |
} |
} |
230 |
|
|
231 |
/* Write out the header records into an a.out file. */ |
/* Write out the header records into an a.out file. */ |
237 |
{ |
{ |
238 |
/* Update the checksum */ |
/* Update the checksum */ |
239 |
hdr->checksum = calculate_checksum (hdr); |
hdr->checksum = calculate_checksum (hdr); |
240 |
|
|
241 |
/* Write the header back into the a.out file */ |
/* Write the header back into the a.out file */ |
242 |
lseek (file, 0, 0); |
lseek (file, 0, 0); |
243 |
if (write (file, hdr, sizeof (*hdr)) != sizeof (*hdr)) |
if (write (file, hdr, sizeof (*hdr)) != sizeof (*hdr)) |
253 |
struct header *hdr; |
struct header *hdr; |
254 |
{ |
{ |
255 |
int checksum, i, *ptr; |
int checksum, i, *ptr; |
256 |
|
|
257 |
checksum = 0; ptr = (int *) hdr; |
checksum = 0; ptr = (int *) hdr; |
258 |
|
|
259 |
for (i = 0; i < sizeof (*hdr) / sizeof (int) - 1; i++) |
for (i = 0; i < sizeof (*hdr) / sizeof (int) - 1; i++) |
260 |
checksum ^= ptr[i]; |
checksum ^= ptr[i]; |
261 |
|
|
262 |
return (checksum); |
return (checksum); |
263 |
} |
} |
264 |
|
|
270 |
{ |
{ |
271 |
int len; |
int len; |
272 |
int buffer[8192]; /* word aligned will be faster */ |
int buffer[8192]; /* word aligned will be faster */ |
273 |
|
|
274 |
for (; size > 0; size -= len) |
for (; size > 0; size -= len) |
275 |
{ |
{ |
276 |
len = min (size, sizeof (buffer)); |
len = min (size, sizeof (buffer)); |
288 |
{ |
{ |
289 |
int buffer[4096]; |
int buffer[4096]; |
290 |
int len; |
int len; |
291 |
|
|
292 |
/* Copy bytes until end of file or error */ |
/* Copy bytes until end of file or error */ |
293 |
while ((len = read (old, buffer, sizeof (buffer))) > 0) |
while ((len = read (old, buffer, sizeof (buffer))) > 0) |
294 |
if (write (new, buffer, len) != len) break; |
if (write (new, buffer, len) != len) break; |
295 |
|
|
296 |
if (len != 0) |
if (len != 0) |
297 |
{ perror ("Unable to copy the rest of the file"); exit (1); } |
{ perror ("Unable to copy the rest of the file"); exit (1); } |
298 |
} |
} |
304 |
{ |
{ |
305 |
/* Display the header information (debug) */ |
/* Display the header information (debug) */ |
306 |
printf ("\n\nFILE HEADER\n"); |
printf ("\n\nFILE HEADER\n"); |
307 |
printf ("magic number %d \n", hdr->a_magic); |
printf ("magic number %d \n", hdr->a_magic); |
308 |
printf ("text loc %.8x size %d \n", auxhdr->exec_tmem, auxhdr->exec_tsize); |
printf ("text loc %.8x size %d \n", auxhdr->exec_tmem, auxhdr->exec_tsize); |
309 |
printf ("data loc %.8x size %d \n", auxhdr->exec_dmem, auxhdr->exec_dsize); |
printf ("data loc %.8x size %d \n", auxhdr->exec_dmem, auxhdr->exec_dsize); |
310 |
printf ("entry %x \n", auxhdr->exec_entry); |
printf ("entry %x \n", auxhdr->exec_entry); |