Deleted Added
full compact
reloc.c (183841) reloc.c (204687)
1/* $NetBSD: mdreloc.c,v 1.23 2003/07/26 15:04:38 mrg Exp $ */
2/* $NetBSD: mips_reloc.c,v 1.53 2008/07/24 04:39:25 matt Exp $ */
1/* $NetBSD: mips_reloc.c,v 1.58 2010/01/14 11:57:06 skrll Exp $ */
3
4/*
5 * Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
6 * Portions copyright 2002 Charles M. Hannum <root@ihack.net>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions

--- 14 unchanged lines hidden (view full) ---

25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
2
3/*
4 * Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
5 * Portions copyright 2002 Charles M. Hannum <root@ihack.net>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions

--- 14 unchanged lines hidden (view full) ---

24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/libexec/rtld-elf/mips/reloc.c 183841 2008-10-13 20:24:03Z imp $");
34#include <sys/param.h>
35#include <sys/mman.h>
32__FBSDID("$FreeBSD: head/libexec/rtld-elf/mips/reloc.c 204687 2010-03-04 04:53:05Z imp $");
36
33
37#include <errno.h>
38#include <stdio.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/endian.h>
37
39#include <stdlib.h>
40#include <string.h>
38#include <stdlib.h>
39#include <string.h>
41#include <unistd.h>
40
42#include "debug.h"
43#include "rtld.h"
44
45void
46init_pltgot(Obj_Entry *obj)
41#include "debug.h"
42#include "rtld.h"
43
44void
45init_pltgot(Obj_Entry *obj)
47{
46{
48 if (obj->pltgot != NULL) {
49 obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start;
47 if (obj->pltgot != NULL) {
48 obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start;
49 /* XXX only if obj->pltgot[1] & 0x80000000 ?? */
50 obj->pltgot[1] |= (Elf_Addr) obj;
51 }
52}
53
50 obj->pltgot[1] |= (Elf_Addr) obj;
51 }
52}
53
54int
54int
55do_copy_relocations(Obj_Entry *dstobj)
56{
57 /* Do nothing */
55do_copy_relocations(Obj_Entry *dstobj)
56{
57 /* Do nothing */
58 return 0;
58 return 0;
59}
60
59}
60
61void _rtld_bind_start(void);
62void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
63
61void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
62
64int open();
65int _open();
66
67/*
68 * It is possible for the compiler to emit relocations for unaligned data.
69 * We handle this situation with these inlines.
70 */
63/*
64 * It is possible for the compiler to emit relocations for unaligned data.
65 * We handle this situation with these inlines.
66 */
71#define RELOC_ALIGNED_P(x) \
72 (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
67#if ELFSIZE == 64
68/*
69 * ELF64 MIPS encodes the relocs uniquely. The first 32-bits of info contain
70 * the symbol index. The top 32-bits contain three relocation types encoded
71 * in big-endian integer with first relocation in LSB. This means for little
72 * endian we have to byte swap that interger (r_type).
73 */
74#define Elf_Sxword Elf64_Sxword
75#define ELF_R_NXTTYPE_64_P(r_type) ((((r_type) >> 8) & 0xff) == R_TYPE(64))
76#if BYTE_ORDER == LITTLE_ENDIAN
77#undef ELF_R_SYM
78#undef ELF_R_TYPE
79#define ELF_R_SYM(r_info) ((r_info) & 0xffffffff)
80#define ELF_R_TYPE(r_info) bswap32((r_info) >> 32)
81#endif
82#else
83#define ELF_R_NXTTYPE_64_P(r_type) (0)
84#define Elf_Sxword Elf32_Sword
85#endif
73
86
74static __inline Elf_Addr
75load_ptr(void *where)
87static __inline Elf_Sxword
88load_ptr(void *where, size_t len)
76{
89{
77 if (__predict_true(RELOC_ALIGNED_P(where)))
78 return *(Elf_Addr *)where;
79 else {
80 Elf_Addr res;
90 Elf_Sxword val;
81
91
82 (void)memcpy(&res, where, sizeof(res));
83 return res;
92 if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) {
93#if ELFSIZE == 64
94 if (len == sizeof(Elf_Sxword))
95 return *(Elf_Sxword *)where;
96#endif
97 return *(Elf_Sword *)where;
84 }
98 }
99
100 val = 0;
101#if BYTE_ORDER == LITTLE_ENDIAN
102 (void)memcpy(&val, where, len);
103#endif
104#if BYTE_ORDER == BIG_ENDIAN
105 (void)memcpy((uint8_t *)((&val)+1) - len, where, len);
106#endif
107 return (len == sizeof(Elf_Sxword)) ? val : (Elf_Sword)val;
85}
86
87static __inline void
108}
109
110static __inline void
88store_ptr(void *where, Elf_Addr val)
111store_ptr(void *where, Elf_Sxword val, size_t len)
89{
112{
90 if (__predict_true(RELOC_ALIGNED_P(where)))
91 *(Elf_Addr *)where = val;
92 else
93 (void)memcpy(where, &val, sizeof(val));
113 if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) {
114#if ELFSIZE == 64
115 if (len == sizeof(Elf_Sxword)) {
116 *(Elf_Sxword *)where = val;
117 return;
118 }
119#endif
120 *(Elf_Sword *)where = val;
121 return;
122 }
123#if BYTE_ORDER == LITTLE_ENDIAN
124 (void)memcpy(where, &val, len);
125#endif
126#if BYTE_ORDER == BIG_ENDIAN
127 (void)memcpy(where, (const uint8_t *)((&val)+1) - len, len);
128#endif
94}
95
96void
97_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
98{
99 const Elf_Rel *rel = 0, *rellim;
100 Elf_Addr relsz = 0;
101 const Elf_Sym *symtab = NULL, *sym;
102 Elf_Addr *where;
103 Elf_Addr *got = NULL;
104 Elf_Word local_gotno = 0, symtabno = 0, gotsym = 0;
129}
130
131void
132_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
133{
134 const Elf_Rel *rel = 0, *rellim;
135 Elf_Addr relsz = 0;
136 const Elf_Sym *symtab = NULL, *sym;
137 Elf_Addr *where;
138 Elf_Addr *got = NULL;
139 Elf_Word local_gotno = 0, symtabno = 0, gotsym = 0;
105 int i;
140 size_t i;
106
107 for (; dynp->d_tag != DT_NULL; dynp++) {
108 switch (dynp->d_tag) {
109 case DT_REL:
110 rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
111 break;
112 case DT_RELSZ:
113 relsz = dynp->d_un.d_val;

--- 15 unchanged lines hidden (view full) ---

129 break;
130 }
131 }
132
133 i = (got[1] & 0x80000000) ? 2 : 1;
134 /* Relocate the local GOT entries */
135 got += i;
136 for (; i < local_gotno; i++) {
141
142 for (; dynp->d_tag != DT_NULL; dynp++) {
143 switch (dynp->d_tag) {
144 case DT_REL:
145 rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
146 break;
147 case DT_RELSZ:
148 relsz = dynp->d_un.d_val;

--- 15 unchanged lines hidden (view full) ---

164 break;
165 }
166 }
167
168 i = (got[1] & 0x80000000) ? 2 : 1;
169 /* Relocate the local GOT entries */
170 got += i;
171 for (; i < local_gotno; i++) {
137 *got++ += relocbase;
172 *got++ += relocbase;
138 }
139
140 sym = symtab + gotsym;
141 /* Now do the global GOT entries */
142 for (i = gotsym; i < symtabno; i++) {
143 *got = sym->st_value + relocbase;
144 ++sym;
145 ++got;
146 }
147
148 rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
149 for (; rel < rellim; rel++) {
173 }
174
175 sym = symtab + gotsym;
176 /* Now do the global GOT entries */
177 for (i = gotsym; i < symtabno; i++) {
178 *got = sym->st_value + relocbase;
179 ++sym;
180 ++got;
181 }
182
183 rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
184 for (; rel < rellim; rel++) {
185 Elf_Word r_symndx, r_type;
186
150 where = (void *)(relocbase + rel->r_offset);
151
187 where = (void *)(relocbase + rel->r_offset);
188
152 switch (ELF_R_TYPE(rel->r_info)) {
153 case R_TYPE(NONE):
154 break;
189 r_symndx = ELF_R_SYM(rel->r_info);
190 r_type = ELF_R_TYPE(rel->r_info);
155
191
156 case R_TYPE(REL32):
157 assert(ELF_R_SYM(rel->r_info) < gotsym);
158 sym = symtab + ELF_R_SYM(rel->r_info);
192 switch (r_type & 0xff) {
193 case R_TYPE(REL32): {
194 const size_t rlen =
195 ELF_R_NXTTYPE_64_P(r_type)
196 ? sizeof(Elf_Sxword)
197 : sizeof(Elf_Sword);
198 Elf_Sxword old = load_ptr(where, rlen);
199 Elf_Sxword val = old;
200#if ELFSIZE == 64
201 assert(r_type == R_TYPE(REL32)
202 || r_type == (R_TYPE(REL32)|(R_TYPE(64) << 8)));
203#endif
204 assert(r_symndx < gotsym);
205 sym = symtab + r_symndx;
159 assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL);
206 assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL);
160 store_ptr(where, load_ptr(where) + relocbase);
207 val += relocbase;
208 store_ptr(where, val, sizeof(Elf_Sword));
209 dbg("REL32/L(%p) %p -> %p in <self>",
210 where, (void *)old, (void *)val);
211 store_ptr(where, val, rlen);
161 break;
212 break;
213 }
162
214
215 case R_TYPE(GPREL32):
216 case R_TYPE(NONE):
217 break;
218
219
163 default:
164 abort();
165 break;
166 }
167 }
168}
169
170Elf_Addr

