OSDN Git Service

Revert to scope as used by original code for now, just in case.
[uclinux-h8/uClibc.git] / ldso / ldso / powerpc / elfinterp.c
1 /* vi: set sw=4 ts=4: */
2 /* powerpc shared library loader suppport
3  *
4  * Copyright (C) 2001-2002 David A. Schleef
5  * Copyright (C) 2003-2004 Erik Andersen
6  * Copyright (C) 2004 Joakim Tjernlund
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. The name of the above contributors may not be
16  *    used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #if defined (__SUPPORT_LD_DEBUG__)
33 static const char *_dl_reltypes_tab[] =
34         { "R_PPC_NONE", "R_PPC_ADDR32", "R_PPC_ADDR24", "R_PPC_ADDR16",
35         "R_PPC_ADDR16_LO", "R_PPC_ADDR16_HI", "R_PPC_ADDR16_HA",
36         "R_PPC_ADDR14", "R_PPC_ADDR14_BRTAKEN", "R_PPC_ADDR14_BRNTAKEN",
37         "R_PPC_REL24", "R_PPC_REL14", "R_PPC_REL14_BRTAKEN",
38         "R_PPC_REL14_BRNTAKEN", "R_PPC_GOT16", "R_PPC_GOT16_LO",
39         "R_PPC_GOT16_HI", "R_PPC_GOT16_HA", "R_PPC_PLTREL24",
40         "R_PPC_COPY", "R_PPC_GLOB_DAT", "R_PPC_JMP_SLOT", "R_PPC_RELATIVE",
41         "R_PPC_LOCAL24PC", "R_PPC_UADDR32", "R_PPC_UADDR16", "R_PPC_REL32",
42         "R_PPC_PLT32", "R_PPC_PLTREL32", "R_PPC_PLT16_LO", "R_PPC_PLT16_HI",
43         "R_PPC_PLT16_HA", "R_PPC_SDAREL16", "R_PPC_SECTOFF",
44         "R_PPC_SECTOFF_LO", "R_PPC_SECTOFF_HI", "R_PPC_SECTOFF_HA",
45 };
46
47 static const char *
48 _dl_reltypes(int type)
49 {
50   static char buf[22];
51   const char *str;
52
53   if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
54       NULL == (str = _dl_reltypes_tab[type]))
55   {
56     str =_dl_simple_ltoa( buf, (unsigned long)(type));
57   }
58   return str;
59 }
60
61 static
62 void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
63 {
64   if(_dl_debug_symbols)
65   {
66     if(symtab_index){
67       _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
68                   strtab + symtab[symtab_index].st_name,
69                   symtab[symtab_index].st_value,
70                   symtab[symtab_index].st_size,
71                   symtab[symtab_index].st_info,
72                   symtab[symtab_index].st_other,
73                   symtab[symtab_index].st_shndx);
74     }
75   }
76 }
77
78 static
79 void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
80 {
81   if(_dl_debug_reloc)
82   {
83     int symtab_index;
84     const char *sym;
85     symtab_index = ELF32_R_SYM(rpnt->r_info);
86     sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
87
88   if(_dl_debug_symbols)
89           _dl_dprintf(_dl_debug_file, "\n\t");
90   else
91           _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
92 #ifdef ELF_USES_RELOCA
93     _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
94                 _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
95                 rpnt->r_offset,
96                 rpnt->r_addend);
97 #else
98     _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
99                 _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
100                 rpnt->r_offset);
101 #endif
102   }
103 }
104 #endif
105
106 extern int _dl_linux_resolve(void);
107
108 void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
109 {
110         Elf32_Word *tramp;
111         Elf32_Word num_plt_entries;
112         Elf32_Word data_words;
113         Elf32_Word rel_offset_words;
114         Elf32_Word dlrr = (Elf32_Word) _dl_linux_resolve;
115
116         num_plt_entries = tpnt->dynamic_info[DT_PLTRELSZ] / sizeof(ELF_RELOC);
117         rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
118         data_words = (Elf32_Word) (plt + rel_offset_words);
119         tpnt->data_words = data_words;
120
121         plt[PLT_LONGBRANCH_ENTRY_WORDS] = OPCODE_ADDIS_HI(11, 11, data_words);
122         plt[PLT_LONGBRANCH_ENTRY_WORDS+1] = OPCODE_LWZ(11,data_words,11);
123
124         plt[PLT_LONGBRANCH_ENTRY_WORDS+2] = OPCODE_MTCTR(11);
125         plt[PLT_LONGBRANCH_ENTRY_WORDS+3] = OPCODE_BCTR();
126
127         /* [4] */
128         /* [5] */
129         tramp = (Elf32_Word *) (plt + PLT_TRAMPOLINE_ENTRY_WORDS);
130
131         /* For the long entries, subtract off data_words.  */
132         tramp[0] = OPCODE_ADDIS_HI(11,11,-data_words);
133         tramp[1] = OPCODE_ADDI(11,11,-data_words);
134
135         /* Multiply index of entry by 3 (in r11).  */
136         tramp[2] = OPCODE_SLWI(12,11,1);
137         tramp[3] = OPCODE_ADD(11,12,11);
138         if (dlrr <= 0x01fffffc || dlrr >= 0xfe000000) {
139                 /* Load address of link map in r12.  */
140                 tramp[4] = OPCODE_LI (12, (Elf32_Word) tpnt);
141                 tramp[5] = OPCODE_ADDIS_HI (12, 12, (Elf32_Word) tpnt);
142
143                 /* Call _dl_linux_resolve .  */
144                 tramp[6] = OPCODE_BA (dlrr);
145         } else {
146                 /* Get address of _dl_linux_resolve in CTR.  */
147                 tramp[4] = OPCODE_LI(12,dlrr);
148                 tramp[5] = OPCODE_ADDIS_HI(12,12,dlrr);
149                 tramp[6] = OPCODE_MTCTR(12);
150
151                 /* Load address of link map in r12.  */
152                 tramp[7] = OPCODE_LI(12,(Elf32_Word) tpnt);
153                 tramp[8] = OPCODE_ADDIS_HI(12,12,(Elf32_Word) tpnt);
154
155                 /* Call _dl_linux_resolve.  */
156                 tramp[9] = OPCODE_BCTR();
157         }
158         /* [16] unused */
159         /* [17] unused */
160
161         PPC_DCBST(plt);
162         PPC_DCBST(plt+4);
163         PPC_DCBST(plt+8);
164         PPC_DCBST(plt+12);
165         PPC_DCBST(plt+16-1);
166         PPC_SYNC;
167         PPC_ICBI(plt);
168         PPC_ICBI(plt+16-1);
169         PPC_ISYNC;
170 }
171
172 unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
173 {
174         ELF_RELOC *this_reloc;
175         char *strtab;
176         Elf32_Sym *symtab;
177         ELF_RELOC *rel_addr;
178         int symtab_index;
179         char *symname;
180         Elf32_Addr *reloc_addr;
181         Elf32_Addr  finaladdr;
182         Elf32_Sword delta;
183
184         rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
185
186         this_reloc = (void *)rel_addr + reloc_entry;
187         symtab_index = ELF32_R_SYM(this_reloc->r_info);
188
189         symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
190         strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
191         symname      = strtab + symtab[symtab_index].st_name;
192
193 #if defined (__SUPPORT_LD_DEBUG__)
194         debug_sym(symtab,strtab,symtab_index);
195         debug_reloc(symtab,strtab,this_reloc);
196
197         if (ELF32_R_TYPE(this_reloc->r_info) != R_PPC_JMP_SLOT) {
198                 _dl_dprintf(2, "%s: Incorrect relocation type in jump relocation\n", _dl_progname);
199                 _dl_exit(1);
200         };
201 #endif
202
203         /* Address of dump instruction to fix up */
204         reloc_addr = (Elf32_Addr *) (tpnt->loadaddr + this_reloc->r_offset);
205
206 #if defined (__SUPPORT_LD_DEBUG__)
207         if(_dl_debug_reloc && _dl_debug_detail)
208                 _dl_dprintf(_dl_debug_file, "\n\tResolving symbol %s %x --> ", symname, (Elf32_Addr)reloc_addr);
209 #endif
210
211         /* Get the address of the GOT entry */
212         finaladdr = (Elf32_Addr) _dl_find_hash(strtab + symtab[symtab_index].st_name,
213                                                 tpnt->symbol_scope, tpnt, resolver);
214         if (!finaladdr) {
215                 _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
216                 _dl_exit(1);
217         };
218
219 #if defined (__SUPPORT_LD_DEBUG__)
220         if(_dl_debug_reloc && _dl_debug_detail)
221                 _dl_dprintf(_dl_debug_file, "%x\n", finaladdr);
222 #endif
223         delta = finaladdr - (Elf32_Word)reloc_addr;
224         if (delta<<6>>6 == delta) {
225                 *reloc_addr = OPCODE_B(delta);
226 #if 0
227         /* this will almost never be true */
228         } else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000) {
229                 *reloc_addr = OPCODE_BA (finaladdr);
230 #endif
231         } else {
232                 /* Warning: we don't handle double-sized PLT entries */
233                 Elf32_Word *plt, *data_words, index, offset;
234
235                 plt = (Elf32_Word *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
236                 offset = reloc_addr - plt;
237                 index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
238                 data_words = (Elf32_Word *)tpnt->data_words;
239                 reloc_addr += 1;
240
241                 data_words[index] = finaladdr;
242                 PPC_SYNC;
243                 *reloc_addr =  OPCODE_B ((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
244         }
245
246         /* instructions were modified */
247         PPC_DCBST(reloc_addr);
248         PPC_SYNC;
249         PPC_ICBI(reloc_addr);
250         PPC_ISYNC;
251
252         return finaladdr;
253 }
254
255 static inline int
256 _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
257               ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
258 {
259         int reloc_type;
260         int symtab_index;
261         char *symname;
262         Elf32_Addr *reloc_addr;
263         Elf32_Addr finaladdr;
264         struct dyn_elf *sym_scope;
265
266         unsigned long symbol_addr;
267 #if defined (__SUPPORT_LD_DEBUG__)
268         unsigned long old_val;
269 #endif
270         reloc_addr   = (Elf32_Addr *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
271         reloc_type   = ELF32_R_TYPE(rpnt->r_info);
272         if (reloc_type == R_PPC_RELATIVE) {
273                 *reloc_addr = tpnt->loadaddr + rpnt->r_addend;
274                 return 0;
275         }
276         if (reloc_type == R_PPC_NONE)
277                 return 0;
278         symtab_index = ELF32_R_SYM(rpnt->r_info);
279         symname      = strtab + symtab[symtab_index].st_name;
280
281 #if 1
282         sym_scope = scope->dyn->symbol_scope;
283 #else
284         /* Funny, this works too and appears to be much faster. */
285         sym_scope = scope;
286 #endif
287         if (reloc_type == R_PPC_COPY) {
288                 sym_scope = scope->next;
289                 tpnt = NULL; /* To be or not to be ...*/
290         }
291         symbol_addr = (unsigned long) _dl_find_hash(symname, sym_scope,
292                                                     (reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL),
293                                                     (reloc_type == R_PPC_COPY ? copyrel : symbolrel));
294         /*
295          * We want to allow undefined references to weak symbols - this might
296          * have been intentional.  We should not be linking local symbols
297          * here, so all bases should be covered.
298          */
299         if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
300 #if defined (__SUPPORT_LD_DEBUG__)
301                 _dl_dprintf(2, "\tglobal symbol '%s' already defined in '%s', rel type: %s\n",
302                             symname, tpnt->libname, _dl_reltypes(reloc_type));
303 #endif
304                 return 0;
305         }
306 #if defined (__SUPPORT_LD_DEBUG__)
307         old_val = *reloc_addr;
308 #endif
309         finaladdr = (Elf32_Addr) (symbol_addr + rpnt->r_addend);
310
311         switch (reloc_type) {
312         case R_PPC_ADDR32:
313         case R_PPC_GLOB_DAT:
314                 *reloc_addr = finaladdr;
315                 return 0; /* No code code modified */
316                 break;
317         case R_PPC_JMP_SLOT:
318         {
319                 Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr;
320
321                 if (delta<<6>>6 == delta) {
322                         *reloc_addr = OPCODE_B(delta);
323 #if 0
324                 /* this will almost never be true */
325                 } else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000) {
326                         *reloc_addr = OPCODE_BA (finaladdr);
327 #endif
328                 } else {
329                         /* Warning: we don't handle double-sized PLT entries */
330                         Elf32_Word *plt, *data_words, index, offset;
331
332                         plt = (Elf32_Word *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
333                         offset = reloc_addr - plt;
334                         index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
335                         data_words = (Elf32_Word *)tpnt->data_words;
336
337                         data_words[index] = finaladdr;
338                         reloc_addr[0] = OPCODE_LI(11,index*4);
339                         reloc_addr[1] = OPCODE_B((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
340
341                         /* instructions were modified */
342                         PPC_DCBST(reloc_addr+1);
343                         PPC_SYNC;
344                         PPC_ICBI(reloc_addr+1);
345                 }
346                 break;
347         }
348         case R_PPC_COPY:
349                 if (symbol_addr) {
350 #if defined (__SUPPORT_LD_DEBUG__)
351                         if(_dl_debug_move)
352                                 _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
353                                             symname, symtab[symtab_index].st_size,
354                                             symbol_addr, symtab[symtab_index].st_value);
355 #endif
356                         _dl_memcpy((char *) reloc_addr, (char *) finaladdr, symtab[symtab_index].st_size);
357                 }
358                 return 0; /* No code code modified */
359                 break;
360         case R_PPC_ADDR16_HA:
361                 *(short *)reloc_addr = (finaladdr + 0x8000)>>16;
362                 break;
363         case R_PPC_ADDR16_HI:
364                 *(short *)reloc_addr = finaladdr >> 16;
365                 break;
366         case R_PPC_ADDR16_LO:
367                 *(short *)reloc_addr = finaladdr;
368                 break;
369         case R_PPC_REL24:
370         {
371                 Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr;
372                 if(delta<<6>>6 != delta){
373                         _dl_dprintf(2, "%s: symbol '%s' R_PPC_REL24 is out of range.\n\t"
374                                         "Compile shared libraries with -fPIC!\n",
375                                     _dl_progname, symname);
376                         _dl_exit(1);
377                 }
378                 *reloc_addr = (*reloc_addr & 0xfc000003) | (delta & 0x3fffffc);
379                 break;
380         }
381         default:
382                 _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);
383 #if defined (__SUPPORT_LD_DEBUG__)
384                 _dl_dprintf(2, "%s ", _dl_reltypes(reloc_type));
385 #endif
386                 if (symtab_index)
387                         _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
388                 return -1;
389         };
390
391         /* instructions were modified */
392         PPC_DCBST(reloc_addr);
393         PPC_SYNC;
394         PPC_ICBI(reloc_addr);
395         PPC_ISYNC;
396 #if defined (__SUPPORT_LD_DEBUG__)
397         if(_dl_debug_reloc && _dl_debug_detail)
398                 _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr);
399 #endif
400         return 0;
401 }
402
403 void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
404         unsigned long rel_addr, unsigned long rel_size, int type)
405 {
406         struct elf_resolve *tpnt = rpnt->dyn;
407         Elf32_Word *plt, offset, i,  num_plt_entries, rel_offset_words;
408
409         (void) type;
410         num_plt_entries = rel_size / sizeof(ELF_RELOC);
411
412         /* When the dynamic linker bootstrapped itself, it resolved some symbols.
413            Make sure we do not do them again */
414         if (tpnt->libtype == program_interpreter)
415                 return;
416         rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
417         plt = (Elf32_Word *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
418
419         /* Set up the lazy PLT entries.  */
420         offset = PLT_INITIAL_ENTRY_WORDS;
421         i = 0;
422         /* Warning: we don't handle double-sized PLT entries */
423         while (i < num_plt_entries) {
424                 plt[offset  ] = OPCODE_LI(11, i * 4);
425                 plt[offset+1] = OPCODE_B((PLT_TRAMPOLINE_ENTRY_WORDS + 2 - (offset+1)) * 4);
426                 i++;
427                 offset += 2;
428         }
429         /* Now, we've modified code.  We need to write the changes from
430            the data cache to a second-level unified cache, then make
431            sure that stale data in the instruction cache is removed.
432            (In a multiprocessor system, the effect is more complex.)
433            Most of the PLT shouldn't be in the instruction cache, but
434            there may be a little overlap at the start and the end.
435
436            Assumes that dcbst and icbi apply to lines of 16 bytes or
437            more.  Current known line sizes are 16, 32, and 128 bytes.  */
438         for (i = 0; i < rel_offset_words; i += 4)
439                 PPC_DCBST (plt + i);
440         PPC_DCBST (plt + rel_offset_words - 1);
441         PPC_SYNC;
442         PPC_ICBI (plt);
443         PPC_ICBI (plt + rel_offset_words - 1);
444         PPC_ISYNC;
445 }
446
447 static inline int
448 _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
449           unsigned long rel_addr, unsigned long rel_size,
450           int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
451                             ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
452 {
453         unsigned int i;
454         char *strtab;
455         Elf32_Sym *symtab;
456         ELF_RELOC *rpnt;
457         int symtab_index;
458
459         /* Now parse the relocation information */
460         rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
461         rel_size = rel_size / sizeof(ELF_RELOC);
462
463         symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
464         strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
465
466           for (i = 0; i < rel_size; i++, rpnt++) {
467                 int res;
468
469                 symtab_index = ELF32_R_SYM(rpnt->r_info);
470
471                 /* When the dynamic linker bootstrapped itself, it resolved some symbols.
472                    Make sure we do not do them again */
473                 if (!symtab_index && tpnt->libtype == program_interpreter)
474                         continue;
475                 if (symtab_index && tpnt->libtype == program_interpreter &&
476                     _dl_symbol(strtab + symtab[symtab_index].st_name))
477                         continue;
478
479 #if defined (__SUPPORT_LD_DEBUG__)
480                 debug_sym(symtab,strtab,symtab_index);
481                 debug_reloc(symtab,strtab,rpnt);
482 #endif
483
484                 res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
485
486                 if (res==0) continue;
487
488                 _dl_dprintf(2, "\n%s: ",_dl_progname);
489
490                 if (symtab_index)
491                   _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
492
493                 if (res <0)
494                 {
495                         int reloc_type = ELF32_R_TYPE(rpnt->r_info);
496 #if defined (__SUPPORT_LD_DEBUG__)
497                         _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
498 #else
499                         _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
500 #endif
501                         _dl_exit(-res);
502                 }
503                 else if (res >0)
504                 {
505                         _dl_dprintf(2, "can't resolve symbol\n");
506                         return res;
507                 }
508           }
509           return 0;
510 }
511
512 int _dl_parse_relocation_information(struct dyn_elf *rpnt,
513         unsigned long rel_addr, unsigned long rel_size, int type)
514 {
515         return _dl_parse(rpnt->dyn, rpnt, rel_addr, rel_size, _dl_do_reloc);
516 }
517
518 /* Should be a static inline instead, but that conflicts with ld_elf.h */
519 int _dl_parse_copy_information(struct dyn_elf *rpnt,
520         unsigned long rel_addr, unsigned long rel_size, int type)
521 {
522         /* Not used! */
523         return 0;
524 }
525