|
|
|
@ -159,23 +159,36 @@ pub fn relocate<R: Relocatable>( |
|
|
|
|
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)?; |
|
|
|
|
|
|
|
|
|
if sym_name == name { |
|
|
|
|
lib.image.write(rela.offset(), value)? |
|
|
|
|
fn rebind_symbol_to_value<R: Relocatable>( |
|
|
|
|
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(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); |
|
|
|
|