annotate src/unexelf.c @ 2227:8e7b4a0c1a81

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