author | Rod Evans <Rod.Evans@Sun.COM> |
Wed, 19 May 2010 22:33:49 -0700 | |
changeset 12449 | a87750d92895 |
parent 11827 | d7ef53deac3f |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
5 |
* Common Development and Distribution License (the "License"). |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
6 |
* You may not use this file except in compliance with the License. |
0 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
21 |
|
0 | 22 |
/* |
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
23 |
* Copyright (c) 1988 AT&T |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
24 |
* All Rights Reserved |
12449
a87750d92895
6943772 Testing for a symbols existence with RTLD_PROBE is compromised by RTLD_BIND_NOW
Rod Evans <Rod.Evans@Sun.COM>
parents:
11827
diff
changeset
|
25 |
* |
a87750d92895
6943772 Testing for a symbols existence with RTLD_PROBE is compromised by RTLD_BIND_NOW
Rod Evans <Rod.Evans@Sun.COM>
parents:
11827
diff
changeset
|
26 |
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 27 |
*/ |
28 |
||
29 |
/* |
|
30 |
* SPARC machine dependent and a.out format file class dependent functions. |
|
31 |
* Contains routines for performing function binding and symbol relocations. |
|
32 |
*/ |
|
33 |
||
34 |
#include <stdio.h> |
|
35 |
#include <sys/types.h> |
|
36 |
#include <sys/mman.h> |
|
37 |
#include <synch.h> |
|
38 |
#include <dlfcn.h> |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
39 |
#include <debug.h> |
0 | 40 |
#include "_a.out.h" |
41 |
#include "_rtld.h" |
|
42 |
#include "_audit.h" |
|
12449
a87750d92895
6943772 Testing for a symbols existence with RTLD_PROBE is compromised by RTLD_BIND_NOW
Rod Evans <Rod.Evans@Sun.COM>
parents:
11827
diff
changeset
|
43 |
#include "_inline_gen.h" |
0 | 44 |
#include "msg.h" |
45 |
||
46 |
extern void iflush_range(caddr_t, size_t); |
|
47 |
||
48 |
/* |
|
49 |
* Function binding routine - invoked on the first call to a function through |
|
50 |
* the procedure linkage table; |
|
51 |
* passes first through an assembly language interface. |
|
52 |
* |
|
53 |
* Takes the address of the PLT entry where the call originated, |
|
54 |
* the offset into the relocation table of the associated |
|
55 |
* relocation entry and the address of the link map (rt_private_map struct) |
|
56 |
* for the entry. |
|
57 |
* |
|
58 |
* Returns the address of the function referenced after re-writing the PLT |
|
59 |
* entry to invoke the function directly. |
|
60 |
* |
|
61 |
* On error, causes process to terminate with a signal. |
|
62 |
*/ |
|
63 |
ulong_t |
|
64 |
aout_bndr(caddr_t pc) |
|
65 |
{ |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
66 |
Rt_map *lmp, *nlmp, *llmp; |
0 | 67 |
struct relocation_info *rp; |
68 |
struct nlist *sp; |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
69 |
Sym *sym; |
0 | 70 |
char *name; |
71 |
int rndx, entry; |
|
72 |
ulong_t symval; |
|
73 |
Slookup sl; |
|
11827 | 74 |
Sresult sr; |
0 | 75 |
uint_t binfo; |
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
76 |
Lm_list *lml; |
0 | 77 |
|
78 |
/* |
|
79 |
* For compatibility with libthread (TI_VERSION 1) we track the entry |
|
80 |
* value. A zero value indicates we have recursed into ld.so.1 to |
|
81 |
* further process a locking request (see comments in completion()). |
|
82 |
* Under this recursion we disable tsort and cleanup activities. |
|
83 |
*/ |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
6387
diff
changeset
|
84 |
entry = enter(0); |
0 | 85 |
|
8394
cfddc4c3786c
6782597 32-bit ld.so.1 needs to accept objects with large inode number
Ali Bahrami <Ali.Bahrami@Sun.COM>
parents:
6812
diff
changeset
|
86 |
for (lmp = lml_main.lm_head; lmp; lmp = NEXT_RT_MAP(lmp)) { |
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
87 |
if (THIS_IS_AOUT(lmp)) { |
0 | 88 |
if (pc > (caddr_t)(LM2LP(lmp)->lp_plt) && |
89 |
pc < (caddr_t)((int)LM2LP(lmp)->lp_plt + |
|
90 |
AOUTDYN(lmp)->v2->ld_plt_sz)) { |
|
91 |
break; |
|
92 |
} |
|
93 |
} |
|
94 |
} |
|
95 |
||
96 |
#define LAST22BITS 0x3fffff |
|
97 |
||
98 |
/* LINTED */ |
|
99 |
rndx = *(int *)(pc + (sizeof (ulong_t *) * 2)) & LAST22BITS; |
|
100 |
rp = &LM2LP(lmp)->lp_rp[rndx]; |
|
101 |
sp = &LM2LP(lmp)->lp_symtab[rp->r_symbolnum]; |
|
102 |
name = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx]; |
|
103 |
||
104 |
/* |
|
105 |
* Determine the last link-map of this list, this'll be the starting |
|
106 |
* point for any tsort() processing. |
|
107 |
*/ |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
108 |
lml = LIST(lmp); |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
109 |
llmp = lml->lm_tail; |
0 | 110 |
|
111 |
/* |
|
5950 | 112 |
* Find definition for symbol. Initialize the symbol lookup data |
113 |
* structure. |
|
0 | 114 |
*/ |
5950 | 115 |
SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0, 0, 0, 0, |
116 |
LKUP_DEFT); |
|
11827 | 117 |
SRESULT_INIT(sr, name); |
0 | 118 |
|
11827 | 119 |
if (aout_lookup_sym(&sl, &sr, &binfo, NULL) == 0) { |
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
120 |
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp), |
0 | 121 |
demangle(name)); |
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
122 |
rtldexit(lml, 1); |
0 | 123 |
} |
124 |
||
11827 | 125 |
name = (char *)sr.sr_name; |
126 |
nlmp = sr.sr_dmap; |
|
127 |
sym = sr.sr_sym; |
|
128 |
||
0 | 129 |
symval = sym->st_value; |
11827 | 130 |
|
0 | 131 |
if (!(FLAGS(nlmp) & FLG_RT_FIXED) && |
132 |
(sym->st_shndx != SHN_ABS)) |
|
133 |
symval += (int)(ADDR(nlmp)); |
|
134 |
if ((lmp != nlmp) && ((FLAGS1(nlmp) & FL1_RT_NOINIFIN) == 0)) { |
|
135 |
/* |
|
136 |
* Record that this new link map is now bound to the caller. |
|
137 |
*/ |
|
138 |
if (bind_one(lmp, nlmp, BND_REFER) == 0) |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
139 |
rtldexit(lml, 1); |
0 | 140 |
} |
141 |
||
142 |
/* |
|
143 |
* Print binding information and rebuild PLT entry. |
|
144 |
*/ |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
145 |
DBG_CALL(Dbg_bind_global(lmp, (Addr)(ADDR(lmp) + rp->r_address), |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
146 |
(Off)rp->r_address, (Xword)(-1), PLT_T_NONE, nlmp, |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
147 |
(Addr)symval, sym->st_value, name, binfo)); |
0 | 148 |
|
149 |
if (!(rtld_flags & RT_FL_NOBIND)) |
|
150 |
aout_plt_write((caddr_t)(ADDR(lmp) + rp->r_address), symval); |
|
151 |
||
152 |
/* |
|
153 |
* Complete any processing for newly loaded objects. Note we don't |
|
154 |
* know exactly where any new objects are loaded (we know the object |
|
155 |
* that supplied the symbol, but others may have been loaded lazily as |
|
156 |
* we searched for the symbol), so sorting starts from the last |
|
157 |
* link-map know on entry to this routine. |
|
158 |
*/ |
|
159 |
if (entry) |
|
4679 | 160 |
load_completion(llmp); |
0 | 161 |
|
162 |
/* |
|
163 |
* Make sure the object to which we've bound has had it's .init fired. |
|
164 |
* Cleanup before return to user code. |
|
165 |
*/ |
|
166 |
if (entry) { |
|
167 |
is_dep_init(nlmp, lmp); |
|
6515
10dab2b883e0
6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents:
6387
diff
changeset
|
168 |
leave(lml, 0); |
0 | 169 |
} |
170 |
||
171 |
return (symval); |
|
172 |
} |
|
173 |
||
174 |
||
175 |
#define IS_PC_RELATIVE(X) (pc_rel_type[(X)] == 1) |
|
176 |
||
177 |
static const uchar_t pc_rel_type[] = { |
|
178 |
0, /* RELOC_8 */ |
|
179 |
0, /* RELOC_16 */ |
|
180 |
0, /* RELOC_32 */ |
|
181 |
1, /* RELOC_DISP8 */ |
|
182 |
1, /* RELOC_DISP16 */ |
|
183 |
1, /* RELOC_DISP32 */ |
|
184 |
1, /* RELOC_WDISP30 */ |
|
185 |
1, /* RELOC_WDISP22 */ |
|
186 |
0, /* RELOC_HI22 */ |
|
187 |
0, /* RELOC_22 */ |
|
188 |
0, /* RELOC_13 */ |
|
189 |
0, /* RELOC_LO10 */ |
|
190 |
0, /* RELOC_SFA_BASE */ |
|
191 |
0, /* RELOC_SFA_OFF13 */ |
|
192 |
0, /* RELOC_BASE10 */ |
|
193 |
0, /* RELOC_BASE13 */ |
|
194 |
0, /* RELOC_BASE22 */ |
|
195 |
0, /* RELOC_PC10 */ |
|
196 |
0, /* RELOC_PC22 */ |
|
197 |
0, /* RELOC_JMP_TBL */ |
|
198 |
0, /* RELOC_SEGOFF16 */ |
|
199 |
0, /* RELOC_GLOB_DAT */ |
|
200 |
0, /* RELOC_JMP_SLOT */ |
|
201 |
0 /* RELOC_RELATIVE */ |
|
202 |
}; |
|
203 |
||
204 |
int |
|
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
205 |
aout_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel) |
0 | 206 |
{ |
207 |
int k; /* loop temporary */ |
|
208 |
int nr; /* number of relocations */ |
|
209 |
char *name; /* symbol being searched for */ |
|
210 |
long value; /* relocation temporary */ |
|
211 |
long *ra; /* cached relocation address */ |
|
212 |
struct relocation_info *rp; /* current relocation */ |
|
213 |
struct nlist *sp; /* symbol table of "symbol" */ |
|
214 |
Rt_map * _lmp; /* lm which holds symbol definition */ |
|
215 |
Sym * sym; /* symbol definition */ |
|
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
216 |
int ret = 1; |
5892
b863dde33f1b
6492726 Merge SHF_MERGE|SHF_STRINGS input sections
ab196087
parents:
5220
diff
changeset
|
217 |
APlist *bound = NULL; |
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
218 |
Lm_list *lml = LIST(lmp); |
0 | 219 |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
220 |
DBG_CALL(Dbg_reloc_run(lmp, SHT_RELA, plt, DBG_REL_START)); |
0 | 221 |
|
222 |
/* |
|
223 |
* If we've been called upon to promote an RTLD_LAZY object to an |
|
224 |
* RTLD_NOW don't bother to do anything - a.out's are bound as if |
|
225 |
* RTLD_NOW regardless. |
|
226 |
*/ |
|
227 |
if (plt) |
|
228 |
return (1); |
|
229 |
||
230 |
rp = LM2LP(lmp)->lp_rp; |
|
231 |
nr = GETRELSZ(AOUTDYN(lmp)) / sizeof (struct relocation_info); |
|
232 |
||
233 |
/* |
|
234 |
* Initialize _PLT_, if any. |
|
235 |
*/ |
|
236 |
if (AOUTDYN(lmp)->v2->ld_plt_sz) |
|
237 |
aout_plt_write((caddr_t)LM2LP(lmp)->lp_plt->jb_inst, |
|
238 |
(ulong_t)aout_rtbndr); |
|
239 |
||
240 |
/* |
|
241 |
* Loop through relocations. |
|
242 |
*/ |
|
243 |
for (k = 0; k < nr; k++, rp++) { |
|
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
244 |
mmapobj_result_t *mpp; |
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
245 |
|
0 | 246 |
/* LINTED */ |
247 |
ra = (long *)&((char *)ADDR(lmp))[rp->r_address]; |
|
248 |
||
249 |
/* |
|
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
250 |
* Make sure the segment is writable. |
0 | 251 |
*/ |
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
252 |
if (((mpp = find_segment((caddr_t)ra, lmp)) != NULL) && |
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
253 |
((mpp->mr_prot & PROT_WRITE) == 0)) { |
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
254 |
if ((set_prot(lmp, mpp, 1) == 0) || |
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
255 |
(aplist_append(textrel, mpp, |
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
256 |
AL_CNT_TEXTREL) == NULL)) { |
0 | 257 |
ret = 0; |
258 |
break; |
|
259 |
} |
|
260 |
} |
|
261 |
||
262 |
/* |
|
263 |
* Perform the relocation. |
|
264 |
*/ |
|
265 |
if (rp->r_extern == 0) { |
|
11827 | 266 |
name = NULL; |
0 | 267 |
value = ADDR(lmp); |
268 |
} else { |
|
269 |
Slookup sl; |
|
11827 | 270 |
Sresult sr; |
0 | 271 |
uint_t binfo; |
272 |
||
273 |
if (rp->r_type == RELOC_JMP_SLOT) |
|
274 |
continue; |
|
275 |
sp = &LM2LP(lmp)->lp_symtab[rp->r_symbolnum]; |
|
276 |
name = &LM2LP(lmp)->lp_symstr[sp->n_un.n_strx]; |
|
277 |
||
278 |
/* |
|
5950 | 279 |
* Locate symbol. Initialize the symbol lookup data |
280 |
* structure. |
|
0 | 281 |
*/ |
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
282 |
SLOOKUP_INIT(sl, name, lmp, 0, ld_entry_cnt, |
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
283 |
0, 0, 0, 0, LKUP_STDRELOC); |
11827 | 284 |
SRESULT_INIT(sr, name); |
0 | 285 |
|
11827 | 286 |
if (aout_lookup_sym(&sl, &sr, &binfo, in_nfavl) == 0) { |
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
287 |
if (lml->lm_flags & LML_FLG_TRC_WARN) { |
0 | 288 |
(void) |
289 |
printf(MSG_INTL(MSG_LDD_SYM_NFOUND), |
|
290 |
demangle(name), NAME(lmp)); |
|
291 |
continue; |
|
292 |
} else { |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
293 |
eprintf(lml, ERR_FATAL, |
0 | 294 |
MSG_INTL(MSG_REL_NOSYM), NAME(lmp), |
295 |
demangle(name)); |
|
296 |
ret = 0; |
|
297 |
break; |
|
298 |
} |
|
299 |
} |
|
300 |
||
301 |
/* |
|
302 |
* If symbol was found in an object other than the |
|
303 |
* referencing object then record the binding. |
|
304 |
*/ |
|
11827 | 305 |
name = (char *)sr.sr_name; |
306 |
_lmp = sr.sr_dmap; |
|
307 |
sym = sr.sr_sym; |
|
308 |
||
0 | 309 |
if ((lmp != _lmp) && |
310 |
((FLAGS1(_lmp) & FL1_RT_NOINIFIN) == 0)) { |
|
5892
b863dde33f1b
6492726 Merge SHF_MERGE|SHF_STRINGS input sections
ab196087
parents:
5220
diff
changeset
|
311 |
if (aplist_test(&bound, _lmp, |
0 | 312 |
AL_CNT_RELBIND) == 0) { |
313 |
ret = 0; |
|
314 |
break; |
|
315 |
} |
|
316 |
} |
|
317 |
||
318 |
value = sym->st_value + rp->r_addend; |
|
319 |
if (!(FLAGS(_lmp) & FLG_RT_FIXED) && |
|
320 |
(sym->st_shndx != SHN_COMMON) && |
|
321 |
(sym->st_shndx != SHN_ABS)) |
|
322 |
value += ADDR(_lmp); |
|
323 |
||
324 |
if (IS_PC_RELATIVE(rp->r_type)) |
|
325 |
value -= (long)ADDR(lmp); |
|
326 |
||
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
327 |
DBG_CALL(Dbg_bind_global(lmp, (Addr)ra, |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
328 |
(Off)(ra - ADDR(lmp)), (Xword)(-1), PLT_T_NONE, |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
329 |
_lmp, (Addr)value, sym->st_value, name, binfo)); |
0 | 330 |
} |
331 |
||
332 |
/* |
|
333 |
* Perform a specific relocation operation. |
|
334 |
*/ |
|
335 |
switch (rp->r_type) { |
|
336 |
case RELOC_RELATIVE: |
|
337 |
value += *ra << (32-22); |
|
338 |
*(long *)ra = (*(long *)ra & ~S_MASK(22)) | |
|
4679 | 339 |
((value >> (32 - 22)) & S_MASK(22)); |
0 | 340 |
ra++; |
341 |
value += (*ra & S_MASK(10)); |
|
342 |
*(long *)ra = (*(long *)ra & ~S_MASK(10)) | |
|
4679 | 343 |
(value & S_MASK(10)); |
0 | 344 |
break; |
345 |
case RELOC_8: |
|
346 |
case RELOC_DISP8: |
|
347 |
value += *ra & S_MASK(8); |
|
4679 | 348 |
if (!S_INRANGE(value, 8)) { |
349 |
eprintf(lml, ERR_FATAL, |
|
350 |
MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), |
|
351 |
(name ? demangle(name) : |
|
352 |
MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 8, |
|
353 |
(uint_t)ra); |
|
354 |
} |
|
0 | 355 |
*ra = value; |
356 |
break; |
|
357 |
case RELOC_LO10: |
|
358 |
case RELOC_BASE10: |
|
359 |
value += *ra & S_MASK(10); |
|
360 |
*(long *)ra = (*(long *)ra & ~S_MASK(10)) | |
|
4679 | 361 |
(value & S_MASK(10)); |
0 | 362 |
break; |
363 |
case RELOC_BASE13: |
|
364 |
case RELOC_13: |
|
365 |
value += *ra & S_MASK(13); |
|
366 |
*(long *)ra = (*(long *)ra & ~S_MASK(13)) | |
|
4679 | 367 |
(value & S_MASK(13)); |
0 | 368 |
break; |
369 |
case RELOC_16: |
|
370 |
case RELOC_DISP16: |
|
371 |
value += *ra & S_MASK(16); |
|
4679 | 372 |
if (!S_INRANGE(value, 16)) { |
373 |
eprintf(lml, ERR_FATAL, |
|
374 |
MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), |
|
375 |
(name ? demangle(name) : |
|
376 |
MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 16, |
|
377 |
(uint_t)ra); |
|
378 |
} |
|
0 | 379 |
*(short *)ra = value; |
380 |
break; |
|
381 |
case RELOC_22: |
|
382 |
case RELOC_BASE22: |
|
383 |
value += *ra & S_MASK(22); |
|
4679 | 384 |
if (!S_INRANGE(value, 22)) { |
385 |
eprintf(lml, ERR_FATAL, |
|
386 |
MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), |
|
387 |
(name ? demangle(name) : |
|
388 |
MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 22, |
|
389 |
(uint_t)ra); |
|
390 |
} |
|
0 | 391 |
*(long *)ra = (*(long *)ra & ~S_MASK(22)) | |
4679 | 392 |
(value & S_MASK(22)); |
0 | 393 |
break; |
394 |
case RELOC_HI22: |
|
395 |
value += (*ra & S_MASK(22)) << (32 - 22); |
|
396 |
*(long *)ra = (*(long *)ra & ~S_MASK(22)) | |
|
4679 | 397 |
((value >> (32 - 22)) & S_MASK(22)); |
0 | 398 |
break; |
399 |
case RELOC_WDISP22: |
|
400 |
value += *ra & S_MASK(22); |
|
401 |
value >>= 2; |
|
4679 | 402 |
if (!S_INRANGE(value, 22)) { |
403 |
eprintf(lml, ERR_FATAL, |
|
404 |
MSG_INTL(MSG_REL_OVERFLOW), NAME(lmp), |
|
405 |
(name ? demangle(name) : |
|
406 |
MSG_INTL(MSG_STR_UNKNOWN)), (int)value, 22, |
|
407 |
(uint_t)ra); |
|
408 |
} |
|
0 | 409 |
*(long *)ra = (*(long *)ra & ~S_MASK(22)) | |
4679 | 410 |
(value & S_MASK(22)); |
0 | 411 |
break; |
412 |
case RELOC_WDISP30: |
|
413 |
value += *ra & S_MASK(30); |
|
414 |
value >>= 2; |
|
415 |
*(long *)ra = (*(long *)ra & ~S_MASK(30)) | |
|
4679 | 416 |
(value & S_MASK(30)); |
0 | 417 |
break; |
418 |
case RELOC_32: |
|
419 |
case RELOC_GLOB_DAT: |
|
420 |
case RELOC_DISP32: |
|
421 |
value += *ra; |
|
422 |
*(long *)ra = value; |
|
423 |
break; |
|
424 |
default: |
|
1618
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
425 |
eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_UNIMPL), |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
426 |
NAME(lmp), (name ? demangle(name) : |
8c9a4f31d225
6316708 LD_DEBUG should provide a means of identifying/isolating individual
rie
parents:
0
diff
changeset
|
427 |
MSG_INTL(MSG_STR_UNKNOWN)), rp->r_type); |
0 | 428 |
ret = 0; |
429 |
break; |
|
430 |
} |
|
431 |
||
432 |
/* |
|
433 |
* If this relocation is against a text segment we must make |
|
434 |
* sure that the instruction cache is flushed. |
|
435 |
*/ |
|
436 |
if (textrel) { |
|
437 |
if (rp->r_type == RELOC_RELATIVE) |
|
438 |
iflush_range((caddr_t)(ra - 1), 0x8); |
|
439 |
else |
|
440 |
iflush_range((caddr_t)ra, 0x4); |
|
441 |
} |
|
442 |
} |
|
443 |
||
8598
0867fc633d66
6686372 ld.so.1 should use mmapobj(2)
Rod Evans <Rod.Evans@Sun.COM>
parents:
8394
diff
changeset
|
444 |
return (relocate_finish(lmp, bound, ret)); |
0 | 445 |
} |