Zero out section data for relocations in relocatable ELFs
Fixes issues with Wii versions of mwld.
This commit is contained in:
parent
c354c6da4b
commit
36bb5ddcc6
|
@ -331,7 +331,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "decomp-toolkit"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ar",
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "decomp-toolkit"
|
|||
description = "Yet another GameCube/Wii decompilation toolkit."
|
||||
authors = ["Luke Street <luke@street.dev>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
build = "build.rs"
|
||||
|
|
|
@ -13,7 +13,7 @@ use object::{
|
|||
elf,
|
||||
elf::{SHF_ALLOC, SHF_EXECINSTR, SHF_WRITE, SHT_NOBITS, SHT_PROGBITS},
|
||||
write::{
|
||||
elf::{ProgramHeader, Rel, SectionHeader, SectionIndex, SymbolIndex},
|
||||
elf::{ProgramHeader, Rel, SectionHeader, SectionIndex, SymbolIndex, Writer},
|
||||
StringId,
|
||||
},
|
||||
Architecture, Endianness, Object, ObjectKind, ObjectSection, ObjectSymbol, Relocation,
|
||||
|
@ -21,6 +21,7 @@ use object::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
array_ref,
|
||||
obj::{
|
||||
ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind,
|
||||
ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjUnit,
|
||||
|
@ -631,8 +632,12 @@ pub fn write_elf(obj: &ObjInfo) -> Result<Vec<u8>> {
|
|||
}
|
||||
writer.write_align(32);
|
||||
ensure!(writer.len() == out_section.offset);
|
||||
if obj.kind == ObjKind::Relocatable {
|
||||
write_relocatable_section_data(&mut writer, section)?;
|
||||
} else {
|
||||
writer.write(§ion.data);
|
||||
}
|
||||
}
|
||||
|
||||
for ((_, section), out_section) in obj.sections.iter().zip(&out_sections) {
|
||||
if section.relocations.is_empty() {
|
||||
|
@ -876,3 +881,35 @@ fn to_obj_reloc(
|
|||
}?;
|
||||
Ok(Some(ObjReloc { kind: reloc_kind, target_symbol, addend, module: None }))
|
||||
}
|
||||
|
||||
/// Writes section data while zeroing out relocations.
|
||||
fn write_relocatable_section_data(w: &mut Writer, section: &ObjSection) -> Result<()> {
|
||||
ensure!(section.address == 0);
|
||||
let mut current_address = 0;
|
||||
for (addr, reloc) in section.relocations.iter() {
|
||||
w.write(§ion.data[current_address..addr as usize]);
|
||||
let mut ins = u32::from_be_bytes(*array_ref!(section.data, addr as usize, 4));
|
||||
match reloc.kind {
|
||||
ObjRelocKind::Absolute => {
|
||||
ins = 0;
|
||||
}
|
||||
ObjRelocKind::PpcAddr16Hi | ObjRelocKind::PpcAddr16Ha | ObjRelocKind::PpcAddr16Lo => {
|
||||
ins &= !0xFFFF;
|
||||
}
|
||||
ObjRelocKind::PpcRel24 => {
|
||||
ins &= !0x3FFFFFC;
|
||||
}
|
||||
ObjRelocKind::PpcRel14 => {
|
||||
ins &= !0xFFFC;
|
||||
}
|
||||
ObjRelocKind::PpcEmbSda21 => {
|
||||
ins &= !0x1FFFFF;
|
||||
}
|
||||
}
|
||||
w.write(&ins.to_be_bytes());
|
||||
current_address = addr as usize + 4;
|
||||
}
|
||||
// Write remaining data
|
||||
w.write(§ion.data[current_address..]);
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue