1 /* Machine-dependent ELF dynamic relocation inline functions. PA-RISC version.
2 Copyright (C) 1995-1997,1999,2000,2001,2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by David Huggins-Daines <dhd@debian.org>
5 This file is part of the GNU C Library.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 #define dl_machine_h 1
25 #define ELF_MACHINE_NAME "hppa"
27 #include <sys/param.h>
32 /* These must match the definition of the stub in bfd/elf32-hppa.c. */
33 #define SIZEOF_PLT_STUB (4*4)
34 #define GOT_FROM_PLT_STUB (4*4)
36 /* A PLABEL is a function descriptor. Properly they consist of just
37 FUNC and GP. But we want to traverse a binary tree too. See
38 dl-fptr.c for the code (it may be made common between HPPA and
41 We call these 'fptr' to make it easier to steal code from IA-64. */
43 /* ld.so currently has 12 PLABEL32 relocs. We'll keep this constant
44 large for now in case we require more, as the rest of these will be
45 used by the dynamic program itself (libc.so has quite a few
46 PLABEL32 relocs in it). */
47 #define HPPA_BOOT_FPTR_SIZE 256
53 struct hppa_fptr
*next
;
56 extern struct hppa_fptr __boot_ldso_fptr
[];
57 extern struct hppa_fptr
*__fptr_root
;
58 extern int __fptr_count
;
60 extern Elf32_Addr
__hppa_make_fptr (const struct link_map
*, Elf32_Addr
,
61 struct hppa_fptr
**, struct hppa_fptr
*);
63 /* Return nonzero iff ELF header is compatible with the running host. */
65 elf_machine_matches_host (const Elf32_Ehdr
*ehdr
)
67 return ehdr
->e_machine
== EM_PARISC
;
71 /* Return the link-time address of _DYNAMIC. */
72 static inline Elf32_Addr
73 elf_machine_dynamic (void)
78 /* Use this method if GOT address not yet set up. */
82 "1: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0\n"
83 " ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
84 : "=r" (dynamic
) : : "r1");
86 /* This works because we already have our GOT address available. */
87 dynamic
= (Elf32_Addr
) &_DYNAMIC
;
93 /* Return the run-time load address of the shared object. */
94 static inline Elf32_Addr
95 elf_machine_load_address (void)
97 Elf32_Addr dynamic
, dynamic_linkaddress
;
102 "1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0\n"
103 " ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%1\n"
104 " addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%0\n"
105 " ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%%r1),%0\n"
106 : "=r" (dynamic_linkaddress
), "=r" (dynamic
) : : "r1");
108 return dynamic
- dynamic_linkaddress
;
111 /* Fixup a PLT entry to bounce directly to the function at VALUE. */
112 static inline Elf32_Addr
113 elf_machine_fixup_plt (struct link_map
*map
, lookup_t t
,
114 const Elf32_Rela
*reloc
,
115 Elf32_Addr
*reloc_addr
, Elf32_Addr value
)
117 /* l is the link_map for the caller, t is the link_map for the object
119 reloc_addr
[1] = D_PTR (t
, l_info
[DT_PLTGOT
]);
120 reloc_addr
[0] = value
;
121 /* Return the PLT slot rather than the function value so that the
122 trampoline can load the new LTP. */
123 return (Elf32_Addr
) reloc_addr
;
126 /* Return the final value of a plt relocation. */
127 static inline Elf32_Addr
128 elf_machine_plt_value (struct link_map
*map
, const Elf32_Rela
*reloc
,
131 /* We are rela only */
132 return value
+ reloc
->r_addend
;
135 /* Set up the loaded object described by L so its unrelocated PLT
136 entries will jump to the on-demand fixup code in dl-runtime.c. */
139 elf_machine_runtime_setup (struct link_map
*l
, int lazy
, int profile
)
141 extern void _dl_runtime_resolve (void);
142 extern void _dl_runtime_profile (void);
143 Elf32_Addr jmprel
= D_PTR(l
, l_info
[DT_JMPREL
]);
147 Elf32_Addr
*got
= NULL
;
149 Elf32_Addr end_jmprel
;
152 /* Relocate all the PLT slots. */
154 end_jmprel
= jmprel
+ l
->l_info
[DT_PLTRELSZ
]->d_un
.d_val
;
155 for (iplt
= jmprel
; iplt
< end_jmprel
; iplt
+= sizeof (Elf32_Rela
))
157 const Elf32_Rela
*reloc
;
160 struct hppa_fptr
*fptr
;
162 reloc
= (const Elf32_Rela
*) iplt
;
163 r_type
= ELF32_R_TYPE (reloc
->r_info
);
164 r_sym
= ELF32_R_SYM (reloc
->r_info
);
166 if (__builtin_expect (r_type
== R_PARISC_IPLT
, 1))
168 fptr
= (struct hppa_fptr
*) (reloc
->r_offset
+ l_addr
);
171 /* Relocate the pointer to the stub. */
172 fptr
->func
+= l_addr
;
173 /* Instead of the LTP value, we put the reloc offset
174 here. The trampoline code will load the proper
175 LTP and pass the reloc offset to the fixup
177 fptr
->gp
= iplt
- jmprel
;
183 } sig
= {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
185 /* Find our .got section. It's right after the
187 got
= (Elf32_Addr
*) (fptr
->func
+ GOT_FROM_PLT_STUB
);
189 /* Sanity check to see if the address we are
190 going to check below is within a reasonable
191 approximation of the bounds of the PLT (or,
192 at least, is at an address that won't fault
193 on read). Then check for the magic signature
195 if (fptr
->func
< (Elf32_Addr
) fptr
+ sizeof(*fptr
))
200 + ((l
->l_info
[DT_PLTRELSZ
]->d_un
.d_val
/ sizeof (Elf32_Rela
))
203 if (got
[-2] != sig
.i
[0] || got
[-1] != sig
.i
[1])
204 return 0; /* No lazy linking for you! */
209 /* Relocate this *ABS* entry. */
210 fptr
->func
= reloc
->r_addend
+ l_addr
;
211 fptr
->gp
= D_PTR (l
, l_info
[DT_PLTGOT
]);
214 else if (__builtin_expect (r_type
!= R_PARISC_NONE
, 0))
215 _dl_reloc_bad_type (l
, r_type
, 1);
220 register Elf32_Addr ltp
__asm__ ("%r19");
221 /* Identify this shared object. */
222 got
[1] = (Elf32_Addr
) l
;
224 /* This function will be called to perform the relocation. */
225 if (__builtin_expect (!profile
, 1))
227 (Elf32_Addr
) ((struct hppa_fptr
*)
228 ((unsigned long) &_dl_runtime_resolve
& ~3))->func
;
231 if (_dl_name_match_p (GL(dl_profile
), l
))
233 /* This is the object we are looking for. Say that
234 we really want profiling and the timers are
236 GL(dl_profile_map
) = l
;
239 (Elf32_Addr
) ((struct hppa_fptr
*)
240 ((unsigned long) &_dl_runtime_profile
& ~3))->func
;
248 /* Initial entry point code for the dynamic linker.
249 The C function `_dl_start' is the real entry point;
250 its return value is the user program's entry point. */
253 /* Set up dp for any non-PIC lib constructors that may be called. */ \
254 static struct link_map * \
255 set_dp (struct link_map *map) \
257 register Elf32_Addr dp asm ("%r27"); \
258 dp = D_PTR (map, l_info[DT_PLTGOT]); \
259 asm volatile ("" : : "r" (dp)); \
266 " .type _start,@function\n" \
268 /* The kernel does not give us an initial stack frame. */ \
269 " ldo 64(%sp),%sp\n" \
270 /* Save the relevant arguments (yes, those are the correct \
271 registers, the kernel is weird) in their stack slots. */ \
272 " stw %r25,-40(%sp)\n" /* argc */ \
273 " stw %r24,-44(%sp)\n" /* argv */ \
275 /* We need the LTP, and we need it now. */ \
276 /* $PIC_pcrel$0 points 8 bytes past the current instruction, \
277 just like a branch reloc. This sequence gets us the runtime \
278 address of _DYNAMIC. */ \
280 " depi 0,31,2,%r19\n" /* clear priviledge bits */ \
281 "0: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19\n" \
282 " ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26\n" \
284 /* Also get the link time address from the first entry of the GOT. */ \
285 " addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19\n" \
286 " ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20\n" \
288 " sub %r26,%r20,%r20\n" /* Calculate load offset */ \
290 /* Rummage through the dynamic entries, looking for DT_PLTGOT. */ \
291 " ldw,ma 8(%r26),%r19\n" \
292 "1: cmpib,=,n 3,%r19,2f\n" /* tag == DT_PLTGOT? */ \
293 " cmpib,<>,n 0,%r19,1b\n" \
294 " ldw,ma 8(%r26),%r19\n" \
296 /* Uh oh! We didn't find one. Abort. */ \
297 " iitlbp %r0,(%r0)\n" \
299 "2: ldw -4(%r26),%r19\n" /* Found it, load value. */ \
300 " add %r19,%r20,%r19\n" /* And add the load offset. */ \
302 /* Our initial stack layout is rather different from everyone \
303 else's due to the unique PA-RISC ABI. As far as I know it \
306 ----------------------------------- (this frame created above) \
307 | 32 bytes of magic | \
308 |---------------------------------| \
309 | 32 bytes argument/sp save area | \
310 |---------------------------------| ((current->mm->env_end) + 63 & ~63) \
311 | N bytes of slack | \
312 |---------------------------------| \
313 | envvar and arg strings | \
314 |---------------------------------| \
315 | ELF auxiliary info | \
316 | (up to 28 words) | \
317 |---------------------------------| \
318 | Environment variable pointers | \
319 | upwards to NULL | \
320 |---------------------------------| \
321 | Argument pointers | \
322 | upwards to NULL | \
323 |---------------------------------| \
325 ----------------------------------- \
327 So, obviously, we can't just pass %sp to _dl_start. That's \
328 okay, argv-4 will do just fine. \
330 The pleasant part of this is that if we need to skip \
331 arguments we can just decrement argc and move argv, because \
332 the stack pointer is utterly unrelated to the location of \
333 the environment and argument vectors. */ \
335 /* This is always within range so we'll be okay. */ \
336 " bl _dl_start,%rp\n" \
337 " ldo -4(%r24),%r26\n" \
339 " .globl _dl_start_user\n" \
340 " .type _dl_start_user,@function\n" \
341 "_dl_start_user:\n" \
342 /* Save the entry point in %r3. */ \
343 " copy %ret0,%r3\n" \
345 /* Remember the lowest stack address. */ \
346 " addil LT'__libc_stack_end,%r19\n" \
347 " ldw RT'__libc_stack_end(%r1),%r20\n" \
348 " stw %sp,0(%r20)\n" \
350 /* See if we were called as a command with the executable file \
351 name as an extra leading argument. */ \
352 " addil LT'_dl_skip_args,%r19\n" \
353 " ldw RT'_dl_skip_args(%r1),%r20\n" \
354 " ldw 0(%r20),%r20\n" \
356 " ldw -40(%sp),%r25\n" /* argc */ \
357 " comib,= 0,%r20,.Lnofix\n" /* FIXME: will be mispredicted */ \
358 " ldw -44(%sp),%r24\n" /* argv (delay slot) */ \
360 " sub %r25,%r20,%r25\n" \
361 " stw %r25,-40(%sp)\n" \
362 " sh2add %r20,%r24,%r24\n" \
363 " stw %r24,-44(%sp)\n" \
366 " addil LT'_rtld_local,%r19\n" \
367 " ldw RT'_rtld_local(%r1),%r26\n" \
368 " bl set_dp, %r2\n" \
369 " ldw 0(%r26),%r26\n" \
371 /* Call _dl_init(_dl_loaded, argc, argv, envp). */ \
372 " copy %r28,%r26\n" \
374 /* envp = argv + argc + 1 */ \
375 " sh2add %r25,%r24,%r23\n" \
376 " bl _dl_init_internal,%r2\n" \
377 " ldo 4(%r23),%r23\n" /* delay slot */ \
379 /* Reload argc, argv to the registers start.S expects them in (feh) */ \
380 " ldw -40(%sp),%r25\n" \
381 " ldw -44(%sp),%r24\n" \
383 /* _dl_fini does have a PLT slot now. I don't know how to get \
384 to it though, so this hack will remain. */ \
385 " .section .data\n" \
386 "__dl_fini_plabel:\n" \
387 " .word _dl_fini\n" \
388 " .word 0xdeadbeef\n" \
391 /* %r3 contains a function pointer, we need to mask out the lower \
392 * bits and load the gp and jump address. */ \
393 " depi 0,31,2,%r3\n" \
394 " ldw 0(%r3),%r2\n" \
395 " addil LT'__dl_fini_plabel,%r19\n" \
396 " ldw RT'__dl_fini_plabel(%r1),%r23\n" \
397 " stw %r19,4(%r23)\n" \
398 " ldw 4(%r3),%r19\n" /* load the object's gp */ \
400 " depi 2,31,2,%r23\n" /* delay slot */ \
404 /* This code gets called via the .plt stub, and is used in
405 dl-runtime.c to call the `fixup' function and then redirect to the
407 Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */
408 #define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
409 extern void tramp_name (void); \
411 /* Trampoline for " #tramp_name " */ \n\
412 .globl " #tramp_name " \n\
413 .type " #tramp_name ",@function \n\
415 /* Save return pointer */ \n\
417 /* Save argument registers in the call stack frame. */ \n\
418 stw %r26,-36(%sp) \n\
419 stw %r25,-40(%sp) \n\
420 stw %r24,-44(%sp) \n\
421 stw %r23,-48(%sp) \n\
422 /* Build a call frame. */ \n\
425 /* Set up args to fixup func. */ \n\
426 ldw 8+4(%r20),%r26 /* got[1] == struct link_map * */ \n\
427 copy %r19,%r25 /* reloc offset */ \n\
429 /* Call the real address resolver. */ \n\
430 bl " #fixup_name ",%r2 \n\
431 copy %r21,%r19 /* delay slot, set fixup func ltp */ \n\
433 ldwm -64(%sp),%sp \n\
435 ldw -36(%sp),%r26 \n\
436 ldw -40(%sp),%r25 \n\
437 ldw -44(%sp),%r24 \n\
438 ldw -48(%sp),%r23 \n\
439 /* Return pointer. */ \n\
441 /* Call the real function. */ \n\
448 #define ELF_MACHINE_RUNTIME_TRAMPOLINE \
449 TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
450 TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
452 #define ELF_MACHINE_RUNTIME_TRAMPOLINE \
453 TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
454 strong_alias (_dl_runtime_resolve, _dl_runtime_profile);
458 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
459 PLT entries should not be allowed to define the value.
460 ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
461 of the main executable's symbols, as for a COPY reloc. */
462 #define elf_machine_type_class(type) \
463 ((((type) == R_PARISC_IPLT || (type) == R_PARISC_EPLT) \
464 * ELF_RTYPE_CLASS_PLT) \
465 | (((type) == R_PARISC_COPY) * ELF_RTYPE_CLASS_COPY))
467 /* Used by ld.so for ... something ... */
468 #define ELF_MACHINE_JMP_SLOT R_PARISC_IPLT
470 /* We only use RELA. */
471 #define ELF_MACHINE_NO_REL 1
473 /* Return the address of the entry point. */
474 #define ELF_MACHINE_START_ADDRESS(map, start) \
475 DL_FUNCTION_ADDRESS (map, start)
477 #endif /* !dl_machine_h */
479 /* These are only actually used where RESOLVE_MAP is defined, anyway. */
483 elf_machine_rela (struct link_map
*map
, const Elf32_Rela
*reloc
,
484 const Elf32_Sym
*sym
, const struct r_found_version
*version
,
485 void *const reloc_addr_arg
)
487 Elf32_Addr
*const reloc_addr
= reloc_addr_arg
;
488 const Elf32_Sym
*const refsym
= sym
;
489 unsigned long const r_type
= ELF32_R_TYPE (reloc
->r_info
);
490 struct link_map
*sym_map
;
493 #if !defined RTLD_BOOTSTRAP && !defined SHARED
494 /* This is defined in rtld.c, but nowhere in the static libc.a; make the
495 reference weak so static programs can still link. This declaration
496 cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
497 because rtld.c contains the common defn for _dl_rtld_map, which is
498 incompatible with a weak decl in the same file. */
499 weak_extern (GL(dl_rtld_map
));
502 /* RESOLVE_MAP will return a null value for undefined syms, and
503 non-null for all other syms. In particular, relocs with no
504 symbol (symbol index of zero), also called *ABS* relocs, will be
505 resolved to MAP. (The first entry in a symbol table is all
506 zeros, and an all zero Elf32_Sym has a binding of STB_LOCAL.)
507 See RESOLVE_MAP definition in elf/dl-reloc.c */
508 #ifdef RTLD_BOOTSTRAP
509 /* RESOLVE_MAP in rtld.c doesn't have the local sym test. */
510 sym_map
= (ELF32_ST_BIND (sym
->st_info
) != STB_LOCAL
511 ? RESOLVE_MAP (&sym
, version
, r_type
) : map
);
513 sym_map
= RESOLVE_MAP (&sym
, version
, r_type
);
517 value
= sym
? sym_map
->l_addr
+ sym
->st_value
: 0;
518 value
+= reloc
->r_addend
;
526 #ifndef RTLD_BOOTSTRAP
527 /* All hell breaks loose if we try to relocate these twice,
528 because any initialized variables in ld.so that refer to
529 other ones will have their values reset. In particular,
530 __fptr_next will be reset, sometimes causing endless loops in
531 __hppa_make_fptr(). So don't do that. */
532 if (map
== &GL(dl_rtld_map
))
535 /* .eh_frame can have unaligned relocs. */
536 if ((unsigned long) reloc_addr_arg
& 3)
538 char *rel_addr
= (char *) reloc_addr_arg
;
539 rel_addr
[0] = value
>> 24;
540 rel_addr
[1] = value
>> 16;
541 rel_addr
[2] = value
>> 8;
547 case R_PARISC_PLABEL32
:
548 /* Easy rule: If there is a symbol and it is global, then we
549 need to make a dynamic function descriptor. Otherwise we
550 have the address of a PLT slot for a local symbol which we
551 know to be unique. */
554 || ELF32_ST_BIND (sym
->st_info
) == STB_LOCAL
)
557 /* Okay, we need to make ourselves a PLABEL then. See the IA64
558 code for an explanation of how this works. */
559 #ifndef RTLD_BOOTSTRAP
560 value
= __hppa_make_fptr (sym_map
, value
, &__fptr_root
, NULL
);
563 struct hppa_fptr
*p_boot_ldso_fptr
;
564 struct hppa_fptr
**p_fptr_root
;
568 /* Go from the top of __boot_ldso_fptr. As on IA64, we
569 probably haven't relocated the necessary values by this
570 point so we have to find them ourselves. */
574 0: addil L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0 \n\
575 ldo R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1 \n\
576 addil L'__fptr_root - ($PIC_pcrel$0 - 16),%0 \n\
577 ldo R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2 \n\
578 addil L'__fptr_count - ($PIC_pcrel$0 - 24),%0 \n\
579 ldo R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
582 "=r" (p_boot_ldso_fptr
),
584 "=r" (p_fptr_count
));
586 value
= __hppa_make_fptr (sym_map
, value
, p_fptr_root
,
587 &p_boot_ldso_fptr
[--*p_fptr_count
]);
593 if (__builtin_expect (sym_map
!= NULL
, 1))
594 elf_machine_fixup_plt (NULL
, sym_map
, reloc
, reloc_addr
, value
);
597 /* If we get here, it's a (weak) undefined sym. */
598 elf_machine_fixup_plt (NULL
, map
, reloc
, reloc_addr
, value
);
603 if (__builtin_expect (sym
== NULL
, 0))
604 /* This can happen in trace mode if an object could not be
607 if (__builtin_expect (sym
->st_size
> refsym
->st_size
, 0)
608 || (__builtin_expect (sym
->st_size
< refsym
->st_size
, 0)
609 && __builtin_expect (GL(dl_verbose
), 0)))
613 strtab
= (const char *) D_PTR (map
, l_info
[DT_STRTAB
]);
615 %s: Symbol `%s' has different size in shared object, consider re-linking\n",
616 rtld_progname
?: "<program name unknown>",
617 strtab
+ refsym
->st_name
);
619 memcpy (reloc_addr_arg
, (void *) value
,
620 MIN (sym
->st_size
, refsym
->st_size
));
623 case R_PARISC_NONE
: /* Alright, Wilbur. */
627 _dl_reloc_bad_type (map
, r_type
, 0);
633 #define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \
634 elf_machine_rel_relative (map, l_addr, relative, \
635 (void *) (l_addr + relative->r_offset))
637 /* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with
638 ELF32_R_SYM (info) == 0 for a similar purpose. */
640 elf_machine_rela_relative (struct link_map
*map
, Elf32_Addr l_addr
,
641 const Elf32_Rela
*reloc
,
642 void *const reloc_addr_arg
)
644 Elf32_Addr
*const reloc_addr
= reloc_addr_arg
;
645 unsigned long const r_type
= ELF32_R_TYPE (reloc
->r_info
);
648 value
= l_addr
+ reloc
->r_addend
;
650 if (ELF32_R_SYM (reloc
->r_info
) != 0)
651 asm volatile ("iitlbp %r0,(%r0)"); /* Crash. */
656 /* .eh_frame can have unaligned relocs. */
657 if ((unsigned long) reloc_addr_arg
& 3)
659 char *rel_addr
= (char *) reloc_addr_arg
;
660 rel_addr
[0] = value
>> 24;
661 rel_addr
[1] = value
>> 16;
662 rel_addr
[2] = value
>> 8;
668 case R_PARISC_PLABEL32
:
672 elf_machine_fixup_plt (NULL
, map
, reloc
, reloc_addr
, value
);
679 _dl_reloc_bad_type (map
, r_type
, 0);
686 elf_machine_lazy_rel (struct link_map
*map
,
687 Elf32_Addr l_addr
, const Elf32_Rela
*reloc
)
689 /* We don't have anything to do here. elf_machine_runtime_setup has
690 done all the relocs already. */
693 #endif /* RESOLVE_MAP */