--- 13 unchanged lines hidden (view full) ---

184 obj->path,
185 reloff, defobj->strtab + def->st_name,
186 (void *)got[obj->local_gotno + reloff - obj->gotsym],
187 (void *)target);
188 got[obj->local_gotno + reloff - obj->gotsym] = target;
189 return (Elf_Addr)target;
190}
191
220 default:
221 abort();
222 break;
223 }
224 }
225}
226
227Elf_Addr

--- 13 unchanged lines hidden (view full) ---

241 obj->path,
242 reloff, defobj->strtab + def->st_name,
243 (void *)got[obj->local_gotno + reloff - obj->gotsym],
244 (void *)target);
245 got[obj->local_gotno + reloff - obj->gotsym] = target;
246 return (Elf_Addr)target;
247}
248
192/*
193 * Process non-PLT relocations
194 */
195int
196reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
197{
198 const Elf_Rel *rel;
199 const Elf_Rel *rellim;
200 Elf_Addr *got = obj->pltgot;
201 const Elf_Sym *sym, *def;
202 const Obj_Entry *defobj;
249int
250reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
251{
252 const Elf_Rel *rel;
253 const Elf_Rel *rellim;
254 Elf_Addr *got = obj->pltgot;
255 const Elf_Sym *sym, *def;
256 const Obj_Entry *defobj;
203 int i;
257 Elf_Word i;
258#ifdef SUPPORT_OLD_BROKEN_LD
259 int broken;
260#endif
204
205 /* The relocation for the dynamic loader has already been done. */
206 if (obj == obj_rtld)
207 return (0);
208
261
262 /* The relocation for the dynamic loader has already been done. */
263 if (obj == obj_rtld)
264 return (0);
265
266#ifdef SUPPORT_OLD_BROKEN_LD
267 broken = 0;
268 sym = obj->symtab;
269 for (i = 1; i < 12; i++)
270 if (sym[i].st_info == ELF_ST_INFO(STB_LOCAL, STT_NOTYPE))
271 broken = 1;
272 dbg("%s: broken=%d", obj->path, broken);
273#endif
274
209 i = (got[1] & 0x80000000) ? 2 : 1;
210
211 /* Relocate the local GOT entries */
212 got += i;
213 dbg("got:%p for %d entries adding %x",
214 got, obj->local_gotno, (uint32_t)obj->relocbase);
215 for (; i < obj->local_gotno; i++) {
275 i = (got[1] & 0x80000000) ? 2 : 1;
276
277 /* Relocate the local GOT entries */
278 got += i;
279 dbg("got:%p for %d entries adding %x",
280 got, obj->local_gotno, (uint32_t)obj->relocbase);
281 for (; i < obj->local_gotno; i++) {
216 *got += (Elf_Addr)obj->relocbase;
217 got++;
282 *got += (Elf_Addr)obj->relocbase;
283 got++;
218 }
219 sym = obj->symtab + obj->gotsym;
220
284 }
285 sym = obj->symtab + obj->gotsym;
286
221
222 dbg("got:%p for %d entries",
223 got, obj->symtabno);
224 /* Now do the global GOT entries */
225 for (i = obj->gotsym; i < obj->symtabno; i++) {
287 dbg("got:%p for %d entries",
288 got, obj->symtabno);
289 /* Now do the global GOT entries */
290 for (i = obj->gotsym; i < obj->symtabno; i++) {
291 dbg(" doing got %d sym %p (%s, %lx)", i - obj->gotsym, sym,
292 sym->st_name + obj->strtab, (u_long) *got);
293
294#ifdef SUPPORT_OLD_BROKEN_LD
226 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
295 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
296 broken && sym->st_shndx == SHN_UNDEF) {
297 /*
298 * XXX DANGER WILL ROBINSON!
299 * You might think this is stupid, as it intentionally
300 * defeats lazy binding -- and you'd be right.
301 * Unfortunately, for lazy binding to work right, we
302 * need to a way to force the GOT slots used for
303 * function pointers to be resolved immediately. This
304 * is supposed to be done automatically by the linker,
305 * by not outputting a PLT slot and setting st_value
306 * to 0 if there are non-PLT references, but older
307 * versions of GNU ld do not do this.
308 */
309 def = find_symdef(i, obj, &defobj, false, NULL);
310 if (def == NULL)
311 return -1;
312 *got = def->st_value + (Elf_Addr)defobj->relocbase;
313 } else
314#endif
315 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
227 sym->st_value != 0 && sym->st_shndx == SHN_UNDEF) {
228 /*
229 * If there are non-PLT references to the function,
230 * st_value should be 0, forcing us to resolve the
231 * address immediately.
232 *
233 * XXX DANGER WILL ROBINSON!
234 * The linker is not outputting PLT slots for calls to
235 * functions that are defined in the same shared
236 * library. This is a bug, because it can screw up
237 * link ordering rules if the symbol is defined in
238 * more than one module. For now, if there is a
239 * definition, we fail the test above and force a full
240 * symbol lookup. This means that all intra-module
241 * calls are bound immediately. - mycroft, 2003/09/24
242 */
243 *got = sym->st_value + (Elf_Addr)obj->relocbase;
244 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
316 sym->st_value != 0 && sym->st_shndx == SHN_UNDEF) {
317 /*
318 * If there are non-PLT references to the function,
319 * st_value should be 0, forcing us to resolve the
320 * address immediately.
321 *
322 * XXX DANGER WILL ROBINSON!
323 * The linker is not outputting PLT slots for calls to
324 * functions that are defined in the same shared
325 * library. This is a bug, because it can screw up
326 * link ordering rules if the symbol is defined in
327 * more than one module. For now, if there is a
328 * definition, we fail the test above and force a full
329 * symbol lookup. This means that all intra-module
330 * calls are bound immediately. - mycroft, 2003/09/24
331 */
332 *got = sym->st_value + (Elf_Addr)obj->relocbase;
333 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
245 dbg("Warning2, i:%d maps to relocbase address:%x",
246 i, (uint32_t)obj->relocbase);
334 dbg("Warning2, i:%d maps to relocbase address:%x",
335 i, (uint32_t)obj->relocbase);
247 }
248
249 } else if (sym->st_info == ELF_ST_INFO(STB_GLOBAL, STT_SECTION)) {
250 /* Symbols with index SHN_ABS are not relocated. */
336 }
337
338 } else if (sym->st_info == ELF_ST_INFO(STB_GLOBAL, STT_SECTION)) {
339 /* Symbols with index SHN_ABS are not relocated. */
251 if (sym->st_shndx != SHN_ABS) {
340 if (sym->st_shndx != SHN_ABS) {
252 *got = sym->st_value +
253 (Elf_Addr)obj->relocbase;
254 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
341 *got = sym->st_value +
342 (Elf_Addr)obj->relocbase;
343 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
255 dbg("Warning3, i:%d maps to relocbase address:%x",
256 i, (uint32_t)obj->relocbase);
344 dbg("Warning3, i:%d maps to relocbase address:%x",
345 i, (uint32_t)obj->relocbase);
257 }
258 }
259 } else {
260 /* TODO: add cache here */
261 def = find_symdef(i, obj, &defobj, false, NULL);
262 if (def == NULL) {
346 }
347 }
348 } else {
349 /* TODO: add cache here */
350 def = find_symdef(i, obj, &defobj, false, NULL);
351 if (def == NULL) {
263 dbg("Warning4, cant find symbole %d", i);
352 dbg("Warning4, cant find symbole %d", i);
264 return -1;
265 }
266 *got = def->st_value + (Elf_Addr)defobj->relocbase;
267 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
353 return -1;
354 }
355 *got = def->st_value + (Elf_Addr)defobj->relocbase;
356 if ((Elf_Addr)(*got) == (Elf_Addr)obj->relocbase) {
268 dbg("Warning4, i:%d maps to relocbase address:%x",
269 i, (uint32_t)obj->relocbase);
270 dbg("via first obj symbol %s",
271 obj->strtab + obj->symtab[i].st_name);
272 dbg("found in obj %p:%s",
273 defobj, defobj->path);
274 }
357 dbg("Warning4, i:%d maps to relocbase address:%x",
358 i, (uint32_t)obj->relocbase);
359 dbg("via first obj symbol %s",
360 obj->strtab + obj->symtab[i].st_name);
361 dbg("found in obj %p:%s",
362 defobj, defobj->path);
363 }
275 }
364 }
365
366 dbg(" --> now %lx", (u_long) *got);
276 ++sym;
277 ++got;
278 }
367 ++sym;
368 ++got;
369 }
370
279 got = obj->pltgot;
280 rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
281 for (rel = obj->rel; rel < rellim; rel++) {
371 got = obj->pltgot;
372 rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
373 for (rel = obj->rel; rel < rellim; rel++) {
374 Elf_Word r_symndx, r_type;
282 void *where;
375 void *where;
283 Elf_Addr tmp;
284 unsigned long symnum;
285
286 where = obj->relocbase + rel->r_offset;
376
377 where = obj->relocbase + rel->r_offset;
287 symnum = ELF_R_SYM(rel->r_info);
288 switch (ELF_R_TYPE(rel->r_info)) {
378 r_symndx = ELF_R_SYM(rel->r_info);
379 r_type = ELF_R_TYPE(rel->r_info);
380
381 switch (r_type & 0xff) {
289 case R_TYPE(NONE):
290 break;
291
382 case R_TYPE(NONE):
383 break;
384
292 case R_TYPE(REL32):
385 case R_TYPE(REL32): {
293 /* 32-bit PC-relative reference */
386 /* 32-bit PC-relative reference */
294 def = obj->symtab + symnum;
295 if (symnum >= obj->gotsym) {
296 tmp = load_ptr(where);
297 tmp += got[obj->local_gotno + symnum - obj->gotsym];
298 store_ptr(where, tmp);
299 break;
387 const size_t rlen =
388 ELF_R_NXTTYPE_64_P(r_type)
389 ? sizeof(Elf_Sxword)
390 : sizeof(Elf_Sword);
391 Elf_Sxword old = load_ptr(where, rlen);
392 Elf_Sxword val = old;
393
394 def = obj->symtab + r_symndx;
395
396 if (r_symndx >= obj->gotsym) {
397 val += got[obj->local_gotno + r_symndx - obj->gotsym];
398 dbg("REL32/G(%p) %p --> %p (%s) in %s",
399 where, (void *)old, (void *)val,
400 obj->strtab + def->st_name,
401 obj->path);
300 } else {
402 } else {
301 tmp = load_ptr(where);
403 /*
404 * XXX: ABI DIFFERENCE!
405 *
406 * Old NetBSD binutils would generate shared
407 * libs with section-relative relocations being
408 * already adjusted for the start address of
409 * the section.
410 *
411 * New binutils, OTOH, generate shared libs
412 * with the same relocations being based at
413 * zero, so we need to add in the start address
414 * of the section.
415 *
416 * --rkb, Oct 6, 2001
417 */
302
303 if (def->st_info ==
304 ELF_ST_INFO(STB_LOCAL, STT_SECTION)
418
419 if (def->st_info ==
420 ELF_ST_INFO(STB_LOCAL, STT_SECTION)
421#ifdef SUPPORT_OLD_BROKEN_LD
422 && !broken
423#endif
305 )
424 )
306 tmp += (Elf_Addr)def->st_value;
425 val += (Elf_Addr)def->st_value;
307
426
308 tmp += (Elf_Addr)obj->relocbase;
309 store_ptr(where, tmp);
427 val += (Elf_Addr)obj->relocbase;
428
429 dbg("REL32/L(%p) %p -> %p (%s) in %s",
430 where, (void *)old, (void *)val,
431 obj->strtab + def->st_name, obj->path);
310 }
432 }
433 store_ptr(where, val, rlen);
311 break;
434 break;
435 }
436
312 default:
313 dbg("sym = %lu, type = %lu, offset = %p, "
314 "contents = %p, symbol = %s",
437 default:
438 dbg("sym = %lu, type = %lu, offset = %p, "
439 "contents = %p, symbol = %s",
315 symnum, (u_long)ELF_R_TYPE(rel->r_info),
316 (void *)rel->r_offset, (void *)load_ptr(where),
317 obj->strtab + obj->symtab[symnum].st_name);
440 (u_long)r_symndx, (u_long)ELF_R_TYPE(rel->r_info),
441 (void *)rel->r_offset,
442 (void *)load_ptr(where, sizeof(Elf_Sword)),
443 obj->strtab + obj->symtab[r_symndx].st_name);
318 _rtld_error("%s: Unsupported relocation type %ld "
444 _rtld_error("%s: Unsupported relocation type %ld "
319 "in non-PLT relocations\n",
445 "in non-PLT relocations",
320 obj->path, (u_long) ELF_R_TYPE(rel->r_info));
321 return -1;
322 }
323 }
324
325 return 0;
326}
327
328/*
329 * Process the PLT relocations.
330 */
331int
332reloc_plt(Obj_Entry *obj)
333{
446 obj->path, (u_long) ELF_R_TYPE(rel->r_info));
447 return -1;
448 }
449 }
450
451 return 0;
452}
453
454/*
455 * Process the PLT relocations.
456 */
457int
458reloc_plt(Obj_Entry *obj)
459{
460#if 0
334 const Elf_Rel *rellim;
335 const Elf_Rel *rel;
336
337 dbg("reloc_plt obj:%p pltrel:%p sz:%d", obj, obj->pltrel, (int)obj->pltrelsize);
338 dbg("gottable %p num syms:%d", obj->pltgot, obj->symtabno );
339 dbg("*****************************************************");
340 rellim = (const Elf_Rel *)((char *)obj->pltrel +
341 obj->pltrelsize);
342 for (rel = obj->pltrel; rel < rellim; rel++) {
343 Elf_Addr *where;
344 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
345 *where += (Elf_Addr )obj->relocbase;
346 }
347
461 const Elf_Rel *rellim;
462 const Elf_Rel *rel;
463
464 dbg("reloc_plt obj:%p pltrel:%p sz:%d", obj, obj->pltrel, (int)obj->pltrelsize);
465 dbg("gottable %p num syms:%d", obj->pltgot, obj->symtabno );
466 dbg("*****************************************************");
467 rellim = (const Elf_Rel *)((char *)obj->pltrel +
468 obj->pltrelsize);
469 for (rel = obj->pltrel; rel < rellim; rel++) {
470 Elf_Addr *where;
471 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
472 *where += (Elf_Addr )obj->relocbase;
473 }
474
475#endif
476 /* PLT fixups were done above in the GOT relocation. */
348 return (0);
349}
350
351/*
352 * LD_BIND_NOW was set - force relocation for all jump slots
353 */
354int
355reloc_jmpslots(Obj_Entry *obj)

--- 28 unchanged lines hidden ---
477 return (0);
478}
479
480/*
481 * LD_BIND_NOW was set - force relocation for all jump slots
482 */
483int
484reloc_jmpslots(Obj_Entry *obj)

--- 28 unchanged lines hidden ---