File: | src/libexec/ld.so/amd64/rtld_machine.c |
Warning: | line 244, column 10 Access to field 'st_info' results in a dereference of a null pointer (loaded from variable 'sym') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: rtld_machine.c,v 1.42 2023/01/29 20:30:21 gnezdo Exp $ */ | |||
2 | ||||
3 | /* | |||
4 | * Copyright (c) 2002,2004 Dale Rahn | |||
5 | * Copyright (c) 2001 Niklas Hallqvist | |||
6 | * Copyright (c) 2001 Artur Grabowski | |||
7 | * | |||
8 | * Redistribution and use in source and binary forms, with or without | |||
9 | * modification, are permitted provided that the following conditions | |||
10 | * are met: | |||
11 | * 1. Redistributions of source code must retain the above copyright | |||
12 | * notice, this list of conditions and the following disclaimer. | |||
13 | * 2. Redistributions in binary form must reproduce the above copyright | |||
14 | * notice, this list of conditions and the following disclaimer in the | |||
15 | * documentation and/or other materials provided with the distribution. | |||
16 | * | |||
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | |||
18 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |||
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
27 | * SUCH DAMAGE. | |||
28 | */ | |||
29 | /*- | |||
30 | * Copyright (c) 2000 Eduardo Horvath. | |||
31 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | |||
32 | * All rights reserved. | |||
33 | * | |||
34 | * This code is derived from software contributed to The NetBSD Foundation | |||
35 | * by Paul Kranenburg. | |||
36 | * | |||
37 | * Redistribution and use in source and binary forms, with or without | |||
38 | * modification, are permitted provided that the following conditions | |||
39 | * are met: | |||
40 | * 1. Redistributions of source code must retain the above copyright | |||
41 | * notice, this list of conditions and the following disclaimer. | |||
42 | * 2. Redistributions in binary form must reproduce the above copyright | |||
43 | * notice, this list of conditions and the following disclaimer in the | |||
44 | * documentation and/or other materials provided with the distribution. | |||
45 | * 3. All advertising materials mentioning features or use of this software | |||
46 | * must display the following acknowledgement: | |||
47 | * This product includes software developed by the NetBSD | |||
48 | * Foundation, Inc. and its contributors. | |||
49 | * 4. Neither the name of The NetBSD Foundation nor the names of its | |||
50 | * contributors may be used to endorse or promote products derived | |||
51 | * from this software without specific prior written permission. | |||
52 | * | |||
53 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |||
54 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |||
55 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |||
56 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |||
57 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||
58 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||
59 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
60 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
61 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
62 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
63 | * POSSIBILITY OF SUCH DAMAGE. | |||
64 | */ | |||
65 | ||||
66 | #define _DYN_LOADER | |||
67 | ||||
68 | #include <sys/types.h> | |||
69 | #include <sys/exec_elf.h> | |||
70 | #include <sys/syscall.h> | |||
71 | #include <sys/unistd.h> | |||
72 | ||||
73 | #include <machine/reloc.h> | |||
74 | ||||
75 | #include "util.h" | |||
76 | #include "resolve.h" | |||
77 | ||||
78 | int64_t pcookie __attribute__((section(".openbsd.randomdata"))) __dso_hidden__attribute__((__visibility__("hidden"))); | |||
79 | ||||
80 | /* | |||
81 | * The following table holds for each relocation type: | |||
82 | * - the width in bits of the memory location the relocation | |||
83 | * applies to | |||
84 | * - the number of bits the relocation value must be shifted to the | |||
85 | * right (i.e. discard least significant bits) to fit into | |||
86 | * the appropriate field in the instruction word. | |||
87 | * - flags indicating whether | |||
88 | * * the relocation involves a symbol | |||
89 | * * the relocation is relative to the current position | |||
90 | * * the relocation is for a GOT entry | |||
91 | * * the relocation is relative to the load address | |||
92 | * | |||
93 | */ | |||
94 | #define _RF_S0x80000000 0x80000000 /* Resolve symbol */ | |||
95 | #define _RF_A0x40000000 0x40000000 /* Use addend */ | |||
96 | #define _RF_P0x20000000 0x20000000 /* Location relative */ | |||
97 | #define _RF_G0x10000000 0x10000000 /* GOT offset */ | |||
98 | #define _RF_B0x08000000 0x08000000 /* Load address relative */ | |||
99 | #define _RF_E0x02000000 0x02000000 /* ERROR */ | |||
100 | #define _RF_SZ(s)(((s) & 0xff) << 8) (((s) & 0xff) << 8) /* memory target size */ | |||
101 | #define _RF_RS(s)((s) & 0xff) ((s) & 0xff) /* right shift */ | |||
102 | static const int reloc_target_flags[] = { | |||
103 | 0, /* 0 NONE */ | |||
104 | _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 1 _64*/ | |||
105 | _RF_S0x80000000|_RF_A0x40000000|_RF_P0x20000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 2 PC32 */ | |||
106 | _RF_G0x10000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 3 GOT32 */ | |||
107 | _RF_E0x02000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 4 PLT32 */ | |||
108 | _RF_S0x80000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 5 COPY */ | |||
109 | _RF_S0x80000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 6 GLOB_DAT*/ | |||
110 | _RF_S0x80000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 7 JUMP_SLOT*/ | |||
111 | _RF_A0x40000000| _RF_B0x08000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 8 RELATIVE*/ | |||
112 | _RF_E0x02000000, /* 9 GOTPCREL*/ | |||
113 | _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 10 32 */ | |||
114 | _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 11 32S */ | |||
115 | _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(16)(((16) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 12 16 */ | |||
116 | _RF_S0x80000000|_RF_A0x40000000|_RF_P0x20000000| _RF_SZ(16)(((16) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 13 PC16 */ | |||
117 | _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(8)(((8) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 14 8 */ | |||
118 | _RF_S0x80000000|_RF_A0x40000000|_RF_P0x20000000| _RF_SZ(8)(((8) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 15 PC8 */ | |||
119 | _RF_E0x02000000, /* 16 DTPMOD64*/ | |||
120 | _RF_E0x02000000, /* 17 DTPOFF64*/ | |||
121 | _RF_E0x02000000, /* 18 TPOFF64 */ | |||
122 | _RF_E0x02000000, /* 19 TLSGD */ | |||
123 | _RF_E0x02000000, /* 20 TLSLD */ | |||
124 | _RF_E0x02000000, /* 21 DTPOFF32*/ | |||
125 | _RF_E0x02000000, /* 22 GOTTPOFF*/ | |||
126 | _RF_E0x02000000 /* 23 TPOFF32*/ | |||
127 | }; | |||
128 | ||||
129 | #define RELOC_RESOLVE_SYMBOL(t)((reloc_target_flags[t] & 0x80000000) != 0) ((reloc_target_flags[t] & _RF_S0x80000000) != 0) | |||
130 | #define RELOC_PC_RELATIVE(t)((reloc_target_flags[t] & 0x20000000) != 0) ((reloc_target_flags[t] & _RF_P0x20000000) != 0) | |||
131 | #define RELOC_BASE_RELATIVE(t)((reloc_target_flags[t] & 0x08000000) != 0) ((reloc_target_flags[t] & _RF_B0x08000000) != 0) | |||
132 | #define RELOC_USE_ADDEND(t)((reloc_target_flags[t] & 0x40000000) != 0) ((reloc_target_flags[t] & _RF_A0x40000000) != 0) | |||
133 | #define RELOC_TARGET_SIZE(t)((reloc_target_flags[t] >> 8) & 0xff) ((reloc_target_flags[t] >> 8) & 0xff) | |||
134 | #define RELOC_VALUE_RIGHTSHIFT(t)(reloc_target_flags[t] & 0xff) (reloc_target_flags[t] & 0xff) | |||
135 | #define RELOC_ERROR(t)((t) >= (sizeof((reloc_target_flags)) / sizeof((reloc_target_flags )[0])) || (reloc_target_flags[t] & 0x02000000)) \ | |||
136 | ((t) >= nitems(reloc_target_flags)(sizeof((reloc_target_flags)) / sizeof((reloc_target_flags)[0 ])) || (reloc_target_flags[t] & _RF_E0x02000000)) | |||
137 | ||||
138 | static const Elf_AddrElf64_Addr reloc_target_bitmask[] = { | |||
139 | #define _BM(x) (~(Elf_AddrElf64_Addr)0 >> ((8*sizeof(reloc_target_bitmask[0])) - (x))) | |||
140 | 0, /* 0 NONE */ | |||
141 | _BM(64), /* 1 _64*/ | |||
142 | _BM(32), /* 2 PC32 */ | |||
143 | _BM(32), /* 3 GOT32 */ | |||
144 | _BM(32), /* 4 PLT32 */ | |||
145 | 0, /* 5 COPY */ | |||
146 | _BM(64), /* 6 GLOB_DAT*/ | |||
147 | _BM(64), /* 7 JUMP_SLOT*/ | |||
148 | _BM(64), /* 8 RELATIVE*/ | |||
149 | _BM(32), /* 9 GOTPCREL*/ | |||
150 | _BM(32), /* 10 32 */ | |||
151 | _BM(32), /* 11 32S */ | |||
152 | _BM(16), /* 12 16 */ | |||
153 | _BM(16), /* 13 PC16 */ | |||
154 | _BM(8), /* 14 8 */ | |||
155 | _BM(8), /* 15 PC8 */ | |||
156 | 0, /* 16 DTPMOD64*/ | |||
157 | 0, /* 17 DTPOFF64*/ | |||
158 | 0, /* 18 TPOFF64 */ | |||
159 | 0, /* 19 TLSGD */ | |||
160 | 0, /* 20 TLSLD */ | |||
161 | 0, /* 21 DTPOFF32*/ | |||
162 | 0, /* 22 GOTTPOFF*/ | |||
163 | 0 /* 23 TPOFF32*/ | |||
164 | #undef _BM | |||
165 | }; | |||
166 | #define RELOC_VALUE_BITMASK(t)(reloc_target_bitmask[t]) (reloc_target_bitmask[t]) | |||
167 | ||||
168 | void _dl_reloc_plt(Elf_AddrElf64_Addr *where, Elf_AddrElf64_Addr value); | |||
169 | ||||
170 | int | |||
171 | _dl_md_reloc(elf_object_t *object, int rel, int relsz) | |||
172 | { | |||
173 | long i; | |||
174 | long numrel; | |||
175 | long relrel; | |||
176 | int fails = 0; | |||
177 | Elf_AddrElf64_Addr loff; | |||
178 | Elf_AddrElf64_Addr prev_value = 0; | |||
179 | const Elf_SymElf64_Sym *prev_sym = NULL((void *)0); | |||
180 | Elf_RelAElf64_Rela *rels; | |||
181 | ||||
182 | loff = object->obj_base; | |||
183 | numrel = object->Dyn.info[relsz] / sizeof(Elf_RelAElf64_Rela); | |||
184 | relrel = rel
| |||
185 | rels = (Elf_RelAElf64_Rela *)(object->Dyn.info[rel]); | |||
186 | if (rels == NULL((void *)0)) | |||
187 | return 0; | |||
188 | ||||
189 | if (relrel > numrel) | |||
190 | _dl_die("relacount > numrel: %ld > %ld", relrel, numrel); | |||
191 | ||||
192 | /* tight loop for leading RELATIVE relocs */ | |||
193 | for (i = 0; i < relrel; i++, rels++) { | |||
194 | Elf_AddrElf64_Addr *where; | |||
195 | ||||
196 | where = (Elf_AddrElf64_Addr *)(rels->r_offset + loff); | |||
197 | *where = rels->r_addend + loff; | |||
198 | } | |||
199 | for (; i < numrel; i++, rels++) { | |||
200 | Elf_AddrElf64_Addr *where, value, mask; | |||
201 | Elf_WordElf64_Word type; | |||
202 | const Elf_SymElf64_Sym *sym; | |||
203 | const char *symn; | |||
204 | ||||
205 | type = ELF_R_TYPE(rels->r_info)((rels->r_info) & 0xFFFFFFFF); | |||
206 | ||||
207 | if (RELOC_ERROR(type)((type) >= (sizeof((reloc_target_flags)) / sizeof((reloc_target_flags )[0])) || (reloc_target_flags[type] & 0x02000000))) | |||
208 | _dl_die("relocation error %d idx %ld", type, i); | |||
209 | ||||
210 | if (type == R_TYPE(NONE)0) | |||
211 | continue; | |||
212 | ||||
213 | if (type == R_TYPE(JUMP_SLOT)7 && rel != DT_JMPREL23) | |||
214 | continue; | |||
215 | ||||
216 | where = (Elf_AddrElf64_Addr *)(rels->r_offset + loff); | |||
217 | ||||
218 | if (RELOC_USE_ADDEND(type)((reloc_target_flags[type] & 0x40000000) != 0)) | |||
219 | value = rels->r_addend; | |||
220 | else | |||
221 | value = 0; | |||
222 | ||||
223 | sym = NULL((void *)0); | |||
224 | symn = NULL((void *)0); | |||
225 | if (RELOC_RESOLVE_SYMBOL(type)((reloc_target_flags[type] & 0x80000000) != 0)) { | |||
226 | sym = object->dynDyn.u.symtab; | |||
227 | sym += ELF_R_SYM(rels->r_info)((rels->r_info) >> 32); | |||
228 | symn = object->dynDyn.u.strtab + sym->st_name; | |||
229 | ||||
230 | if (sym->st_shndx != SHN_UNDEF0 && | |||
231 | ELF_ST_BIND(sym->st_info)((sym->st_info) >> 4) == STB_LOCAL0) { | |||
232 | value += loff; | |||
233 | } else if (sym == prev_sym) { | |||
234 | value += prev_value; | |||
235 | } else { | |||
236 | struct sym_res sr; | |||
237 | ||||
238 | sr = _dl_find_symbol(symn, | |||
239 | SYM_SEARCH_ALL0x00|SYM_WARNNOTFOUND0x10| | |||
240 | ((type == R_TYPE(JUMP_SLOT)7)? | |||
241 | SYM_PLT0x20:SYM_NOTPLT0x00), sym, object); | |||
242 | if (sr.sym == NULL((void *)0)) { | |||
243 | resolve_failed: | |||
244 | if (ELF_ST_BIND(sym->st_info)((sym->st_info) >> 4) != | |||
| ||||
245 | STB_WEAK2) | |||
246 | fails++; | |||
247 | continue; | |||
248 | } | |||
249 | prev_sym = sym; | |||
250 | prev_value = (Elf_AddrElf64_Addr)(sr.obj->obj_base + | |||
251 | sr.sym->st_value); | |||
252 | value += prev_value; | |||
253 | } | |||
254 | } | |||
255 | ||||
256 | if (type
| |||
257 | _dl_reloc_plt(where, value); | |||
258 | continue; | |||
259 | } | |||
260 | ||||
261 | if (type == R_TYPE(COPY)5) { | |||
262 | void *dstaddr = where; | |||
263 | const void *srcaddr; | |||
264 | const Elf_SymElf64_Sym *dstsym = sym; | |||
265 | struct sym_res sr; | |||
266 | ||||
267 | sr = _dl_find_symbol(symn, | |||
268 | SYM_SEARCH_OTHER0x02|SYM_WARNNOTFOUND0x10|SYM_NOTPLT0x00, | |||
269 | dstsym, object); | |||
270 | if (sr.sym == NULL((void *)0)) | |||
271 | goto resolve_failed; | |||
272 | ||||
273 | srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value); | |||
274 | _dl_bcopy(srcaddr, dstaddr, dstsym->st_size); | |||
275 | continue; | |||
276 | } | |||
277 | ||||
278 | if (RELOC_PC_RELATIVE(type)((reloc_target_flags[type] & 0x20000000) != 0)) | |||
279 | value -= (Elf_AddrElf64_Addr)where; | |||
280 | if (RELOC_BASE_RELATIVE(type)((reloc_target_flags[type] & 0x08000000) != 0)) | |||
281 | value += loff; | |||
282 | ||||
283 | mask = RELOC_VALUE_BITMASK(type)(reloc_target_bitmask[type]); | |||
284 | value >>= RELOC_VALUE_RIGHTSHIFT(type)(reloc_target_flags[type] & 0xff); | |||
285 | value &= mask; | |||
286 | ||||
287 | if (RELOC_TARGET_SIZE(type)((reloc_target_flags[type] >> 8) & 0xff) > 32) { | |||
288 | *where &= ~mask; | |||
289 | *where |= value; | |||
290 | } else { | |||
291 | Elf32_Addr *where32 = (Elf32_Addr *)where; | |||
292 | ||||
293 | *where32 &= ~mask; | |||
294 | *where32 |= value; | |||
295 | } | |||
296 | } | |||
297 | ||||
298 | return fails; | |||
299 | } | |||
300 | ||||
301 | void | |||
302 | _dl_reloc_plt(Elf_AddrElf64_Addr *where, Elf_AddrElf64_Addr value) | |||
303 | { | |||
304 | *where = value; | |||
305 | } | |||
306 | ||||
307 | /* | |||
308 | * Resolve a symbol at run-time. | |||
309 | */ | |||
310 | Elf_AddrElf64_Addr | |||
311 | _dl_bind(elf_object_t *object, int index) | |||
312 | { | |||
313 | Elf_RelAElf64_Rela *rel; | |||
314 | const Elf_SymElf64_Sym *sym; | |||
315 | const char *symn; | |||
316 | struct sym_res sr; | |||
317 | int64_t cookie = pcookie; | |||
318 | struct { | |||
319 | struct __kbind param; | |||
320 | Elf_AddrElf64_Addr newval; | |||
321 | } buf; | |||
322 | ||||
323 | rel = (Elf_RelAElf64_Rela *)(object->Dyn.info[DT_JMPREL23]) + index; | |||
324 | ||||
325 | sym = object->dynDyn.u.symtab; | |||
326 | sym += ELF_R_SYM(rel->r_info)((rel->r_info) >> 32); | |||
327 | symn = object->dynDyn.u.strtab + sym->st_name; | |||
328 | ||||
329 | sr = _dl_find_symbol(symn, SYM_SEARCH_ALL0x00|SYM_WARNNOTFOUND0x10|SYM_PLT0x20, | |||
330 | sym, object); | |||
331 | if (sr.sym == NULL((void *)0)) | |||
332 | _dl_die("lazy binding failed!"); | |||
333 | ||||
334 | buf.newval = sr.obj->obj_base + sr.sym->st_value; | |||
335 | ||||
336 | if (__predict_false(sr.obj->traced)__builtin_expect(((sr.obj->traced) != 0), 0) && _dl_trace_plt(sr.obj, symn)) | |||
337 | return buf.newval; | |||
338 | ||||
339 | buf.param.kb_addr = (Elf_WordElf64_Word *)(object->obj_base + rel->r_offset); | |||
340 | buf.param.kb_size = sizeof(Elf_AddrElf64_Addr); | |||
341 | ||||
342 | /* directly code the syscall, so that it's actually inline here */ | |||
343 | { | |||
344 | register long syscall_num __asm("rax") = SYS_kbind86; | |||
345 | register void *arg1 __asm("rdi") = &buf; | |||
346 | register long arg2 __asm("rsi") = sizeof(buf); | |||
347 | register long arg3 __asm("rdx") = cookie; | |||
348 | ||||
349 | __asm volatile("syscall" : "+r" (syscall_num), "+r" (arg3) : | |||
350 | "r" (arg1), "r" (arg2) : "cc", "rcx", "r11", "memory"); | |||
351 | } | |||
352 | return buf.newval; | |||
353 | } | |||
354 | ||||
355 | int | |||
356 | _dl_md_reloc_got(elf_object_t *object, int lazy) | |||
357 | { | |||
358 | extern void _dl_bind_start(void); /* XXX */ | |||
359 | int fails = 0; | |||
360 | Elf_AddrElf64_Addr *pltgot = (Elf_AddrElf64_Addr *)object->Dyn.info[DT_PLTGOT3]; | |||
361 | int i, num; | |||
362 | Elf_RelAElf64_Rela *rel; | |||
363 | ||||
364 | if (pltgot == NULL((void *)0)) | |||
| ||||
365 | return 0; /* it is possible to have no PLT/GOT relocations */ | |||
366 | ||||
367 | if (object->Dyn.info[DT_PLTREL20] != DT_RELA7) | |||
368 | return 0; | |||
369 | ||||
370 | if (__predict_false(!lazy)__builtin_expect(((!lazy) != 0), 0)) { | |||
371 | fails = _dl_md_reloc(object, DT_JMPREL23, DT_PLTRELSZ2); | |||
372 | } else { | |||
373 | pltgot[1] = (Elf_AddrElf64_Addr)object; | |||
374 | pltgot[2] = (Elf_AddrElf64_Addr)&_dl_bind_start; | |||
375 | ||||
376 | rel = (Elf_RelAElf64_Rela *)(object->Dyn.info[DT_JMPREL23]); | |||
377 | num = (object->Dyn.info[DT_PLTRELSZ2]); | |||
378 | for (i = 0; i < num/sizeof(Elf_RelAElf64_Rela); i++, rel++) { | |||
379 | Elf_AddrElf64_Addr *where; | |||
380 | where = (Elf_AddrElf64_Addr *)(rel->r_offset + object->obj_base); | |||
381 | *where += object->obj_base; | |||
382 | } | |||
383 | } | |||
384 | ||||
385 | return fails; | |||
386 | } |