diff --git a/src/libdyld/src/reloc.rs b/src/libdyld/src/reloc.rs index 1bbacea..93f4bbc 100644 --- a/src/libdyld/src/reloc.rs +++ b/src/libdyld/src/reloc.rs @@ -159,23 +159,36 @@ pub fn relocate( pub fn rebind( arch: Arch, lib: &Library, name: &[u8], value: Elf32_Word ) -> Result<(), Error> { - for rela in lib.pltrel() { - let rel_type = RelType::new(arch, rela.type_info()) - .ok_or("unsupported relocation type")?; - match rel_type { - RelType::LookupAbs => { - let sym = lib.symtab().get(ELF32_R_SYM(rela.r_info) as usize) - .ok_or("symbol out of bounds of symbol table")?; - let sym_name = lib.name_starting_at(sym.st_name as usize)?; + fn rebind_symbol_to_value( + arch: Arch, lib: &Library,name: &[u8], value: Elf32_Word, relocs: &[R] + ) -> Result<(), Error> { + for reloc in relocs { + let rel_type = RelType::new(arch, reloc.type_info()) + .ok_or("unsupported relocation type")?; + match rel_type { + RelType::LookupAbs => { + let sym = lib.symtab().get(reloc.sym_info() as usize) + .ok_or("symbol out of bounds of symbol table")?; + let sym_name = lib.name_starting_at(sym.st_name as usize)?; - if sym_name == name { - lib.image.write(rela.offset(), value)? + if sym_name == name { + lib.image.write(reloc.offset(), value)? + } } + // No associated symbols for other relocation types. + _ => {} } - // No associated symbols for other relocation types. - _ => {} } + + Ok(()) } + + if lib.pltrel().is_empty() { + rebind_symbol_to_value(arch, lib, name, value, lib.rela())?; + } else { + rebind_symbol_to_value(arch, lib, name, value, lib.pltrel())?; + } + // FIXME: the cache maintainance operations may be more than enough, // may cause performance degradation. dcci_slice(lib.image.data);