comparison src/unexelfsgi.c @ 444:576fb035e263 r21-2-37

Import from CVS: tag r21-2-37
author cvs
date Mon, 13 Aug 2007 11:36:19 +0200
parents 8de8e3f6228a
children 1ccc32a20af4
comparison
equal deleted inserted replaced
443:a8296e22da4e 444:576fb035e263
1 /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992 1 /* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992, 1999, 2000
2 Free Software Foundation, Inc. 2 Free Software Foundation, Inc.
3 3
4 This file is part of XEmacs. 4 This file is part of XEmacs.
5 5
6 XEmacs is free software; you can redistribute it and/or modify it 6 XEmacs is free software; you can redistribute it and/or modify
7 under the terms of the GNU General Public License as published by the 7 it under the terms of the GNU General Public License as published by
8 Free Software Foundation; either version 2, or (at your option) any 8 the Free Software Foundation; either version 2, or (at your option)
9 later version. 9 any later version.
10 10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT 11 GNU Emacs is distributed in the hope that it will be useful,
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to 17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */ 19 Boston, MA 02111-1307, USA.
20 20
21 /* Synched up with: FSF 19.31. */ 21 In other words, you are welcome to use, share and improve this program.
22 22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding! */
24
25 /* 2000-10-31: Martin Buchholz
26
27 I noticed that xemacs on Irix 6.5 could not write to stderr, e.g.
28 (external-debugging-output "\n")
29 would produce NO output.
30 temacs worked fine, so this was clearly a dumping problem.
31
32 So I copied over the latest available unexelf.c from FSF Emacs,
33 and installed it as unexelfsgi.c in XEmacs.
34 In addition, I converted it to "Clean C", resulting in this file.
35 */
23 36
24 /* 37 /*
25 * unexec.c - Convert a running program into an a.out file. 38 * unexec.c - Convert a running program into an a.out file.
26 * 39 *
27 * Author: Spencer W. Thomas 40 * Author: Spencer W. Thomas
29 * University of Utah 42 * University of Utah
30 * Date: Tue Mar 2 1982 43 * Date: Tue Mar 2 1982
31 * Modified heavily since then. 44 * Modified heavily since then.
32 * 45 *
33 * Synopsis: 46 * Synopsis:
34 * unexec (new_name, a_name, data_start, bss_start, entry_address) 47 * unexec (new_name, old_name, data_start, bss_start, entry_address)
35 * char *new_name, *a_name; 48 * char *new_name, *old_name;
36 * unsigned data_start, bss_start, entry_address; 49 * unsigned data_start, bss_start, entry_address;
37 * 50 *
38 * Takes a snapshot of the program and makes an a.out format file in the 51 * Takes a snapshot of the program and makes an a.out format file in the
39 * file named by the string argument new_name. 52 * file named by the string argument new_name.
40 * If a_name is non-NULL, the symbol table will be taken from the given file. 53 * If old_name is non-NULL, the symbol table will be taken from the given file.
41 * On some machines, an existing a_name file is required. 54 * On some machines, an existing old_name file is required.
42 * 55 *
43 * The boundaries within the a.out file may be adjusted with the data_start 56 * The boundaries within the a.out file may be adjusted with the data_start
44 * and bss_start arguments. Either or both may be given as 0 for defaults. 57 * and bss_start arguments. Either or both may be given as 0 for defaults.
45 * 58 *
46 * Data_start gives the boundary between the text segment and the data 59 * Data_start gives the boundary between the text segment and the data
48 * program code and literal data, while the data segment is always unshared 61 * program code and literal data, while the data segment is always unshared
49 * and unprotected. Data_start gives the lowest unprotected address. 62 * and unprotected. Data_start gives the lowest unprotected address.
50 * The value you specify may be rounded down to a suitable boundary 63 * The value you specify may be rounded down to a suitable boundary
51 * as required by the machine you are using. 64 * as required by the machine you are using.
52 * 65 *
53 * Specifying zero for data_start means the boundary between text and data
54 * should not be the same as when the program was loaded.
55 * If NO_REMAP is defined, the argument data_start is ignored and the
56 * segment boundaries are never changed.
57 *
58 * Bss_start indicates how much of the data segment is to be saved in the 66 * Bss_start indicates how much of the data segment is to be saved in the
59 * a.out file and restored when the program is executed. It gives the lowest 67 * a.out file and restored when the program is executed. It gives the lowest
60 * unsaved address, and is rounded up to a page boundary. The default when 0 68 * unsaved address, and is rounded up to a page boundary. The default when 0
61 * is given assumes that the entire data segment is to be stored, including 69 * is given assumes that the entire data segment is to be stored, including
62 * the previous data and bss as well as any additional storage allocated with 70 * the previous data and bss as well as any additional storage allocated with
63 * break (2). 71 * break (2).
64 * 72 *
65 * The new file is set up to start at entry_address. 73 * The new file is set up to start at entry_address.
66 * 74 *
67 * If you make improvements I'd like to get them too.
68 * harpo!utah-cs!thomas, thomas@Utah-20
69 *
70 */ 75 */
71 76
72 /* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co. 77 /* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
73 * ELF support added. 78 * ELF support added.
74 * 79 *
97 **** SECTION HEADER TABLE **** 102 **** SECTION HEADER TABLE ****
98 [No] Type Flags Addr Offset Size Name 103 [No] Type Flags Addr Offset Size Name
99 Link Info Adralgn Entsize 104 Link Info Adralgn Entsize
100 105
101 [1] 1 2 0x80480d4 0xd4 0x13 .interp 106 [1] 1 2 0x80480d4 0xd4 0x13 .interp
102 0 0 0x1 0 107 0 0 0x1 0
103 108
104 [2] 5 2 0x80480e8 0xe8 0x388 .hash 109 [2] 5 2 0x80480e8 0xe8 0x388 .hash
105 3 0 0x4 0x4 110 3 0 0x4 0x4
106 111
107 [3] 11 2 0x8048470 0x470 0x7f0 .dynsym 112 [3] 11 2 0x8048470 0x470 0x7f0 .dynsym
108 4 1 0x4 0x10 113 4 1 0x4 0x10
109 114
110 [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr 115 [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
111 0 0 0x1 0 116 0 0 0x1 0
112 117
113 [5] 9 2 0x8049010 0x1010 0x338 .rel.plt 118 [5] 9 2 0x8049010 0x1010 0x338 .rel.plt
114 3 7 0x4 0x8 119 3 7 0x4 0x8
115 120
116 [6] 1 6 0x8049348 0x1348 0x3 .init 121 [6] 1 6 0x8049348 0x1348 0x3 .init
117 0 0 0x4 0 122 0 0 0x4 0
118 123
119 [7] 1 6 0x804934c 0x134c 0x680 .plt 124 [7] 1 6 0x804934c 0x134c 0x680 .plt
120 0 0 0x4 0x4 125 0 0 0x4 0x4
121 126
122 [8] 1 6 0x80499cc 0x19cc 0x3c56f .text 127 [8] 1 6 0x80499cc 0x19cc 0x3c56f .text
123 0 0 0x4 0 128 0 0 0x4 0
124 129
125 [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini 130 [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
126 0 0 0x4 0 131 0 0 0x4 0
127 132
128 [10] 1 2 0x8085f40 0x3df40 0x69c .rodata 133 [10] 1 2 0x8085f40 0x3df40 0x69c .rodata
129 0 0 0x4 0 134 0 0 0x4 0
130 135
131 [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 136 [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
132 0 0 0x4 0 137 0 0 0x4 0
133 138
134 [12] 1 3 0x8088330 0x3f330 0x20afc .data 139 [12] 1 3 0x8088330 0x3f330 0x20afc .data
135 0 0 0x4 0 140 0 0 0x4 0
136 141
137 [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 142 [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
138 0 0 0x4 0 143 0 0 0x4 0
139 144
140 [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got 145 [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
141 0 0 0x4 0x4 146 0 0 0x4 0x4
142 147
143 [15] 6 3 0x80a9874 0x60874 0x80 .dynamic 148 [15] 6 3 0x80a9874 0x60874 0x80 .dynamic
144 4 0 0x4 0x8 149 4 0 0x4 0x8
145 150
146 [16] 8 3 0x80a98f4 0x608f4 0x449c .bss 151 [16] 8 3 0x80a98f4 0x608f4 0x449c .bss
147 0 0 0x4 0 152 0 0 0x4 0
148 153
149 [17] 2 0 0 0x608f4 0x9b90 .symtab 154 [17] 2 0 0 0x608f4 0x9b90 .symtab
150 18 371 0x4 0x10 155 18 371 0x4 0x10
151 156
152 [18] 3 0 0 0x6a484 0x8526 .strtab 157 [18] 3 0 0 0x6a484 0x8526 .strtab
153 0 0 0x1 0 158 0 0 0x1 0
154 159
155 [19] 3 0 0 0x729aa 0x93 .shstrtab 160 [19] 3 0 0 0x729aa 0x93 .shstrtab
156 0 0 0x1 0 161 0 0 0x1 0
157 162
158 [20] 1 0 0 0x72a3d 0x68b7 .comment 163 [20] 1 0 0 0x72a3d 0x68b7 .comment
159 0 0 0x1 0 164 0 0 0x1 0
160 165
161 raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs 166 raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
162 167
163 xemacs: 168 xemacs:
164 169
165 **** SECTION HEADER TABLE **** 170 **** SECTION HEADER TABLE ****
166 [No] Type Flags Addr Offset Size Name 171 [No] Type Flags Addr Offset Size Name
167 Link Info Adralgn Entsize 172 Link Info Adralgn Entsize
168 173
169 [1] 1 2 0x80480d4 0xd4 0x13 .interp 174 [1] 1 2 0x80480d4 0xd4 0x13 .interp
170 0 0 0x1 0 175 0 0 0x1 0
171 176
172 [2] 5 2 0x80480e8 0xe8 0x388 .hash 177 [2] 5 2 0x80480e8 0xe8 0x388 .hash
173 3 0 0x4 0x4 178 3 0 0x4 0x4
174 179
175 [3] 11 2 0x8048470 0x470 0x7f0 .dynsym 180 [3] 11 2 0x8048470 0x470 0x7f0 .dynsym
176 4 1 0x4 0x10 181 4 1 0x4 0x10
177 182
178 [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr 183 [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
179 0 0 0x1 0 184 0 0 0x1 0
180 185
181 [5] 9 2 0x8049010 0x1010 0x338 .rel.plt 186 [5] 9 2 0x8049010 0x1010 0x338 .rel.plt
182 3 7 0x4 0x8 187 3 7 0x4 0x8
183 188
184 [6] 1 6 0x8049348 0x1348 0x3 .init 189 [6] 1 6 0x8049348 0x1348 0x3 .init
185 0 0 0x4 0 190 0 0 0x4 0
186 191
187 [7] 1 6 0x804934c 0x134c 0x680 .plt 192 [7] 1 6 0x804934c 0x134c 0x680 .plt
188 0 0 0x4 0x4 193 0 0 0x4 0x4
189 194
190 [8] 1 6 0x80499cc 0x19cc 0x3c56f .text 195 [8] 1 6 0x80499cc 0x19cc 0x3c56f .text
191 0 0 0x4 0 196 0 0 0x4 0
192 197
193 [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini 198 [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
194 0 0 0x4 0 199 0 0 0x4 0
195 200
196 [10] 1 2 0x8085f40 0x3df40 0x69c .rodata 201 [10] 1 2 0x8085f40 0x3df40 0x69c .rodata
197 0 0 0x4 0 202 0 0 0x4 0
198 203
199 [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 204 [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
200 0 0 0x4 0 205 0 0 0x4 0
201 206
202 [12] 1 3 0x8088330 0x3f330 0x20afc .data 207 [12] 1 3 0x8088330 0x3f330 0x20afc .data
203 0 0 0x4 0 208 0 0 0x4 0
204 209
205 [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 210 [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
206 0 0 0x4 0 211 0 0 0x4 0
207 212
208 [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got 213 [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
209 0 0 0x4 0x4 214 0 0 0x4 0x4
210 215
211 [15] 6 3 0x80a9874 0x60874 0x80 .dynamic 216 [15] 6 3 0x80a9874 0x60874 0x80 .dynamic
212 4 0 0x4 0x8 217 4 0 0x4 0x8
213 218
214 [16] 8 3 0x80c6800 0x7d800 0 .bss 219 [16] 8 3 0x80c6800 0x7d800 0 .bss
215 0 0 0x4 0 220 0 0 0x4 0
216 221
217 [17] 2 0 0 0x7d800 0x9b90 .symtab 222 [17] 2 0 0 0x7d800 0x9b90 .symtab
218 18 371 0x4 0x10 223 18 371 0x4 0x10
219 224
220 [18] 3 0 0 0x87390 0x8526 .strtab 225 [18] 3 0 0 0x87390 0x8526 .strtab
221 0 0 0x1 0 226 0 0 0x1 0
222 227
223 [19] 3 0 0 0x8f8b6 0x93 .shstrtab 228 [19] 3 0 0 0x8f8b6 0x93 .shstrtab
224 0 0 0x1 0 229 0 0 0x1 0
225 230
226 [20] 1 0 0 0x8f949 0x68b7 .comment 231 [20] 1 0 0 0x8f949 0x68b7 .comment
227 0 0 0x1 0 232 0 0 0x1 0
228 233
229 [21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data 234 [21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
230 0 0 0x4 0 235 0 0 0x4 0
231 236
232 * This is an example of how the file header is changed. "Shoff" is 237 * This is an example of how the file header is changed. "Shoff" is
233 * the section header offset within the file. Since that table is 238 * the section header offset within the file. Since that table is
234 * after the new .data section, it is moved. "Shnum" is the number of 239 * after the new .data section, it is moved. "Shnum" is the number of
235 * sections, which we increment. 240 * sections, which we increment.
275 temacs: 280 temacs:
276 ***** PROGRAM EXECUTION HEADER ***** 281 ***** PROGRAM EXECUTION HEADER *****
277 Type Offset Vaddr Paddr 282 Type Offset Vaddr Paddr
278 Filesz Memsz Flags Align 283 Filesz Memsz Flags Align
279 284
280 6 0x34 0x8048034 0 285 6 0x34 0x8048034 0
281 0xa0 0xa0 5 0 286 0xa0 0xa0 5 0
282 287
283 3 0xd4 0 0 288 3 0xd4 0 0
284 0x13 0 4 0 289 0x13 0 4 0
285 290
286 1 0x34 0x8048034 0 291 1 0x34 0x8048034 0
287 0x3f2f9 0x3f2f9 5 0x1000 292 0x3f2f9 0x3f2f9 5 0x1000
288 293
289 1 0x3f330 0x8088330 0 294 1 0x3f330 0x8088330 0
290 0x215c4 0x25a60 7 0x1000 295 0x215c4 0x25a60 7 0x1000
291 296
292 2 0x60874 0x80a9874 0 297 2 0x60874 0x80a9874 0
293 0x80 0 7 0 298 0x80 0 7 0
294 299
295 raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs 300 raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
296 301
297 xemacs: 302 xemacs:
298 ***** PROGRAM EXECUTION HEADER ***** 303 ***** PROGRAM EXECUTION HEADER *****
299 Type Offset Vaddr Paddr 304 Type Offset Vaddr Paddr
300 Filesz Memsz Flags Align 305 Filesz Memsz Flags Align
301 306
302 6 0x34 0x8048034 0 307 6 0x34 0x8048034 0
303 0xa0 0xa0 5 0 308 0xa0 0xa0 5 0
304 309
305 3 0xd4 0 0 310 3 0xd4 0 0
306 0x13 0 4 0 311 0x13 0 4 0
307 312
308 1 0x34 0x8048034 0 313 1 0x34 0x8048034 0
309 0x3f2f9 0x3f2f9 5 0x1000 314 0x3f2f9 0x3f2f9 5 0x1000
310 315
311 1 0x3f330 0x8088330 0 316 1 0x3f330 0x8088330 0
312 0x3e4d0 0x3e4d0 7 0x1000 317 0x3e4d0 0x3e4d0 7 0x1000
313 318
314 2 0x60874 0x80a9874 0 319 2 0x60874 0x80a9874 0
315 0x80 0 7 0 320 0x80 0 7 0
316 321
317 322
318 */ 323 */
319 324
320 /* Modified by wtien@urbana.mcd.mot.com of Motorola Inc. 325 /* Modified by wtien@urbana.mcd.mot.com of Motorola Inc.
321 * 326 *
322 * The above mechanism does not work if the unexeced ELF file is being 327 * The above mechanism does not work if the unexeced ELF file is being
323 * re-layout by other applications (such as `strip'). All the applications 328 * re-layout by other applications (such as `strip'). All the applications
324 * that re-layout the internal of ELF will layout all sections in ascending 329 * that re-layout the internal of ELF will layout all sections in ascending
325 * order of their file offsets. After the re-layout, the data2 section will 330 * order of their file offsets. After the re-layout, the data2 section will
326 * still be the LAST section in the section header vector, but its file offset 331 * still be the LAST section in the section header vector, but its file offset
327 * is now being pushed far away down, and causes part of it not to be mapped 332 * is now being pushed far away down, and causes part of it not to be mapped
328 * in (ie. not covered by the load segment entry in PHDR vector), therefore 333 * in (ie. not covered by the load segment entry in PHDR vector), therefore
329 * causes the new binary to fail. 334 * causes the new binary to fail.
330 * 335 *
331 * The solution is to modify the unexec algorithm to insert the new data2 336 * The solution is to modify the unexec algorithm to insert the new data2
332 * section header right before the new bss section header, so their file 337 * section header right before the new bss section header, so their file
333 * offsets will be in the ascending order. Since some of the section's (all 338 * offsets will be in the ascending order. Since some of the section's (all
334 * sections AFTER the bss section) indexes are now changed, we also need to 339 * sections AFTER the bss section) indexes are now changed, we also need to
335 * modify some fields to make them point to the right sections. This is done 340 * modify some fields to make them point to the right sections. This is done
336 * by macro PATCH_INDEX. All the fields that need to be patched are: 341 * by macro PATCH_INDEX. All the fields that need to be patched are:
337 * 342 *
338 * 1. ELF header e_shstrndx field. 343 * 1. ELF header e_shstrndx field.
339 * 2. section header sh_link and sh_info field. 344 * 2. section header sh_link and sh_info field.
340 * 3. symbol table entry st_shndx field. 345 * 3. symbol table entry st_shndx field.
341 * 346 *
342 * The above example now should look like: 347 * The above example now should look like:
344 **** SECTION HEADER TABLE **** 349 **** SECTION HEADER TABLE ****
345 [No] Type Flags Addr Offset Size Name 350 [No] Type Flags Addr Offset Size Name
346 Link Info Adralgn Entsize 351 Link Info Adralgn Entsize
347 352
348 [1] 1 2 0x80480d4 0xd4 0x13 .interp 353 [1] 1 2 0x80480d4 0xd4 0x13 .interp
349 0 0 0x1 0 354 0 0 0x1 0
350 355
351 [2] 5 2 0x80480e8 0xe8 0x388 .hash 356 [2] 5 2 0x80480e8 0xe8 0x388 .hash
352 3 0 0x4 0x4 357 3 0 0x4 0x4
353 358
354 [3] 11 2 0x8048470 0x470 0x7f0 .dynsym 359 [3] 11 2 0x8048470 0x470 0x7f0 .dynsym
355 4 1 0x4 0x10 360 4 1 0x4 0x10
356 361
357 [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr 362 [4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
358 0 0 0x1 0 363 0 0 0x1 0
359 364
360 [5] 9 2 0x8049010 0x1010 0x338 .rel.plt 365 [5] 9 2 0x8049010 0x1010 0x338 .rel.plt
361 3 7 0x4 0x8 366 3 7 0x4 0x8
362 367
363 [6] 1 6 0x8049348 0x1348 0x3 .init 368 [6] 1 6 0x8049348 0x1348 0x3 .init
364 0 0 0x4 0 369 0 0 0x4 0
365 370
366 [7] 1 6 0x804934c 0x134c 0x680 .plt 371 [7] 1 6 0x804934c 0x134c 0x680 .plt
367 0 0 0x4 0x4 372 0 0 0x4 0x4
368 373
369 [8] 1 6 0x80499cc 0x19cc 0x3c56f .text 374 [8] 1 6 0x80499cc 0x19cc 0x3c56f .text
370 0 0 0x4 0 375 0 0 0x4 0
371 376
372 [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini 377 [9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
373 0 0 0x4 0 378 0 0 0x4 0
374 379
375 [10] 1 2 0x8085f40 0x3df40 0x69c .rodata 380 [10] 1 2 0x8085f40 0x3df40 0x69c .rodata
376 0 0 0x4 0 381 0 0 0x4 0
377 382
378 [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1 383 [11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
379 0 0 0x4 0 384 0 0 0x4 0
380 385
381 [12] 1 3 0x8088330 0x3f330 0x20afc .data 386 [12] 1 3 0x8088330 0x3f330 0x20afc .data
382 0 0 0x4 0 387 0 0 0x4 0
383 388
384 [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1 389 [13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
385 0 0 0x4 0 390 0 0 0x4 0
386 391
387 [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got 392 [14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
388 0 0 0x4 0x4 393 0 0 0x4 0x4
389 394
390 [15] 6 3 0x80a9874 0x60874 0x80 .dynamic 395 [15] 6 3 0x80a9874 0x60874 0x80 .dynamic
391 4 0 0x4 0x8 396 4 0 0x4 0x8
392 397
393 [16] 1 3 0x80a98f4 0x608f4 0x1cf0c .data 398 [16] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
394 0 0 0x4 0 399 0 0 0x4 0
395 400
396 [17] 8 3 0x80c6800 0x7d800 0 .bss 401 [17] 8 3 0x80c6800 0x7d800 0 .bss
397 0 0 0x4 0 402 0 0 0x4 0
398 403
399 [18] 2 0 0 0x7d800 0x9b90 .symtab 404 [18] 2 0 0 0x7d800 0x9b90 .symtab
400 19 371 0x4 0x10 405 19 371 0x4 0x10
401 406
402 [19] 3 0 0 0x87390 0x8526 .strtab 407 [19] 3 0 0 0x87390 0x8526 .strtab
403 0 0 0x1 0 408 0 0 0x1 0
404 409
405 [20] 3 0 0 0x8f8b6 0x93 .shstrtab 410 [20] 3 0 0 0x8f8b6 0x93 .shstrtab
406 0 0 0x1 0 411 0 0 0x1 0
407 412
408 [21] 1 0 0 0x8f949 0x68b7 .comment 413 [21] 1 0 0 0x8f949 0x68b7 .comment
409 0 0 0x1 0 414 0 0 0x1 0
410 415
411 */ 416 */
412
413 /* More mods, by Jack Repenning <jackr@sgi.com>, Fri Aug 11 15:45:52 1995
414
415 Same algorithm as immediately above. However, the detailed
416 calculations of the various locations needed significant
417 overhaul.
418
419 At the point of the old .bss, the file offsets and the memory
420 addresses do distinct, slightly snaky things:
421
422 offset of .bss is meaningless and unpredictable
423 addr of .bss is meaningful
424 alignment of .bss is important to addr, so there may be a small
425 gap in address range before start of bss
426 offset of next section is rounded up modulo 0x1000
427 the hole so-introduced is zero-filled, so it can be mapped in as
428 the first partial-page of bss (the rest of the bss is mapped from
429 /dev/zero)
430 I suppose you could view this not as a hole, but as the beginning
431 of the bss, actually present in the file. But you should not
432 push that worldview too far, as the linker still knows that the
433 "offset" claimed for the bss is unused, and seems not always
434 careful about setting it.
435
436 We are doing all our tricks at this same rather complicated
437 location (isn't life fun?):
438
439 insert a new data section to contain now-initialized old bss and
440 heap
441 define a zero-length bss just so there is one
442
443 The offset of the new data section is dictated by its current
444 address (which, of course, we want also to be its addr): the
445 loader maps in the whole file region containing old data, rodata,
446 got, and new data as a single mapped segment, starting at the
447 address of the first chunk; the rest have to be laid out in the
448 file such that the map into the right spots. That is:
449
450 offset(newdata) ==
451 addrInRunningMemory(newdata)-aIRM(olddata)
452 + offset(oldData)
453
454 This would not necessarily match the oldbss offset, even if it
455 were carefully calculated! We must compute this.
456
457 The linker that built temacs has also already arranged that
458 olddata is properly page-aligned (not necessarily beginning on a
459 page, but rather that a page's worth of the low bits of addr and
460 offset match). We preserve this.
461
462 addr(bss) is alignment-constrained from the end of the new data.
463 Since we base endof(newdata) on sbrk(), we have a page boundary
464 (in both offset and addr) and meet any alignment constraint,
465 needing no alignment adjustment of this location and no
466 mini-hole. Or, if you like, we've allowed sbrk() to "compute"
467 the mini-hole size for us.
468
469 That puts newbss beginning on a page boundary, both in offset and
470 addr. (offset(bss) is still meaningless, but what the heck,
471 we'll fix it up.)
472
473 Since newbss has zero length, and its offset (however
474 meaningless) is page aligned, we place the next section exactly
475 there, with no hole needed to restore page alignment.
476
477 So, the shift for all sections beyond the playing field is:
478
479 new_bss_addr - roundup(old_bss_addr,0x1000)
480
481 */
482 /* Still more mods... Olivier Galibert 19971705
483 - support for .sbss section (automagically changed to data without
484 name change)
485 - support for 64bits ABI (will need a bunch of fixes in the rest
486 of the code before it works
487 */
488 417
418 #ifndef emacs
419 #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1)
420 #include <string.h>
421 #else
422 #include <config.h>
423 extern void fatal (const char *, ...);
424 #endif
425
489 #include <sys/types.h> 426 #include <sys/types.h>
490 #include <stdio.h> 427 #include <stdio.h>
491 #include <sys/stat.h> 428 #include <sys/stat.h>
492 #include <memory.h> 429 #include <memory.h>
493 #include <string.h>
494 #include <errno.h> 430 #include <errno.h>
495 #include <unistd.h> 431 #include <unistd.h>
496 #include <fcntl.h> 432 #include <fcntl.h>
433 #if !defined (__NetBSD__) && !defined (__OpenBSD__)
497 #include <elf.h> 434 #include <elf.h>
498 #include <sym.h> /* for HDRR declaration */ 435 #endif
499 #include <sys/mman.h> 436 #include <sys/mman.h>
500 #include <config.h> 437 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
501 #include "lisp.h" 438 #include <sys/elf_mips.h>
502 439 #include <sym.h>
503 /* in 64bits mode, use 64bits elf */ 440 #endif /* __sony_news && _SYSTYPE_SYSV */
504 #ifdef _ABI64 441 #if __sgi
505 typedef Elf64_Shdr l_Elf_Shdr; 442 #include <syms.h> /* for HDRR declaration */
506 typedef Elf64_Phdr l_Elf_Phdr; 443 #endif /* __sgi */
507 typedef Elf64_Ehdr l_Elf_Ehdr; 444
508 typedef Elf64_Addr l_Elf_Addr; 445 #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
509 typedef Elf64_Word l_Elf_Word; 446 /* Declare COFF debugging symbol table. This used to be in
510 typedef Elf64_Off l_Elf_Off; 447 /usr/include/sym.h, but this file is no longer included in Red Hat
511 typedef Elf64_Sym l_Elf_Sym; 448 5.0 and presumably in any other glibc 2.x based distribution. */
512 #else 449 typedef struct {
513 typedef Elf32_Shdr l_Elf_Shdr; 450 short magic;
514 typedef Elf32_Phdr l_Elf_Phdr; 451 short vstamp;
515 typedef Elf32_Ehdr l_Elf_Ehdr; 452 int ilineMax;
516 typedef Elf32_Addr l_Elf_Addr; 453 int idnMax;
517 typedef Elf32_Word l_Elf_Word; 454 int ipdMax;
518 typedef Elf32_Off l_Elf_Off; 455 int isymMax;
519 typedef Elf32_Sym l_Elf_Sym; 456 int ioptMax;
520 #endif 457 int iauxMax;
521 458 int issMax;
459 int issExtMax;
460 int ifdMax;
461 int crfd;
462 int iextMax;
463 long cbLine;
464 long cbLineOffset;
465 long cbDnOffset;
466 long cbPdOffset;
467 long cbSymOffset;
468 long cbOptOffset;
469 long cbAuxOffset;
470 long cbSsOffset;
471 long cbSsExtOffset;
472 long cbFdOffset;
473 long cbRfdOffset;
474 long cbExtOffset;
475 } HDRR, *pHDRR;
476 #define cbHDRR sizeof(HDRR)
477 #define hdrNil ((pHDRR)0)
478 #endif
479
480 #ifdef __NetBSD__
481 /*
482 * NetBSD does not have normal-looking user-land ELF support.
483 */
484 # if defined __alpha__ || defined __sparc_v9__
485 # define ELFSIZE 64
486 # else
487 # define ELFSIZE 32
488 # endif
489 # include <sys/exec_elf.h>
490
491 # ifndef PT_LOAD
492 # define PT_LOAD Elf_pt_load
493 # if 0 /* was in pkgsrc patches for 20.7 */
494 # define SHT_PROGBITS Elf_sht_progbits
495 # endif
496 # define SHT_SYMTAB Elf_sht_symtab
497 # define SHT_DYNSYM Elf_sht_dynsym
498 # define SHT_NULL Elf_sht_null
499 # define SHT_NOBITS Elf_sht_nobits
500 # define SHT_REL Elf_sht_rel
501 # define SHT_RELA Elf_sht_rela
502
503 # define SHN_UNDEF Elf_eshn_undefined
504 # define SHN_ABS Elf_eshn_absolute
505 # define SHN_COMMON Elf_eshn_common
506 # endif /* !PT_LOAD */
507
508 # ifdef __alpha__
509 # include <sys/exec_ecoff.h>
510 # define HDRR struct ecoff_symhdr
511 # define pHDRR HDRR *
512 # endif /* __alpha__ */
513
514 #ifdef __mips__ /* was in pkgsrc patches for 20.7 */
515 # define SHT_MIPS_DEBUG DT_MIPS_FLAGS
516 # define HDRR struct Elf_Shdr
517 #endif /* __mips__ */
518 #endif /* __NetBSD__ */
519
520 #ifdef __OpenBSD__
521 # include <sys/exec_elf.h>
522 #endif
523
524 #if __GNU_LIBRARY__ - 0 >= 6
525 # include <link.h> /* get ElfW etc */
526 #endif
527
528 #ifndef ElfW
529 # ifdef __STDC__
530 # define ElfBitsW(bits, type) Elf##bits##_##type
531 # else
532 # define ElfBitsW(bits, type) Elf/**/bits/**/_/**/type
533 # endif
534 # ifdef _LP64
535 # define ELFSIZE 64
536 # else
537 # define ELFSIZE 32
538 # endif
539 /* This macro expands `bits' before invoking ElfBitsW. */
540 # define ElfExpandBitsW(bits, type) ElfBitsW (bits, type)
541 # define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
542 #endif
543
544 #ifndef ELF_BSS_SECTION_NAME
545 #define ELF_BSS_SECTION_NAME ".bss"
546 #endif
522 547
523 /* Get the address of a particular section or program header entry, 548 /* Get the address of a particular section or program header entry,
524 * accounting for the size of the entries. 549 * accounting for the size of the entries.
525 */ 550 */
551 /*
552 On PPC Reference Platform running Solaris 2.5.1
553 the plt section is also of type NOBI like the bss section.
554 (not really stored) and therefore sections after the bss
555 section start at the plt offset. The plt section is always
556 the one just before the bss section.
557 Thus, we modify the test from
558 if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
559 to
560 if (NEW_SECTION_H (nn).sh_offset >=
561 OLD_SECTION_H (old_bss_index-1).sh_offset)
562 This is just a hack. We should put the new data section
563 before the .plt section.
564 And we should not have this routine at all but use
565 the libelf library to read the old file and create the new
566 file.
567 The changed code is minimal and depends on prep set in m/prep.h
568 Erik Deumens
569 Quantum Theory Project
570 University of Florida
571 deumens@qtp.ufl.edu
572 Apr 23, 1996
573 */
526 574
527 #define OLD_SECTION_H(n) \ 575 #define OLD_SECTION_H(n) \
528 (*(l_Elf_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) 576 (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
529 #define NEW_SECTION_H(n) \ 577 #define NEW_SECTION_H(n) \
530 (*(l_Elf_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) 578 (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
531 #define OLD_PROGRAM_H(n) \ 579 #define OLD_PROGRAM_H(n) \
532 (*(l_Elf_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) 580 (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
533 #define NEW_PROGRAM_H(n) \ 581 #define NEW_PROGRAM_H(n) \
534 (*(l_Elf_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) 582 (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
535 583
536 #define PATCH_INDEX(n) \ 584 #define PATCH_INDEX(n) \
537 do { \ 585 do { \
538 if ((n) >= old_bss_index) \ 586 if ((int) (n) >= old_bss_index) \
539 (n)++; } while (0) 587 (n)++; } while (0)
540 typedef unsigned char byte; 588 typedef unsigned char byte;
541 589
542 /* Round X up to a multiple of Y. */ 590 /* Round X up to a multiple of Y. */
543 591
544 static int 592 static ElfW(Addr)
545 round_up (int x, int y) 593 round_up (ElfW(Addr) x, ElfW(Addr) y)
546 { 594 {
547 int rem = x % y; 595 int rem = x % y;
548 if (rem == 0) 596 if (rem == 0)
549 return x; 597 return x;
550 return x - rem + y; 598 return x - rem + y;
559 607
560 static int 608 static int
561 find_section (char *name, 609 find_section (char *name,
562 char *section_names, 610 char *section_names,
563 char *file_name, 611 char *file_name,
564 l_Elf_Ehdr *old_file_h, 612 ElfW(Ehdr) *old_file_h,
565 l_Elf_Shdr *old_section_h, 613 ElfW(Shdr) *old_section_h,
566 int noerror) 614 int noerror)
567 { 615 {
568 int idx; 616 int idx;
569 617
570 for (idx = 1; idx < old_file_h->e_shnum; idx++) 618 for (idx = 1; idx < old_file_h->e_shnum; idx++)
580 if (idx == old_file_h->e_shnum) 628 if (idx == old_file_h->e_shnum)
581 { 629 {
582 if (noerror) 630 if (noerror)
583 return -1; 631 return -1;
584 else 632 else
585 fatal ("Can't find .bss in %s.\n", file_name); 633 fatal ("Can't find %s in %s.\n", name, file_name);
586 } 634 }
587 635
588 return idx; 636 return idx;
589 } 637 }
590 638
595 * 643 *
596 * In ELF, this works by replacing the old .bss section with a new 644 * In ELF, this works by replacing the old .bss section with a new
597 * .data section, and inserting an empty .bss immediately afterwards. 645 * .data section, and inserting an empty .bss immediately afterwards.
598 * 646 *
599 */ 647 */
600 int 648 void
601 unexec (char *new_name, 649 unexec (char *new_name,
602 char *old_name, 650 char *old_name,
603 uintptr_t data_start, 651 uintptr_t data_start,
604 uintptr_t bss_start, 652 uintptr_t bss_start,
605 uintptr_t entry_address) 653 uintptr_t entry_address)
606 { 654 {
607 extern uintptr_t bss_end;
608 int new_file, old_file, new_file_size; 655 int new_file, old_file, new_file_size;
609 656
610 /* Pointers to the base of the image of the two files. */ 657 /* Pointers to the base of the image of the two files. */
611 caddr_t old_base, new_base; 658 caddr_t old_base, new_base;
612 659
613 /* Pointers to the file, program and section headers for the old and new 660 /* Pointers to the file, program and section headers for the old and new
614 files. */ 661 * files.
615 l_Elf_Ehdr *old_file_h, *new_file_h; 662 */
616 l_Elf_Phdr *old_program_h, *new_program_h; 663 ElfW(Ehdr) *old_file_h, *new_file_h;
617 l_Elf_Shdr *old_section_h, *new_section_h; 664 ElfW(Phdr) *old_program_h, *new_program_h;
618 l_Elf_Shdr *oldbss; 665 ElfW(Shdr) *old_section_h, *new_section_h;
619 666
620 /* Point to the section name table in the old file. */ 667 /* Point to the section name table in the old file */
621 char *old_section_names; 668 char *old_section_names;
622 669
623 l_Elf_Addr old_bss_addr, new_bss_addr; 670 ElfW(Addr) old_bss_addr, new_bss_addr;
624 l_Elf_Addr old_base_addr; 671 ElfW(Word) old_bss_size, new_data2_size;
625 l_Elf_Word old_bss_size, new_data2_size; 672 ElfW(Off) new_data2_offset;
626 l_Elf_Off new_data2_offset, new_base_offset; 673 ElfW(Addr) new_data2_addr;
627 l_Elf_Addr new_data2_addr; 674
628 l_Elf_Addr new_offsets_shift; 675 int n, nn;
629 676 int old_bss_index, old_sbss_index;
630 int n, nn, old_bss_index, old_data_index; 677 int old_data_index, new_data2_index;
631 int old_mdebug_index, old_sbss_index; 678 int old_mdebug_index;
632 struct stat stat_buf; 679 struct stat stat_buf;
633 680
634 /* Open the old file & map it into the address space. */ 681 /* Open the old file & map it into the address space. */
635 682
636 old_file = open (old_name, O_RDONLY); 683 old_file = open (old_name, O_RDONLY);
637 684
638 if (old_file < 0) 685 if (old_file < 0)
639 fatal ("Can't open %s for reading: errno %d\n", old_name, errno); 686 fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
640 687
641 if (fstat (old_file, &stat_buf) == -1) 688 if (fstat (old_file, &stat_buf) == -1)
642 fatal ("Can't fstat(%s): errno %d\n", old_name, errno); 689 fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
643 690
644 old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0); 691 old_base = (caddr_t) mmap ((caddr_t) 0, stat_buf.st_size,
692 PROT_READ, MAP_SHARED, old_file, 0);
645 693
646 if (old_base == (caddr_t) -1) 694 if (old_base == (caddr_t) -1)
647 fatal ("Can't mmap(%s): errno %d\n", old_name, errno); 695 fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
648 696
649 #ifdef DEBUG 697 #ifdef DEBUG
650 fprintf (stderr, "mmap(%s, %x) -> %x\n", old_name, stat_buf.st_size, 698 fprintf (stderr, "mmap (%s, %x) -> %x\n", old_name, stat_buf.st_size,
651 old_base); 699 old_base);
652 #endif 700 #endif
653 701
654 /* Get pointers to headers & section names. */ 702 /* Get pointers to headers & section names */
655 703
656 old_file_h = (l_Elf_Ehdr *) old_base; 704 old_file_h = (ElfW(Ehdr) *) old_base;
657 old_program_h = (l_Elf_Phdr *) ((byte *) old_base + old_file_h->e_phoff); 705 old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
658 old_section_h = (l_Elf_Shdr *) ((byte *) old_base + old_file_h->e_shoff); 706 old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
659 old_section_names 707 old_section_names = (char *) old_base
660 = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; 708 + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
661 709
662 /* Find the mdebug section, if any. */ 710 /* Find the mdebug section, if any. */
663 711
664 old_mdebug_index = find_section (".mdebug", old_section_names, 712 old_mdebug_index = find_section (".mdebug", old_section_names,
665 old_name, old_file_h, old_section_h, 1); 713 old_name, old_file_h, old_section_h, 1);
666 714
667 /* Find the .sbss section, if any. */ 715 /* Find the old .bss section. Figure out parameters of the new
716 * data2 and bss sections.
717 */
718
719 old_bss_index = find_section (".bss", old_section_names,
720 old_name, old_file_h, old_section_h, 0);
668 721
669 old_sbss_index = find_section (".sbss", old_section_names, 722 old_sbss_index = find_section (".sbss", old_section_names,
670 old_name, old_file_h, old_section_h, 1); 723 old_name, old_file_h, old_section_h, 1);
671 724 if (old_sbss_index != -1)
672 if (old_sbss_index != -1 && (OLD_SECTION_H (old_sbss_index).sh_type == SHT_PROGBITS)) 725 if (OLD_SECTION_H (old_sbss_index).sh_type == SHT_PROGBITS)
673 old_sbss_index = -1; 726 old_sbss_index = -1;
674 727
675 /* Find the old .bss section. */ 728 if (old_sbss_index == -1)
676 729 {
677 old_bss_index = find_section (".bss", old_section_names, 730 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
678 old_name, old_file_h, old_section_h, 0); 731 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
732 new_data2_index = old_bss_index;
733 }
734 else
735 {
736 old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr;
737 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size
738 + OLD_SECTION_H (old_sbss_index).sh_size;
739 new_data2_index = old_sbss_index;
740 }
679 741
680 /* Find the old .data section. Figure out parameters of 742 /* Find the old .data section. Figure out parameters of
681 the new data2 and bss sections. */ 743 the new data2 and bss sections. */
682 744
683 old_data_index = find_section (".data", old_section_names, 745 old_data_index = find_section (".data", old_section_names,
684 old_name, old_file_h, old_section_h, 0); 746 old_name, old_file_h, old_section_h, 0);
685 747
686 old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; 748 #if defined (emacs) || !defined (DEBUG)
687 old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; 749 new_bss_addr = (ElfW(Addr)) sbrk (0);
688 old_base_addr = old_sbss_index == -1 ? old_bss_addr : OLD_SECTION_H (old_sbss_index).sh_addr;
689 #if defined(emacs) || !defined(DEBUG)
690 bss_end = (uintptr_t) sbrk (0);
691 new_bss_addr = (l_Elf_Addr) bss_end;
692 #else 750 #else
693 new_bss_addr = old_bss_addr + old_bss_size + 0x1234; 751 new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
694 #endif 752 #endif
695 new_data2_addr = old_bss_addr; 753 new_data2_addr = old_bss_addr;
696 new_data2_size = new_bss_addr - old_bss_addr; 754 new_data2_size = new_bss_addr - old_bss_addr;
697 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset + 755 new_data2_offset = OLD_SECTION_H (old_data_index).sh_offset +
698 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr); 756 (new_data2_addr - OLD_SECTION_H (old_data_index).sh_addr);
699 new_base_offset = OLD_SECTION_H (old_data_index).sh_offset +
700 (old_base_addr - OLD_SECTION_H (old_data_index).sh_addr);
701 new_offsets_shift = new_bss_addr - (old_base_addr & ~0xfff) +
702 ((old_base_addr & 0xfff) ? 0x1000 : 0);
703 757
704 #ifdef DEBUG 758 #ifdef DEBUG
705 fprintf (stderr, "old_bss_index %d\n", old_bss_index); 759 fprintf (stderr, "old_bss_index %d\n", old_bss_index);
706 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr); 760 fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
707 fprintf (stderr, "old_bss_size %x\n", old_bss_size); 761 fprintf (stderr, "old_bss_size %x\n", old_bss_size);
708 fprintf (stderr, "old_base_addr %x\n", old_base_addr);
709 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr); 762 fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
710 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr); 763 fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
711 fprintf (stderr, "new_data2_size %x\n", new_data2_size); 764 fprintf (stderr, "new_data2_size %x\n", new_data2_size);
712 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset); 765 fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
713 fprintf (stderr, "new_offsets_shift %x\n", new_offsets_shift);
714 #endif 766 #endif
715 767
716 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size) 768 if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
717 fatal (".bss shrank when undumping???\n"); 769 fatal (".bss shrank when undumping???\n", 0, 0);
718 770
719 /* Set the output file to the right size and mmap it. Set 771 /* Set the output file to the right size and mmap it. Set
720 pointers to various interesting objects. stat_buf still has 772 * pointers to various interesting objects. stat_buf still has
721 old_file data. */ 773 * old_file data.
774 */
722 775
723 new_file = open (new_name, O_RDWR | O_CREAT, 0666); 776 new_file = open (new_name, O_RDWR | O_CREAT, 0666);
724 if (new_file < 0) 777 if (new_file < 0)
725 fatal ("Can't creat (%s): errno %d\n", new_name, errno); 778 fatal ("Can't creat (%s): errno %d\n", new_name, errno);
726 779
727 new_file_size = stat_buf.st_size /* old file size */ 780 new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
728 + old_file_h->e_shentsize /* one new section header */
729 + new_offsets_shift; /* trailing section shift */
730 781
731 if (ftruncate (new_file, new_file_size)) 782 if (ftruncate (new_file, new_file_size))
732 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno); 783 fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
733 784
734 new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, 785 #ifdef UNEXEC_USE_MAP_PRIVATE
735 new_file, 0); 786 new_base = (caddr_t) mmap ((caddr_t) 0, new_file_size,
787 PROT_READ | PROT_WRITE,
788 MAP_PRIVATE, new_file, 0);
789 #else
790 new_base = (caddr_t) mmap ((caddr_t) 0, new_file_size,
791 PROT_READ | PROT_WRITE,
792 MAP_SHARED, new_file, 0);
793 #endif
736 794
737 if (new_base == (caddr_t) -1) 795 if (new_base == (caddr_t) -1)
738 fatal ("Can't mmap (%s): errno %d\n", new_name, errno); 796 fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
739 797
740 new_file_h = (l_Elf_Ehdr *) new_base; 798 new_file_h = (ElfW(Ehdr) *) new_base;
741 new_program_h = (l_Elf_Phdr *) ((byte *) new_base + old_file_h->e_phoff); 799 new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
742 new_section_h 800 new_section_h = (ElfW(Shdr) *)
743 = (l_Elf_Shdr *) ((byte *) new_base + old_file_h->e_shoff 801 ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
744 + new_offsets_shift);
745 802
746 /* Make our new file, program and section headers as copies of the 803 /* Make our new file, program and section headers as copies of the
747 originals. */ 804 * originals.
805 */
748 806
749 memcpy (new_file_h, old_file_h, old_file_h->e_ehsize); 807 memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
750 memcpy (new_program_h, old_program_h, 808 memcpy (new_program_h, old_program_h,
751 old_file_h->e_phnum * old_file_h->e_phentsize); 809 old_file_h->e_phnum * old_file_h->e_phentsize);
752 810
753 /* Modify the e_shstrndx if necessary. */ 811 /* Modify the e_shstrndx if necessary. */
754 PATCH_INDEX (new_file_h->e_shstrndx); 812 PATCH_INDEX (new_file_h->e_shstrndx);
755 813
756 /* Fix up file header. We'll add one section. Section header is 814 /* Fix up file header. We'll add one section. Section header is
757 further away now. */ 815 * further away now.
758 816 */
759 new_file_h->e_shoff += new_offsets_shift; 817
818 new_file_h->e_shoff += new_data2_size;
760 new_file_h->e_shnum += 1; 819 new_file_h->e_shnum += 1;
761
762 820
763 #ifdef DEBUG 821 #ifdef DEBUG
764 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff); 822 fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
765 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum); 823 fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
766 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff); 824 fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
767 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); 825 fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
768 #endif 826 #endif
769 827
770 /* Fix up a new program header. Extend the writable data segment so 828 /* Fix up a new program header. Extend the writable data segment so
771 that the bss area is covered too. Find that segment by looking 829 * that the bss area is covered too. Find that segment by looking
772 for one that starts before and ends after the .bss and it PT_LOADable. 830 * for a segment that ends just before the .bss area. Make sure
773 Put a loop at the end to adjust the offset and address of any segment 831 * that no segments are above the new .data2. Put a loop at the end
774 that is above data2, just in case we decide to allow this later. */ 832 * to adjust the offset and address of any segment that is above
775 833 * data2, just in case we decide to allow this later.
776 oldbss = &OLD_SECTION_H(old_bss_index); 834 */
835
777 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 836 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
778 { 837 {
779 /* Compute maximum of all requirements for alignment of section. */ 838 /* Compute maximum of all requirements for alignment of section. */
780 l_Elf_Phdr * ph = (l_Elf_Phdr *)((byte *) new_program_h + 839 ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align;
781 new_file_h->e_phentsize*(n)); 840 if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
782 #ifdef DEBUG 841 alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
783 printf ("%d @ %0x + %0x against %0x + %0x", 842
784 n, ph->p_vaddr, ph->p_memsz, 843 #ifdef __sgi
785 oldbss->sh_addr, oldbss->sh_size); 844 /* According to r02kar@x4u2.desy.de (Karsten Kuenne)
786 #endif 845 and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we
787 if ((ph->p_type == PT_LOAD) && 846 always get "Program segment above .bss" when dumping
788 (ph->p_vaddr <= oldbss->sh_addr) && 847 when the executable doesn't have an sbss section. */
789 ((ph->p_vaddr + ph->p_memsz)>=(oldbss->sh_addr + oldbss->sh_size))) { 848 if (old_sbss_index != -1)
790 ph->p_filesz += new_offsets_shift; 849 #endif /* __sgi */
791 ph->p_memsz = ph->p_filesz; 850 if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
792 #ifdef DEBUG 851 > (old_sbss_index == -1
793 puts (" That's the one!"); 852 ? old_bss_addr
794 fflush (stdout); 853 : round_up (old_bss_addr, alignment)))
795 #endif 854 fatal ("Program segment above .bss in %s\n", old_name, 0);
796 break; 855
797 } 856 if (NEW_PROGRAM_H (n).p_type == PT_LOAD
798 #ifdef DEBUG 857 && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
799 putchar ('\n'); 858 + (NEW_PROGRAM_H (n)).p_filesz,
800 fflush (stdout); 859 alignment)
801 #endif 860 == round_up (old_bss_addr, alignment)))
861 break;
802 } 862 }
803 if (n < 0) 863 if (n < 0)
804 fatal ("Couldn't find segment next to %s in %s\n", 864 fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
805 old_sbss_index == -1 ? ".sbss" : ".bss", old_name); 865
806 866 /* Make sure that the size includes any padding before the old .bss
807 867 section. */
808 #if 1 /* Maybe allow section after data2 - does this ever happen? */ 868 NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr;
869 NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
870
871 #if 0 /* Maybe allow section after data2 - does this ever happen? */
809 for (n = new_file_h->e_phnum - 1; n >= 0; n--) 872 for (n = new_file_h->e_phnum - 1; n >= 0; n--)
810 { 873 {
811 if (NEW_PROGRAM_H (n).p_vaddr 874 if (NEW_PROGRAM_H (n).p_vaddr
812 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr) 875 && NEW_PROGRAM_H (n).p_vaddr >= new_data2_addr)
813 NEW_PROGRAM_H (n).p_vaddr += new_offsets_shift - old_bss_size; 876 NEW_PROGRAM_H (n).p_vaddr += new_data2_size - old_bss_size;
814 877
815 if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset) 878 if (NEW_PROGRAM_H (n).p_offset >= new_data2_offset)
816 NEW_PROGRAM_H (n).p_offset += new_offsets_shift; 879 NEW_PROGRAM_H (n).p_offset += new_data2_size;
817 } 880 }
818 #endif 881 #endif
819 882
820 /* Fix up section headers based on new .data2 section. Any section 883 /* Fix up section headers based on new .data2 section. Any section
821 whose offset or virtual address is after the new .data2 section 884 * whose offset or virtual address is after the new .data2 section
822 gets its value adjusted. .bss size becomes zero and new address 885 * gets its value adjusted. .bss size becomes zero and new address
823 is set. data2 section header gets added by copying the existing 886 * is set. data2 section header gets added by copying the existing
824 .data header and modifying the offset, address and size. */ 887 * .data header and modifying the offset, address and size.
825 for (old_data_index = 1; old_data_index < old_file_h->e_shnum; 888 */
889 for (old_data_index = 1; old_data_index < (int) old_file_h->e_shnum;
826 old_data_index++) 890 old_data_index++)
827 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name, 891 if (!strcmp (old_section_names + OLD_SECTION_H (old_data_index).sh_name,
828 ".data")) 892 ".data"))
829 break; 893 break;
830 if (old_data_index == old_file_h->e_shnum) 894 if (old_data_index == old_file_h->e_shnum)
831 fatal ("Can't find .data in %s.\n", old_name); 895 fatal ("Can't find .data in %s.\n", old_name, 0);
832 896
833 /* Walk through all section headers, insert the new data2 section right 897 /* Walk through all section headers, insert the new data2 section right
834 before the new bss section. */ 898 before the new bss section. */
835 for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++) 899 for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++)
836 { 900 {
837 caddr_t src; 901 caddr_t src;
838 902 /* If it is (s)bss section, insert the new data2 section before it. */
839 /* XEmacs change: */ 903 /* new_data2_index is the index of either old_sbss or old_bss, that was
840 if (n < old_bss_index) 904 chosen as a section for new_data2. */
905 if (n == new_data2_index)
841 { 906 {
842 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), 907 /* Steal the data section header for this data2 section. */
843 old_file_h->e_shentsize);
844
845 }
846 else if (n == old_bss_index)
847 {
848
849 /* If it is bss section, insert the new data2 section before it. */
850 /* Steal the data section header for this data2 section. */
851 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index), 908 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
852 new_file_h->e_shentsize); 909 new_file_h->e_shentsize);
853 910
854 NEW_SECTION_H (nn).sh_addr = new_data2_addr; 911 NEW_SECTION_H (nn).sh_addr = new_data2_addr;
855 NEW_SECTION_H (nn).sh_offset = new_data2_offset; 912 NEW_SECTION_H (nn).sh_offset = new_data2_offset;
856 NEW_SECTION_H (nn).sh_size = new_data2_size; 913 NEW_SECTION_H (nn).sh_size = new_data2_size;
857 /* Use the bss section's alignment. This will assure that the 914 /* Use the bss section's alignment. This will assure that the
858 new data2 section always be placed in the same spot as the old 915 new data2 section always be placed in the same spot as the old
859 bss section by any other application. */ 916 bss section by any other application. */
860 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign; 917 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
861 918
862 /* Now copy over what we have in the memory now. */ 919 /* Now copy over what we have in the memory now. */
863 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, 920 memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
864 (caddr_t) OLD_SECTION_H (n).sh_addr, 921 (caddr_t) OLD_SECTION_H (n).sh_addr,
865 new_data2_size); 922 new_data2_size);
866 nn++; 923 nn++;
867 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), 924 }
868 old_file_h->e_shentsize); 925
869 926 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
870 /* The new bss section's size is zero, and its file offset and virtual 927 old_file_h->e_shentsize);
871 address should be off by NEW_OFFSETS_SHIFT. */ 928
872 NEW_SECTION_H (nn).sh_offset += new_offsets_shift; 929 if (n == old_bss_index
873 NEW_SECTION_H (nn).sh_addr = new_bss_addr; 930 /* The new bss and sbss section's size is zero, and its file offset
931 and virtual address should be off by NEW_DATA2_SIZE. */
932 || n == old_sbss_index
933 )
934 {
935 /* NN should be `old_s?bss_index + 1' at this point. */
936 NEW_SECTION_H (nn).sh_offset =
937 NEW_SECTION_H (new_data2_index).sh_offset + new_data2_size;
938 NEW_SECTION_H (nn).sh_addr =
939 NEW_SECTION_H (new_data2_index).sh_addr + new_data2_size;
874 /* Let the new bss section address alignment be the same as the 940 /* Let the new bss section address alignment be the same as the
875 section address alignment followed the old bss section, so 941 section address alignment followed the old bss section, so
876 this section will be placed in exactly the same place. */ 942 this section will be placed in exactly the same place. */
877 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign; 943 NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
878 NEW_SECTION_H (nn).sh_size = 0; 944 NEW_SECTION_H (nn).sh_size = 0;
879 } 945 }
880 else /* n > old_bss_index */ 946 else
881 memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n), 947 {
882 old_file_h->e_shentsize); 948 /* Any section that was original placed AFTER the bss
883 949 section should now be off by NEW_DATA2_SIZE. */
884 /* Any section that was original placed AFTER the bss 950 #ifdef SOLARIS_POWERPC
885 section must now be adjusted by NEW_OFFSETS_SHIFT. */ 951 /* On PPC Reference Platform running Solaris 2.5.1
886 952 the plt section is also of type NOBI like the bss section.
887 if (NEW_SECTION_H (nn).sh_offset >= new_base_offset) 953 (not really stored) and therefore sections after the bss
888 NEW_SECTION_H (nn).sh_offset += new_offsets_shift; 954 section start at the plt offset. The plt section is always
889 955 the one just before the bss section.
956 It would be better to put the new data section before
957 the .plt section, or use libelf instead.
958 Erik Deumens, deumens@qtp.ufl.edu. */
959 if (NEW_SECTION_H (nn).sh_offset
960 >= OLD_SECTION_H (old_bss_index-1).sh_offset)
961 NEW_SECTION_H (nn).sh_offset += new_data2_size;
962 #else
963 if (round_up (NEW_SECTION_H (nn).sh_offset,
964 OLD_SECTION_H (old_bss_index).sh_addralign)
965 >= new_data2_offset)
966 NEW_SECTION_H (nn).sh_offset += new_data2_size;
967 #endif
968 /* Any section that was originally placed after the section
969 header table should now be off by the size of one section
970 header table entry. */
971 if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff)
972 NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize;
973 }
974
890 /* If any section hdr refers to the section after the new .data 975 /* If any section hdr refers to the section after the new .data
891 section, make it refer to next one because we have inserted 976 section, make it refer to next one because we have inserted
892 a new section in between. */ 977 a new section in between. */
893 978
894 PATCH_INDEX (NEW_SECTION_H (nn).sh_link); 979 PATCH_INDEX (NEW_SECTION_H (nn).sh_link);
895 /* For symbol tables, info is a symbol table index, 980 /* For symbol tables, info is a symbol table index,
896 so don't change it. */ 981 so don't change it. */
897 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB 982 if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
898 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM) 983 && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
899 PATCH_INDEX (NEW_SECTION_H (nn).sh_info); 984 PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
900 985
901 /* Fix the type and alignment for the .sbss section */ 986 if (old_sbss_index != -1)
902 if ((old_sbss_index != -1) && !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss")) 987 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss"))
903 { 988 {
904 NEW_SECTION_H (nn).sh_type = SHT_PROGBITS; 989 NEW_SECTION_H (nn).sh_offset =
905 NEW_SECTION_H (nn).sh_offset = round_up (NEW_SECTION_H (nn).sh_offset, 990 round_up (NEW_SECTION_H (nn).sh_offset,
906 NEW_SECTION_H (nn).sh_addralign); 991 NEW_SECTION_H (nn).sh_addralign);
907 } 992 NEW_SECTION_H (nn).sh_type = SHT_PROGBITS;
908 993 }
909 /* Now, start to copy the content of sections. */ 994
995 /* Now, start to copy the content of sections. */
910 if (NEW_SECTION_H (nn).sh_type == SHT_NULL 996 if (NEW_SECTION_H (nn).sh_type == SHT_NULL
911 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS) 997 || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
912 continue; 998 continue;
913 999
914 /* Write out the sections. .data, .data1 and .sbss (and data2, called 1000 /* Write out the sections. .data and .data1 (and data2, called
915 ".data" in the strings table) get copied from the current process 1001 ".data" in the strings table) get copied from the current process
916 instead of the old file. */ 1002 instead of the old file. */
917 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") 1003 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
918 || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data1") 1004 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
919 || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".got") 1005 ".sdata")
920 || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss")) 1006 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
1007 ".lit4")
1008 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
1009 ".lit8")
1010 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
1011 ".sdata1")
1012 || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
1013 ".data1")
1014 || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name,
1015 ".sbss"))
921 src = (caddr_t) OLD_SECTION_H (n).sh_addr; 1016 src = (caddr_t) OLD_SECTION_H (n).sh_addr;
922 else 1017 else
923 src = old_base + OLD_SECTION_H (n).sh_offset; 1018 src = old_base + OLD_SECTION_H (n).sh_offset;
924 1019
925 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, 1020 memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
926 NEW_SECTION_H (nn).sh_size); 1021 NEW_SECTION_H (nn).sh_size);
927 1022
928 /* Adjust the HDRR offsets in .mdebug and copy the 1023 #ifdef __alpha__
1024 /* Update Alpha COFF symbol table: */
1025 if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
1026 == 0)
1027 {
1028 pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
1029
1030 symhdr->cbLineOffset += new_data2_size;
1031 symhdr->cbDnOffset += new_data2_size;
1032 symhdr->cbPdOffset += new_data2_size;
1033 symhdr->cbSymOffset += new_data2_size;
1034 symhdr->cbOptOffset += new_data2_size;
1035 symhdr->cbAuxOffset += new_data2_size;
1036 symhdr->cbSsOffset += new_data2_size;
1037 symhdr->cbSsExtOffset += new_data2_size;
1038 symhdr->cbFdOffset += new_data2_size;
1039 symhdr->cbRfdOffset += new_data2_size;
1040 symhdr->cbExtOffset += new_data2_size;
1041 }
1042 #endif /* __alpha__ */
1043
1044 #if defined (__sony_news) && defined (_SYSTYPE_SYSV)
1045 if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
1046 && old_mdebug_index != -1)
1047 {
1048 int diff = NEW_SECTION_H(nn).sh_offset
1049 - OLD_SECTION_H(old_mdebug_index).sh_offset;
1050 HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
1051
1052 if (diff)
1053 {
1054 phdr->cbLineOffset += diff;
1055 phdr->cbDnOffset += diff;
1056 phdr->cbPdOffset += diff;
1057 phdr->cbSymOffset += diff;
1058 phdr->cbOptOffset += diff;
1059 phdr->cbAuxOffset += diff;
1060 phdr->cbSsOffset += diff;
1061 phdr->cbSsExtOffset += diff;
1062 phdr->cbFdOffset += diff;
1063 phdr->cbRfdOffset += diff;
1064 phdr->cbExtOffset += diff;
1065 }
1066 }
1067 #endif /* __sony_news && _SYSTYPE_SYSV */
1068
1069 #if __sgi
1070 /* Adjust the HDRR offsets in .mdebug and copy the
929 line data if it's in its usual 'hole' in the object. 1071 line data if it's in its usual 'hole' in the object.
930 Makes the new file debuggable with dbx. 1072 Makes the new file debuggable with dbx.
931 patches up two problems: the absolute file offsets 1073 patches up two problems: the absolute file offsets
932 in the HDRR record of .mdebug (see /usr/include/syms.h), and 1074 in the HDRR record of .mdebug (see /usr/include/syms.h), and
933 the ld bug that gets the line table in a hole in the 1075 the ld bug that gets the line table in a hole in the
941 n_phdrr->__fileaddr += movement; \ 1083 n_phdrr->__fileaddr += movement; \
942 } 1084 }
943 1085
944 HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset); 1086 HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
945 HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset); 1087 HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
946 unsigned movement = new_offsets_shift; 1088 unsigned movement = new_data2_size;
947 1089
948 MDEBUGADJUST (idnMax, cbDnOffset); 1090 MDEBUGADJUST (idnMax, cbDnOffset);
949 MDEBUGADJUST (ipdMax, cbPdOffset); 1091 MDEBUGADJUST (ipdMax, cbPdOffset);
950 MDEBUGADJUST (isymMax, cbSymOffset); 1092 MDEBUGADJUST (isymMax, cbSymOffset);
951 MDEBUGADJUST (ioptMax, cbOptOffset); 1093 MDEBUGADJUST (ioptMax, cbOptOffset);
975 /* somehow line data is in .mdebug as it is supposed to be. */ 1117 /* somehow line data is in .mdebug as it is supposed to be. */
976 MDEBUGADJUST (cbLine, cbLineOffset); 1118 MDEBUGADJUST (cbLine, cbLineOffset);
977 } 1119 }
978 } 1120 }
979 } 1121 }
980 1122 #endif /* __sgi */
981 /* If it is the symbol table, its st_shndx field needs to be patched. */ 1123
1124 /* If it is the symbol table, its st_shndx field needs to be patched. */
982 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB 1125 if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
983 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) 1126 || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
984 { 1127 {
985 l_Elf_Shdr *spt = &NEW_SECTION_H (nn); 1128 ElfW(Shdr) *spt = &NEW_SECTION_H (nn);
986 unsigned int num = spt->sh_size / spt->sh_entsize; 1129 unsigned int num = spt->sh_size / spt->sh_entsize;
987 l_Elf_Sym * sym = (l_Elf_Sym *) (NEW_SECTION_H (nn).sh_offset 1130 ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset +
988 + new_base); 1131 new_base);
989 for (; num--; sym++) 1132 for (; num--; sym++)
990 { 1133 {
991 if (sym->st_shndx == SHN_UNDEF 1134 if ((sym->st_shndx == SHN_UNDEF)
992 || sym->st_shndx == SHN_ABS 1135 || (sym->st_shndx == SHN_ABS)
993 || sym->st_shndx == SHN_COMMON) 1136 || (sym->st_shndx == SHN_COMMON))
994 continue; 1137 continue;
995 1138
996 PATCH_INDEX (sym->st_shndx); 1139 PATCH_INDEX (sym->st_shndx);
997 } 1140 }
998 } 1141 }
999 } 1142 }
1143
1144 /* Update the symbol values of _edata and _end. */
1145 for (n = new_file_h->e_shnum - 1; n; n--)
1146 {
1147 byte *symnames;
1148 ElfW(Sym) *symp, *symendp;
1149
1150 if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
1151 && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
1152 continue;
1153
1154 symnames = ((byte *) new_base
1155 + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
1156 symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
1157 symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
1158
1159 for (; symp < symendp; symp ++)
1160 if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
1161 || strcmp ((char *) (symnames + symp->st_name), "end") == 0
1162 || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0
1163 || strcmp ((char *) (symnames + symp->st_name), "edata") == 0)
1164 memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
1165 }
1166
1167 /* This loop seeks out relocation sections for the data section, so
1168 that it can undo relocations performed by the runtime linker. */
1169 for (n = new_file_h->e_shnum - 1; n; n--)
1170 {
1171 ElfW(Shdr) section = NEW_SECTION_H (n);
1172 switch (section.sh_type) {
1173 default:
1174 break;
1175 case SHT_REL:
1176 case SHT_RELA:
1177 /* This code handles two different size structs, but there should
1178 be no harm in that provided that r_offset is always the first
1179 member. */
1180 nn = section.sh_info;
1181 if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
1182 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1183 ".sdata")
1184 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1185 ".lit4")
1186 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1187 ".lit8")
1188 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1189 ".sdata1")
1190 || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
1191 ".data1"))
1192 {
1193 ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr -
1194 NEW_SECTION_H (nn).sh_offset;
1195 caddr_t reloc = old_base + section.sh_offset, end;
1196 for (end = reloc + section.sh_size; reloc < end;
1197 reloc += section.sh_entsize)
1198 {
1199 ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
1200 #ifdef __alpha__
1201 /* The Alpha ELF binutils currently have a bug that
1202 sometimes results in relocs that contain all
1203 zeroes. Work around this for now... */
1204 if (((ElfW(Rel) *) reloc)->r_offset == 0)
1205 continue;
1206 #endif
1207 memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
1208 }
1209 }
1210 break;
1211 }
1212 }
1213
1214 #ifdef UNEXEC_USE_MAP_PRIVATE
1215 if (lseek (new_file, 0, SEEK_SET) == -1)
1216 fatal ("Can't rewind (%s): errno %d\n", new_name, errno);
1217
1218 if (write (new_file, new_base, new_file_size) != new_file_size)
1219 fatal ("Can't write (%s): errno %d\n", new_name, errno);
1220 #endif
1000 1221
1001 /* Close the files and make the new file executable. */ 1222 /* Close the files and make the new file executable. */
1002 1223
1003 if (close (old_file)) 1224 if (close (old_file))
1004 fatal ("Can't close (%s): errno %d\n", old_name, errno); 1225 fatal ("Can't close (%s): errno %d\n", old_name, errno);
1012 n = umask (777); 1233 n = umask (777);
1013 umask (n); 1234 umask (n);
1014 stat_buf.st_mode |= 0111 & ~n; 1235 stat_buf.st_mode |= 0111 & ~n;
1015 if (chmod (new_name, stat_buf.st_mode) == -1) 1236 if (chmod (new_name, stat_buf.st_mode) == -1)
1016 fatal ("Can't chmod (%s): errno %d\n", new_name, errno); 1237 fatal ("Can't chmod (%s): errno %d\n", new_name, errno);
1017
1018 return 0;
1019 } 1238 }