From 9cba52f0aedbb95671e8a14e3fd5ff98381ff2b0 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Thu, 8 Aug 2002 14:35:49 +0000 Subject: Patch from Stefan Allius and Edie C. Dost to add SuperH shared library support. This also adds some cleaner error handling, which I (Erik) then ported over to x86 and arm. In addition Stefan added the following fixes: - in hash.c was the lvalue handling of global library functions wrong. To fix this I had to change the prototype of _dl_find_hash. (==> TIS and ELF spec. Vers. 1.2) - in ldso.c was the order of the .init sections calls wrong. Before we call the initialization code of a library we have to check that all dependend libraries are already initialized. This can easily made by calling it in the revers loading order. For this I added a previous pointer chain. - in ldso.c the ELF magics wasn't checked fo PPC, MIPS and SH architecture --- ldso/ldso/arm/elfinterp.c | 468 ++++++++++++++++++++++++++++------------------ 1 file changed, 283 insertions(+), 185 deletions(-) (limited to 'ldso/ldso/arm/elfinterp.c') diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c index 39f29d634..dd68324a5 100644 --- a/ldso/ldso/arm/elfinterp.c +++ b/ldso/ldso/arm/elfinterp.c @@ -1,39 +1,102 @@ -/* Run an ELF binary on a linux system. - - Copyright (C) 1993, Eric Youngdale. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef VERBOSE_DLINKER -#define VERBOSE_DLINKER -#endif -#ifdef VERBOSE_DLINKER -static const char *_dl_reltypes[] = - { "R_ARM_NONE", "R_ARM_PC24", "R_ARM_ABS32", "R_ARM_REL32", - "R_ARM_PC13", "R_ARM_ABS16", "R_ARM_ABS12", "R_ARM_THM_ABS5", - "R_ARM_ABS8", "R_ARM_SBREL32", "R_ARM_THM_PC22", "R_ARM_THM_PC8", - "R_ARM_AMP_VCALL9", "R_ARM_SWI24", "R_ARM_THM_SWI8", "R_ARM_XPC25", - "R_ARM_THM_XPC22", "R_ARM_COPY", "R_ARM_GLOB_DAT", "R_ARM_JUMP_SLOT", - "R_ARM_RELATIVE", "R_ARM_GOTOFF", "R_ARM_GOTPC", "R_ARM_GOT32", - "R_ARM_PLT32", "R_ARM_ALU_PCREL_7_0", "R_ARM_ALU_PCREL_15_8", - "R_ARM_ALU_PCREL_23_15", "R_ARM_LDR_SBREL_11_0", "R_ARM_ALU_SBREL_19_12", - "R_ARM_ALU_SBREL_27_20", "R_ARM_GNU_VTENTRY", "R_ARM_GNU_VTINHERIT", - "R_ARM_THM_PC11", "R_ARM_THM_PC9", "R_ARM_RXPC25", "R_ARM_RSBREL32", - "R_ARM_THM_RPC22", "R_ARM_RREL32", "R_ARM_RABS22", "R_ARM_RPC24", - "R_ARM_RBASE", "R_ARM_NUM" +/* vi: set sw=4 ts=4: */ +/* ARM ELF shared library loader suppport + * + * Copyright (C) 2001-2002, Erik Andersen + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the above contributors may not be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined (SUPPORT_LD_DEBUG) || defined (LD_DEBUG_SYMBOLS) +static const char *_dl_reltypes_tab[] = + [0] "R_ARM_NONE", "R_ARM_PC24", "R_ARM_ABS32", "R_ARM_REL32", + [4] "R_ARM_PC13", "R_ARM_ABS16", "R_ARM_ABS12", "R_ARM_THM_ABS5", + [8] "R_ARM_ABS8", "R_ARM_SBREL32","R_ARM_THM_PC22", "R_ARM_THM_PC8", + [12] "R_ARM_AMP_VCALL9", "R_ARM_SWI24", "R_ARM_THM_SWI8", "R_ARM_XPC25", + [16] "R_ARM_THM_XPC22", + [20] "R_ARM_COPY", "R_ARM_GLOB_DAT","R_ARM_JUMP_SLOT", "R_ARM_RELATIVE", + [24] "R_ARM_GOTOFF", "R_ARM_GOTPC", "R_ARM_GOT32", "R_ARM_PLT32", + [32] "R_ARM_ALU_PCREL_7_0","R_ARM_ALU_PCREL_15_8","R_ARM_ALU_PCREL_23_15","R_ARM_LDR_SBREL_11_0", + [36] "R_ARM_ALU_SBREL_19_12","R_ARM_ALU_SBREL_27_20", + [100] "R_ARM_GNU_VTENTRY","R_ARM_GNU_VTINHERIT","R_ARM_THM_PC11","R_ARM_THM_PC9", + [249] "R_ARM_RXPC25", "R_ARM_RSBREL32", "R_ARM_THM_RPC22", "R_ARM_RREL32", + [253] "R_ARM_RABS22", "R_ARM_RPC24", "R_ARM_RBASE", }; + +static const char * +_dl_reltypes(int type) +{ + static char buf[22]; + const char *str; + + if (type >= (sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) || + NULL == (str = _dl_reltypes_tab[type])) + { + str =_dl_simple_ltoa( buf, (unsigned long)(type)); + } + return str; +} + +static +void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index) +{ + if(_dl_debug_symbols) + { + if(symtab_index){ + _dl_dprintf(_dl_debug_file, "\n%s\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x", + strtab + symtab[symtab_index].st_name, + symtab[symtab_index].st_value, + symtab[symtab_index].st_size, + symtab[symtab_index].st_info, + symtab[symtab_index].st_other, + symtab[symtab_index].st_shndx); + } + } +} + +static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt) +{ + if(_dl_debug_reloc) + { + int symtab_index; + const char *sym; + symtab_index = ELF32_R_SYM(rpnt->r_info); + sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0"; + +#ifdef ELF_USES_RELOCA + _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x\taddend=%x %s", + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), + rpnt->r_offset, + rpnt->r_addend, + sym); +#else + _dl_dprintf(_dl_debug_file, "\n%s\toffset=%x %s", + _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)), + rpnt->r_offset, + sym); +#endif + } +} #endif /* Program to load an ELF binary on a linux system, and run it. @@ -47,22 +110,21 @@ static const char *_dl_reltypes[] = a more than adequate job of explaining everything required to get this working. */ - extern int _dl_linux_resolve(void); unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) { int reloc_type; - Elf32_Rel *this_reloc; + ELF_RELOC *this_reloc; char *strtab; Elf32_Sym *symtab; - Elf32_Rel *rel_addr; + ELF_RELOC *rel_addr; int symtab_index; char *new_addr; char **got_addr; unsigned long instr_addr; - rel_addr = (Elf32_Rel *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr); + rel_addr = (ELF_RELOC *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr); this_reloc = rel_addr + (reloc_entry >> 3); reloc_type = ELF32_R_TYPE(this_reloc->r_info); @@ -71,92 +133,114 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); + if (reloc_type != R_ARM_JUMP_SLOT) { - _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", - _dl_progname); - _dl_exit(1); + _dl_dprintf(2, "%s: Incorrect relocation type in jump relocations\n", + _dl_progname); + _dl_exit(1); }; - + /* Address of jump instruction to fix up */ instr_addr = ((unsigned long) this_reloc->r_offset + - (unsigned long) tpnt->loadaddr); + (unsigned long) tpnt->loadaddr); got_addr = (char **) instr_addr; -#ifdef DL_DEBUG_SYMBOLS - _dl_dprintf(2, "Resolving symbol %s\n", - strtab + symtab[symtab_index].st_name); -#endif - /* Get the address of the GOT entry */ new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, - tpnt->symbol_scope, tpnt, 0); + tpnt->symbol_scope, tpnt, resolver); if (!new_addr) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, strtab + symtab[symtab_index].st_name); _dl_exit(1); }; -#ifdef DL_NEVER_FIXUP_SYMBOLS - if ((unsigned long) got_addr < 0x40000000) { - _dl_dprintf(2, "Calling library function: %s\n", +#if defined (SUPPORT_LD_DEBUG) || defined (LD_NEVER_FIXUP_SYMBOLS) + if ((unsigned long) got_addr < 0x40000000) + { +#ifndef SUPPORT_LD_DEBUG + if (_dl_debug_bindings) + { + _dl_dprintf(_dl_debug_file, "\nresolve function: %s", strtab + symtab[symtab_index].st_name); + if(_dl_debug_detail) _dl_dprintf(_dl_debug_file, "\tpatch %x ==> %x @ %x", *got_addr, new_addr, got_addr); + } +#endif +#ifndef LD_NEVER_FIXUP_SYMBOLS + *got_addr = new_addr; +#endif } else { - *got_addr = new_addr; + *got_addr = new_addr; } #else *got_addr = new_addr; #endif + return (unsigned long) new_addr; } -void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, - unsigned long rel_addr, unsigned long rel_size, int type) +static int +_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, + unsigned long rel_addr, unsigned long rel_size, + int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope, + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)) { int i; char *strtab; - int reloc_type; - int symtab_index; + int goof = 0; Elf32_Sym *symtab; - Elf32_Rel *rpnt; - unsigned long *reloc_addr; - + ELF_RELOC *rpnt; + int symtab_index; /* Now parse the relocation information */ - rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr); - rel_size = rel_size / sizeof(Elf32_Rel); - symtab = - (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); + rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr); + rel_size = rel_size / sizeof(ELF_RELOC); + + symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); - for (i = 0; i < rel_size; i++, rpnt++) { - reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); - reloc_type = ELF32_R_TYPE(rpnt->r_info); + for (i = 0; i < rel_size; i++, rpnt++) { + int res; + symtab_index = ELF32_R_SYM(rpnt->r_info); - + /* When the dynamic linker bootstrapped itself, it resolved some symbols. Make sure we do not do them again */ if (!symtab_index && tpnt->libtype == program_interpreter) continue; if (symtab_index && tpnt->libtype == program_interpreter && - _dl_symbol(strtab + symtab[symtab_index].st_name)) + _dl_symbol(strtab + symtab[symtab_index].st_name)) continue; - switch (reloc_type) { - case R_ARM_NONE: - break; - case R_ARM_JUMP_SLOT: - *reloc_addr += (unsigned long) tpnt->loadaddr; - break; - default: - _dl_dprintf(2, "%s: (LAZY) can't handle reloc type ", - _dl_progname); -#ifdef VERBOSE_DLINKER - _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]); +#if defined (SUPPORT_LD_DEBUG) || defined (LD_DEBUG_SYMBOLS) + debug_sym(symtab,strtab,symtab_index); + debug_reloc(symtab,strtab,rpnt); #endif - if (symtab_index) - _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name); - _dl_exit(1); - }; - }; + + res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab); + + if (res==0) continue; + + _dl_dprintf(2, "\n%s: ",_dl_progname); + + if (symtab_index) + _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name); + + if (res <0) + { + int reloc_type = ELF32_R_TYPE(rpnt->r_info); +#if defined (SUPPORT_LD_DEBUG) + _dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type)); +#else + _dl_dprintf(2, "can't handle reloc type %x\n", reloc_type); +#endif + _dl_exit(-res); + } + else if (res >0) + { + _dl_dprintf(2, "can't resolve symbol '%s'\n"); + goof += res; + } + } + return goof; } static unsigned long @@ -183,58 +267,40 @@ fix_bad_pc24 (unsigned long *const reloc_addr, unsigned long value) return (unsigned long)fix_address; } - -int _dl_parse_relocation_information(struct elf_resolve *tpnt, - unsigned long rel_addr, unsigned long rel_size, int type) +static int +_dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { - int i; - char *strtab; int reloc_type; - int goof = 0; - Elf32_Sym *symtab; - Elf32_Rel *rpnt; + int symtab_index; unsigned long *reloc_addr; unsigned long symbol_addr; - int symtab_index; - - /* Now parse the relocation information */ + int goof = 0; - rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr); - rel_size = rel_size / sizeof(Elf32_Rel); + reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); + reloc_type = ELF32_R_TYPE(rpnt->r_info); + symtab_index = ELF32_R_SYM(rpnt->r_info); + symbol_addr = 0; - symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); - strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); + if (symtab_index) { - for (i = 0; i < rel_size; i++, rpnt++) { - reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); - reloc_type = ELF32_R_TYPE(rpnt->r_info); - symtab_index = ELF32_R_SYM(rpnt->r_info); - symbol_addr = 0; + symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, + scope, (reloc_type == R_ARM_JUMP_SLOT ? tpnt : NULL), symbolrel); - if (!symtab_index && tpnt->libtype == program_interpreter) - continue; - - if (symtab_index) { - - if (tpnt->libtype == program_interpreter && - _dl_symbol(strtab + symtab[symtab_index].st_name)) - continue; - - symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, - tpnt->symbol_scope, - (reloc_type == R_ARM_JUMP_SLOT ? tpnt : NULL), 0); - - /* - * We want to allow undefined references to weak symbols - this might - * have been intentional. We should not be linking local symbols - * here, so all bases should be covered. - */ - if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) { - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", - _dl_progname, strtab + symtab[symtab_index].st_name); - goof++; - } + /* + * We want to allow undefined references to weak symbols - this might + * have been intentional. We should not be linking local symbols + * here, so all bases should be covered. + */ + if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) { + goof++; } + } + +#if defined (SUPPORT_LD_DEBUG) + { + unsigned long old_val = *reloc_addr; +#endif switch (reloc_type) { case R_ARM_NONE: break; @@ -286,19 +352,50 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt, #endif break; default: - _dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname); -#ifdef VERBOSE_DLINKER - _dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]); + return -1; /*call _dl_exit(1) */ + } +#if defined (SUPPORT_LD_DEBUG) + if(_dl_debug_reloc && _dl_debug_detail) + _dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr); + } + #endif - if (symtab_index) - _dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name); - _dl_exit(1); - }; - }; return goof; } +static int +_dl_do_lazy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope, + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) +{ + int reloc_type; + unsigned long *reloc_addr; + + reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); + reloc_type = ELF32_R_TYPE(rpnt->r_info); + +#if defined (SUPPORT_LD_DEBUG) + { + unsigned long old_val = *reloc_addr; +#endif + switch (reloc_type) { + case R_ARM_NONE: + break; + case R_ARM_JUMP_SLOT: + *reloc_addr += (unsigned long) tpnt->loadaddr; + break; + default: + return -1; /*call _dl_exit(1) */ + } +#if defined (SUPPORT_LD_DEBUG) + if(_dl_debug_reloc && _dl_debug_detail) + _dl_dprintf(_dl_debug_file, "\tpatch: %x ==> %x @ %x", old_val, *reloc_addr, reloc_addr); + } + +#endif + return 0; + +} /* This is done as a separate step, because there are cases where information is first copied and later initialized. This results in @@ -308,59 +405,60 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt, /* No, there are cases where the SVr4 linker fails to emit COPY relocs at all */ - -int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, - unsigned long rel_size, int type) +static int +_dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope, + ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab) { - int i; - char *strtab; - int reloc_type; - int goof = 0; - Elf32_Sym *symtab; - Elf32_Rel *rpnt; + int reloc_type; + int symtab_index; unsigned long *reloc_addr; unsigned long symbol_addr; - struct elf_resolve *tpnt; - int symtab_index; - - /* Now parse the relocation information */ + int goof = 0; + + reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); + reloc_type = ELF32_R_TYPE(rpnt->r_info); + if (reloc_type != R_ARM_COPY) + return 0; + symtab_index = ELF32_R_SYM(rpnt->r_info); + symbol_addr = 0; + + if (symtab_index) { + + symbol_addr = (unsigned long) _dl_find_hash(strtab + + symtab[symtab_index].st_name, scope, + NULL, copyrel); + if (!symbol_addr) goof++; + } + if (!goof) { +#if defined (SUPPORT_LD_DEBUG) + if(_dl_debug_move) + _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x", + strtab + symtab[symtab_index].st_name, + symtab[symtab_index].st_size, + symbol_addr, symtab[symtab_index].st_value); +#endif + _dl_memcpy((char *) symtab[symtab_index].st_value, + (char *) symbol_addr, symtab[symtab_index].st_size); + } - tpnt = xpnt->dyn; + return goof; +} - rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr); - rel_size = rel_size / sizeof(Elf32_Rel); +void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, + unsigned long rel_addr, unsigned long rel_size, int type) +{ + (void)_dl_parse(tpnt, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); +} - symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); - strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); +int _dl_parse_relocation_information(struct elf_resolve *tpnt, + unsigned long rel_addr, unsigned long rel_size, int type) +{ + return _dl_parse(tpnt, tpnt->symbol_scope, rel_addr, rel_size, _dl_do_reloc); +} - for (i = 0; i < rel_size; i++, rpnt++) { - reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); - reloc_type = ELF32_R_TYPE(rpnt->r_info); - if (reloc_type != R_ARM_COPY) - continue; - symtab_index = ELF32_R_SYM(rpnt->r_info); - symbol_addr = 0; - if (!symtab_index && tpnt->libtype == program_interpreter) - continue; - if (symtab_index) { - - if (tpnt->libtype == program_interpreter && - _dl_symbol(strtab + symtab[symtab_index].st_name)) - continue; - - symbol_addr = (unsigned long) _dl_find_hash(strtab + - symtab[symtab_index].st_name, xpnt->next, - NULL, 1); - if (!symbol_addr) { - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", - _dl_progname, strtab + symtab[symtab_index].st_name); - goof++; - }; - }; - if (!goof) { - _dl_memcpy((char *) symtab[symtab_index].st_value, - (char *) symbol_addr, symtab[symtab_index].st_size); - } - }; - return goof; +int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, + unsigned long rel_size, int type) +{ + return _dl_parse(xpnt->dyn, xpnt->next, rel_addr, rel_size, _dl_do_copy); } + -- cgit v1.2.3