Clear the exception flags, not the enable flags.
[kopensolaris-gnu/glibc.git] / sysdeps / hppa / dl-machine.h
1 /* Machine-dependent ELF dynamic relocation inline functions.  PA-RISC version.
2    Copyright (C) 1995,1996,1997,1999,2000,2001 Free Software Foundation, Inc.
3    Contributed by David Huggins-Daines <dhd@debian.org>
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If
18    not, write to the Free Software Foundation, Inc.,
19    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #ifndef dl_machine_h
22 #define dl_machine_h 1
23
24 #define ELF_MACHINE_NAME "hppa"
25
26 #include <sys/param.h>
27 #include <string.h>
28 #include <link.h>
29 #include <assert.h>
30
31 /* These must match the definition of the stub in bfd/elf32-hppa.c. */
32 #define SIZEOF_PLT_STUB (4*4)
33 #define GOT_FROM_PLT_STUB (4*4)
34
35 /* A PLABEL is a function descriptor.  Properly they consist of just
36    FUNC and GP.  But we want to traverse a binary tree too.  See
37    dl-fptr.c for the code (it may be made common between HPPA and
38    IA-64 in the future).
39
40    We call these 'fptr' to make it easier to steal code from IA-64. */
41
42 /* ld.so currently has 12 PLABEL32 relocs.  We'll keep this constant
43    large for now in case we require more, as the rest of these will be
44    used by the dynamic program itself (libc.so has quite a few
45    PLABEL32 relocs in it). */
46 #define HPPA_BOOT_FPTR_SIZE     256
47
48 struct hppa_fptr
49 {
50   Elf32_Addr func;
51   Elf32_Addr gp;
52   struct hppa_fptr *next;
53 };
54
55 extern struct hppa_fptr __boot_ldso_fptr[];
56 extern struct hppa_fptr *__fptr_root;
57 extern int __fptr_count;
58
59 extern Elf32_Addr __hppa_make_fptr (const struct link_map *, Elf32_Addr,
60                                     struct hppa_fptr **, struct hppa_fptr *);
61
62 /* Return nonzero iff ELF header is compatible with the running host.  */
63 static inline int
64 elf_machine_matches_host (const Elf32_Ehdr *ehdr)
65 {
66   return ehdr->e_machine == EM_PARISC;
67 }
68
69
70 /* Return the link-time address of _DYNAMIC.  */
71 static inline Elf32_Addr
72 elf_machine_dynamic (void)
73 {
74   Elf32_Addr dynamic;
75
76 #if 0
77   /* Use this method if GOT address not yet set up.  */
78   asm ("\
79         b,l     1f,%0
80         depi    0,31,2,%0
81 1:      addil   L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0
82         ldw     R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0"
83       : "=r" (dynamic) : : "r1");
84 #else
85   /* This works because we already have our GOT address available.  */
86   dynamic = (Elf32_Addr) &_DYNAMIC;
87 #endif
88
89   return dynamic;
90 }
91
92 /* Return the run-time load address of the shared object.  */
93 static inline Elf32_Addr
94 elf_machine_load_address (void)
95 {
96   Elf32_Addr dynamic, dynamic_linkaddress;
97
98   asm ("\
99         b,l     1f,%0
100         depi    0,31,2,%0
101 1:      addil   L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0
102         ldo     R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%1
103         addil   L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%0
104         ldw     R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%%r1),%0"
105    : "=r" (dynamic_linkaddress), "=r" (dynamic) : : "r1");
106
107   return dynamic - dynamic_linkaddress;
108 }
109
110 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
111 static inline Elf32_Addr
112 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
113                        const Elf32_Rela *reloc,
114                        Elf32_Addr *reloc_addr, Elf32_Addr value)
115 {
116   /* l is the link_map for the caller, t is the link_map for the object
117    * being called */
118   reloc_addr[1] = D_PTR (t, l_info[DT_PLTGOT]);
119   reloc_addr[0] = value;
120   /* Return the PLT slot rather than the function value so that the
121      trampoline can load the new LTP. */
122   return (Elf32_Addr) reloc_addr;
123 }
124
125 /* Return the final value of a plt relocation.  */
126 static inline Elf32_Addr
127 elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
128                        Elf32_Addr value)
129 {
130   /* We are rela only */
131   return value + reloc->r_addend;
132 }
133
134 /* Set up the loaded object described by L so its unrelocated PLT
135    entries will jump to the on-demand fixup code in dl-runtime.c.  */
136
137 static inline int
138 elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
139 {
140   extern void _dl_runtime_resolve (void);
141   extern void _dl_runtime_profile (void);
142   Elf32_Addr jmprel = D_PTR(l, l_info[DT_JMPREL]);
143
144   if (lazy && jmprel)
145     {
146       Elf32_Addr *got = NULL;
147       Elf32_Addr l_addr;
148       Elf32_Addr end_jmprel;
149       Elf32_Addr iplt;
150
151       /* Relocate all the PLT slots.  */
152       l_addr = l->l_addr;
153       end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
154       for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela))
155         {
156           const Elf32_Rela *reloc;
157           Elf32_Word r_type;
158           Elf32_Word r_sym;
159           struct hppa_fptr *fptr;
160
161           reloc = (const Elf32_Rela *) iplt;
162           r_type = ELF32_R_TYPE (reloc->r_info);
163           r_sym = ELF32_R_SYM (reloc->r_info);
164
165           if (__builtin_expect (r_type == R_PARISC_IPLT, 1))
166             {
167               fptr = (struct hppa_fptr *) (reloc->r_offset + l_addr);
168               if (r_sym != 0)
169                 {
170                   /* Relocate the pointer to the stub.  */
171                   fptr->func += l_addr;
172                   /* Instead of the LTP value, we put the reloc offset
173                      here.  The trampoline code will load the proper
174                      LTP and pass the reloc offset to the fixup
175                      function.  */
176                   fptr->gp = iplt - jmprel;
177                   if (!got)
178                     {
179                       static union {
180                         unsigned char c[8];
181                         Elf32_Addr i[2];
182                       } sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
183
184                       /* Find our .got section.  It's right after the
185                          stub.  */
186                       got = (Elf32_Addr *) (fptr->func + GOT_FROM_PLT_STUB);
187
188                       /* Sanity check to see if the address we are
189                          going to check below is within a reasonable
190                          approximation of the bounds of the PLT (or,
191                          at least, is at an address that won't fault
192                          on read).  Then check for the magic signature
193                          above. */
194                       if (fptr->func < (Elf32_Addr) fptr + sizeof(*fptr))
195                           return 0;
196                       if (fptr->func >
197                           ((Elf32_Addr) fptr
198                            + SIZEOF_PLT_STUB
199                            + ((l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeof (Elf32_Rela))
200                               * 8)))
201                         return 0;
202                       if (got[-2] != sig.i[0] || got[-1] != sig.i[1])
203                         return 0; /* No lazy linking for you! */
204                     }
205                 }
206               else
207                 {
208                   /* Relocate this *ABS* entry.  */
209                   fptr->func = reloc->r_addend + l_addr;
210                   fptr->gp = D_PTR (l, l_info[DT_PLTGOT]);
211                 }
212             }
213           else if (__builtin_expect (r_type != R_PARISC_NONE, 0))
214             _dl_reloc_bad_type (l, r_type, 1);
215         }
216
217       if (got)
218         {
219           register Elf32_Addr ltp __asm__ ("%r19");
220           /* Identify this shared object. */
221           got[1] = (Elf32_Addr) l;
222
223           /* This function will be called to perform the relocation. */
224           if (__builtin_expect (!profile, 1))
225             got[-2] =
226               (Elf32_Addr) ((struct hppa_fptr *)
227                             ((unsigned long) &_dl_runtime_resolve & ~3))->func;
228           else
229             {
230               if (_dl_name_match_p (_dl_profile, l))
231                 {
232                   /* This is the object we are looking for.  Say that
233                      we really want profiling and the timers are
234                      started.  */
235                   _dl_profile_map = l;
236                 }
237               got[-2] =
238                 (Elf32_Addr) ((struct hppa_fptr *)
239                               ((unsigned long) &_dl_runtime_profile & ~3))->func;
240             }
241           got[-1] = ltp;
242         }
243     }
244   return lazy;
245 }
246
247 /* Initial entry point code for the dynamic linker.
248    The C function `_dl_start' is the real entry point;
249    its return value is the user program's entry point.  */
250
251 #define RTLD_START \
252 /* Set up dp for any non-PIC lib constructors that may be called.  */   \
253 static struct link_map * set_dp (struct link_map *map)          \
254 {                                                               \
255   register Elf32_Addr dp asm ("%r27");                          \
256   dp = D_PTR (map, l_info[DT_PLTGOT]);                          \
257   asm volatile ("" : : "r" (dp));                               \
258   return map;                                                   \
259 }                                                               \
260                                                                 \
261 asm ("\
262         .text
263         .globl _start
264         .type _start,@function
265 _start:
266         /* The kernel does not give us an initial stack frame. */
267         ldo     64(%sp),%sp
268         /* Save the relevant arguments (yes, those are the correct
269            registers, the kernel is weird) in their stack slots. */
270         stw     %r25,-40(%sp) /* argc */
271         stw     %r24,-44(%sp) /* argv */
272
273         /* We need the LTP, and we need it now. */
274         /* $PIC_pcrel$0 points 8 bytes past the current instruction,
275            just like a branch reloc.  This sequence gets us the runtime
276            address of _DYNAMIC. */
277         bl      0f,%r19
278         depi    0,31,2,%r19     /* clear priviledge bits */
279 0:      addil   L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19
280         ldo     R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26
281
282         /* Also get the link time address from the first entry of the GOT.  */
283         addil   L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19
284         ldw     R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20
285
286         sub     %r26,%r20,%r20  /* Calculate load offset */
287
288         /* Rummage through the dynamic entries, looking for DT_PLTGOT.  */
289         ldw,ma  8(%r26),%r19
290 1:      cmpib,=,n 3,%r19,2f     /* tag == DT_PLTGOT? */
291         cmpib,<>,n 0,%r19,1b
292         ldw,ma  8(%r26),%r19
293
294         /* Uh oh!  We didn't find one.  Abort. */
295         iitlbp  %r0,(%r0)
296
297 2:      ldw     -4(%r26),%r19   /* Found it, load value. */
298         add     %r19,%r20,%r19  /* And add the load offset. */
299
300         /* Our initial stack layout is rather different from everyone
301            else's due to the unique PA-RISC ABI.  As far as I know it
302            looks like this:
303
304            -----------------------------------  (this frame created above)
305            |         32 bytes of magic       |
306            |---------------------------------|
307            | 32 bytes argument/sp save area  |
308            |---------------------------------|  ((current->mm->env_end) + 63 & ~63)
309            |         N bytes of slack        |
310            |---------------------------------|
311            |      envvar and arg strings     |
312            |---------------------------------|
313            |        ELF auxiliary info       |
314            |         (up to 28 words)        |
315            |---------------------------------|
316            |  Environment variable pointers  |
317            |         upwards to NULL         |
318            |---------------------------------|
319            |        Argument pointers        |
320            |         upwards to NULL         |
321            |---------------------------------|
322            |          argc (1 word)          |
323            -----------------------------------
324
325           So, obviously, we can't just pass %sp to _dl_start.  That's
326           okay, argv-4 will do just fine.
327
328           The pleasant part of this is that if we need to skip
329           arguments we can just decrement argc and move argv, because
330           the stack pointer is utterly unrelated to the location of
331           the environment and argument vectors. */
332
333         /* This is always within range so we'll be okay. */
334         bl      _dl_start,%rp
335         ldo     -4(%r24),%r26
336
337         .globl _dl_start_user
338         .type _dl_start_user,@function
339 _dl_start_user:
340         /* Save the entry point in %r3. */
341         copy    %ret0,%r3
342
343         /* Remember the lowest stack address. */
344         addil   LT'__libc_stack_end,%r19
345         ldw     RT'__libc_stack_end(%r1),%r20
346         stw     %sp,0(%r20)
347
348         /* See if we were called as a command with the executable file
349            name as an extra leading argument. */
350         addil   LT'_dl_skip_args,%r19
351         ldw     RT'_dl_skip_args(%r1),%r20
352         ldw     0(%r20),%r20
353
354         ldw     -40(%sp),%r25   /* argc */
355         comib,= 0,%r20,.Lnofix  /* FIXME: will be mispredicted */
356         ldw     -44(%sp),%r24   /* argv (delay slot) */
357
358         sub     %r25,%r20,%r25
359         stw     %r25,-40(%sp)
360         sh2add  %r20,%r24,%r24
361         stw     %r24,-44(%sp)
362
363 .Lnofix:
364         addil   LT'_dl_loaded,%r19
365         ldw     RT'_dl_loaded(%r1),%r26
366         bl      set_dp, %r2
367         ldw     0(%r26),%r26
368
369         /* Call _dl_init(_dl_loaded, argc, argv, envp). */
370         copy    %r28,%r26
371
372         /* envp = argv + argc + 1 */
373         sh2add  %r25,%r24,%r23
374         bl      _dl_init,%r2
375         ldo     4(%r23),%r23    /* delay slot */
376
377         /* Reload argc, argv  to the registers start.S expects them in (feh) */
378         ldw     -40(%sp),%r25
379         ldw     -44(%sp),%r24
380
381         /* _dl_fini does have a PLT slot now.  I don't know how to get
382            to it though, so this hack will remain. */
383         .section .data
384 __dl_fini_plabel:
385         .word   _dl_fini
386         .word   0xdeadbeef
387         .previous
388
389         /* %r3 contains a function pointer, we need to mask out the lower
390          * bits and load the gp and jump address. */
391         depi    0,31,2,%r3
392         ldw     0(%r3),%r2
393         addil   LT'__dl_fini_plabel,%r19
394         ldw     RT'__dl_fini_plabel(%r1),%r23
395         stw     %r19,4(%r23)
396         ldw     4(%r3),%r19     /* load the object's gp */
397         bv      %r0(%r2)
398         depi    2,31,2,%r23     /* delay slot */
399 ");
400
401
402 /* This code gets called via the .plt stub, and is used in
403    dl-runtime.c to call the `fixup' function and then redirect to the
404    address it returns.
405    Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp.  */
406 #define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
407   extern void tramp_name (void);                    \
408   asm ( "\
409         /* Trampoline for " #tramp_name " */
410         .globl " #tramp_name "
411         .type " #tramp_name ",@function
412 " #tramp_name ":
413         /* Save return pointer */
414         stw     %r2,-20(%sp)
415         /* Save argument registers in the call stack frame. */
416         stw     %r26,-36(%sp)
417         stw     %r25,-40(%sp)
418         stw     %r24,-44(%sp)
419         stw     %r23,-48(%sp)
420         /* Build a call frame. */
421         stwm    %sp,64(%sp)
422
423         /* Set up args to fixup func.  */
424         ldw     8+4(%r20),%r26  /* got[1] == struct link_map *  */
425         copy    %r19,%r25       /* reloc offset  */
426
427         /* Call the real address resolver. */
428         bl      " #fixup_name ",%r2
429         copy    %r21,%r19       /* delay slot, set fixup func ltp */
430
431         ldwm    -64(%sp),%sp
432         /* Arguments. */
433         ldw     -36(%sp),%r26
434         ldw     -40(%sp),%r25
435         ldw     -44(%sp),%r24
436         ldw     -48(%sp),%r23
437         /* Return pointer. */
438         ldw     -20(%sp),%r2
439         /* Call the real function. */
440         ldw     0(%r28),%r22
441         bv      %r0(%r22)
442         ldw     4(%r28),%r19
443 ");
444
445 #ifndef PROF
446 #define ELF_MACHINE_RUNTIME_TRAMPOLINE                  \
447   TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);     \
448   TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
449 #else
450 #define ELF_MACHINE_RUNTIME_TRAMPOLINE                  \
451   TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);     \
452   strong_alias (_dl_runtime_resolve, _dl_runtime_profile);
453 #endif
454
455
456 /* Nonzero iff TYPE describes a relocation that should
457    skip the executable when looking up the symbol value.  */
458 #define elf_machine_lookup_noexec_p(type) ((type) == R_PARISC_COPY)
459
460 /* Nonzero iff TYPE describes relocation of a PLT entry, so
461    PLT entries should not be allowed to define the value.  */
462 #define elf_machine_lookup_noplt_p(type) ((type) == R_PARISC_IPLT \
463                                           || (type) == R_PARISC_EPLT)
464
465 /* Used by ld.so for ... something ... */
466 #define ELF_MACHINE_JMP_SLOT R_PARISC_IPLT
467
468 /* We only use RELA. */
469 #define ELF_MACHINE_NO_REL 1
470
471 /* Return the address of the entry point. */
472 #define ELF_MACHINE_START_ADDRESS(map, start) \
473   DL_FUNCTION_ADDRESS (map, start)
474
475 #endif /* !dl_machine_h */
476
477 /* These are only actually used where RESOLVE_MAP is defined, anyway. */
478 #ifdef RESOLVE_MAP
479
480 static inline void
481 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
482                   const Elf32_Sym *sym, const struct r_found_version *version,
483                   Elf32_Addr *const reloc_addr)
484 {
485   const Elf32_Sym *const refsym = sym;
486   unsigned long const r_type = ELF32_R_TYPE (reloc->r_info);
487   struct link_map *sym_map;
488   Elf32_Addr value;
489
490 #ifndef RTLD_BOOTSTRAP
491   /* This is defined in rtld.c, but nowhere in the static libc.a; make the
492      reference weak so static programs can still link.  This declaration
493      cannot be done when compiling rtld.c (i.e.  #ifdef RTLD_BOOTSTRAP)
494      because rtld.c contains the common defn for _dl_rtld_map, which is
495      incompatible with a weak decl in the same file.  */
496   weak_extern (_dl_rtld_map);
497 #endif
498
499   /* RESOLVE_MAP will return a null value for undefined syms, and
500      non-null for all other syms.  In particular, relocs with no
501      symbol (symbol index of zero), also called *ABS* relocs, will be
502      resolved to MAP.  (The first entry in a symbol table is all
503      zeros, and an all zero Elf32_Sym has a binding of STB_LOCAL.)
504      See RESOLVE_MAP definition in elf/dl-reloc.c  */
505 #ifdef RTLD_BOOTSTRAP
506   /* RESOLVE_MAP in rtld.c doesn't have the local sym test.  */
507   sym_map = (ELF32_ST_BIND (sym->st_info) != STB_LOCAL
508              ? RESOLVE_MAP (&sym, version, r_type) : map);
509 #else
510   sym_map = RESOLVE_MAP (&sym, version, r_type);
511 #endif
512   if (sym_map)
513     {
514       value = sym ? sym_map->l_addr + sym->st_value : 0;
515       value += reloc->r_addend;
516     }
517   else
518     value = 0;
519
520   switch (r_type)
521     {
522     case R_PARISC_DIR32:
523 #ifndef RTLD_BOOTSTRAP
524       /* All hell breaks loose if we try to relocate these twice,
525          because any initialized variables in ld.so that refer to
526          other ones will have their values reset.  In particular,
527          __fptr_next will be reset, sometimes causing endless loops in
528          __hppa_make_fptr().  So don't do that. */
529       if (map == &_dl_rtld_map)
530         return;
531 #endif
532       /* Otherwise, nothing more to do here. */
533       break;
534
535     case R_PARISC_PLABEL32:
536       /* Easy rule: If there is a symbol and it is global, then we
537          need to make a dynamic function descriptor.  Otherwise we
538          have the address of a PLT slot for a local symbol which we
539          know to be unique. */
540       if (sym == NULL
541           || sym_map == NULL
542           || ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
543         break;
544
545       /* Okay, we need to make ourselves a PLABEL then.  See the IA64
546          code for an explanation of how this works.  */
547 #ifndef RTLD_BOOTSTRAP
548       value = __hppa_make_fptr (sym_map, value, &__fptr_root, NULL);
549 #else
550       {
551         struct hppa_fptr *p_boot_ldso_fptr;
552         struct hppa_fptr **p_fptr_root;
553         int *p_fptr_count;
554         unsigned long dot;
555
556         /* Go from the top of __boot_ldso_fptr.  As on IA64, we
557            probably haven't relocated the necessary values by this
558            point so we have to find them ourselves. */
559
560         asm ("bl        0f,%0
561               depi      0,31,2,%0
562 0:            addil     L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0
563               ldo       R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1
564               addil     L'__fptr_root - ($PIC_pcrel$0 - 16),%0
565               ldo       R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2
566               addil     L'__fptr_count - ($PIC_pcrel$0 - 24),%0
567               ldo       R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
568              :
569              "=r" (dot),
570              "=r" (p_boot_ldso_fptr),
571              "=r" (p_fptr_root),
572              "=r" (p_fptr_count));
573
574         value = __hppa_make_fptr (sym_map, value, p_fptr_root,
575                                   &p_boot_ldso_fptr[--*p_fptr_count]);
576       }
577 #endif
578       break;
579
580     case R_PARISC_IPLT:
581       if (__builtin_expect (sym_map != NULL, 1))
582         elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value);
583       else
584         {
585           /* If we get here, it's a (weak) undefined sym.  */
586           elf_machine_fixup_plt (NULL, map, reloc, reloc_addr, value);
587         }
588       return;
589
590     case R_PARISC_COPY:
591       if (__builtin_expect (sym == NULL, 0))
592         /* This can happen in trace mode if an object could not be
593            found.  */
594         break;
595       if (__builtin_expect (sym->st_size > refsym->st_size, 0)
596           || (__builtin_expect (sym->st_size < refsym->st_size, 0)
597               && __builtin_expect (_dl_verbose, 0)))
598         {
599           const char *strtab;
600
601           strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
602           _dl_error_printf ("\
603 %s: Symbol `%s' has different size in shared object, consider re-linking\n",
604                             _dl_argv[0] ?: "<program name unknown>",
605                             strtab + refsym->st_name);
606         }
607       memcpy (reloc_addr, (void *) value,
608               MIN (sym->st_size, refsym->st_size));
609       return;
610
611     case R_PARISC_NONE: /* Alright, Wilbur. */
612       return;
613
614     default:
615       _dl_reloc_bad_type (map, r_type, 0);
616     }
617
618   *reloc_addr = value;
619 }
620
621 static inline void
622 elf_machine_lazy_rel (struct link_map *map,
623                       Elf32_Addr l_addr, const Elf32_Rela *reloc)
624 {
625   /* We don't have anything to do here.  elf_machine_runtime_setup has
626      done all the relocs already.  */
627 }
628
629 #endif /* RESOLVE_MAP */