mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2025-12-12 22:56:28 +00:00
REL section alignment fixes
- Honor section alignment from splits.txt when writing RELs - Better heuristic for determining REL section alignment on initial analysis
This commit is contained in:
@@ -48,7 +48,7 @@ use crate::{
|
||||
file::{buf_reader, buf_writer, map_file, touch, verify_hash, FileIterator},
|
||||
lcf::{asm_path_for_unit, generate_ldscript, obj_path_for_unit},
|
||||
map::apply_map_file,
|
||||
rel::{process_rel, process_rel_header},
|
||||
rel::{process_rel, process_rel_header, update_rel_section_alignment},
|
||||
rso::{process_rso, DOL_SECTION_ABS, DOL_SECTION_NAMES},
|
||||
split::{is_linker_generated_object, split_obj, update_splits},
|
||||
IntoCow, ToCow,
|
||||
@@ -856,7 +856,7 @@ fn load_analyze_rel(config: &ProjectConfig, module_config: &ModuleConfig) -> Res
|
||||
if let Some(hash_str) = &module_config.hash {
|
||||
verify_hash(file.as_slice(), hash_str)?;
|
||||
}
|
||||
let (_, mut module_obj) =
|
||||
let (header, mut module_obj) =
|
||||
process_rel(&mut Cursor::new(file.as_slice()), module_config.name().as_ref())?;
|
||||
|
||||
if let Some(comment_version) = config.mw_comment_version {
|
||||
@@ -895,6 +895,9 @@ fn load_analyze_rel(config: &ProjectConfig, module_config: &ModuleConfig) -> Res
|
||||
// Create _ctors and _dtors symbols if missing
|
||||
update_ctors_dtors(&mut module_obj)?;
|
||||
|
||||
// Determine REL section alignment
|
||||
update_rel_section_alignment(&mut module_obj, &header)?;
|
||||
|
||||
Ok((module_obj, dep))
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ use crate::{
|
||||
cmd::dol::{ModuleConfig, ProjectConfig},
|
||||
obj::{ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol},
|
||||
util::{
|
||||
config::is_auto_symbol,
|
||||
config::{is_auto_symbol, read_splits_sections, SectionDef},
|
||||
dol::process_dol,
|
||||
elf::{to_obj_reloc_kind, write_elf},
|
||||
file::{buf_reader, buf_writer, map_file, process_rsp, verify_hash, FileIterator},
|
||||
@@ -153,7 +153,7 @@ fn match_section_index(
|
||||
// })
|
||||
}
|
||||
|
||||
fn load_rel(module_config: &ModuleConfig) -> Result<(RelHeader, Vec<RelSectionHeader>)> {
|
||||
fn load_rel(module_config: &ModuleConfig) -> Result<RelInfo> {
|
||||
let file = map_file(&module_config.object)?;
|
||||
if let Some(hash_str) = &module_config.hash {
|
||||
verify_hash(file.as_slice(), hash_str)?;
|
||||
@@ -161,12 +161,17 @@ fn load_rel(module_config: &ModuleConfig) -> Result<(RelHeader, Vec<RelSectionHe
|
||||
let mut reader = file.as_reader();
|
||||
let header = process_rel_header(&mut reader)?;
|
||||
let sections = process_rel_sections(&mut reader, &header)?;
|
||||
Ok((header, sections))
|
||||
let section_defs = if let Some(splits_path) = &module_config.splits {
|
||||
read_splits_sections(splits_path)?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok((header, sections, section_defs))
|
||||
}
|
||||
|
||||
fn resolve_relocations(
|
||||
module: &File,
|
||||
existing_headers: &BTreeMap<u32, (RelHeader, Vec<RelSectionHeader>)>,
|
||||
existing_headers: &BTreeMap<u32, RelInfo>,
|
||||
module_id: usize,
|
||||
symbol_map: &FxHashMap<&[u8], (usize, SymbolIndex)>,
|
||||
modules: &[(File, PathBuf)],
|
||||
@@ -177,11 +182,12 @@ fn resolve_relocations(
|
||||
if !matches!(section.name(), Ok(name) if PERMITTED_SECTIONS.contains(&name)) {
|
||||
continue;
|
||||
}
|
||||
let section_index = if let Some((_, sections)) = existing_headers.get(&(module_id as u32)) {
|
||||
match_section_index(module, section.index(), sections)?
|
||||
} else {
|
||||
section.index().0
|
||||
} as u8;
|
||||
let section_index =
|
||||
if let Some((_, sections, _)) = existing_headers.get(&(module_id as u32)) {
|
||||
match_section_index(module, section.index(), sections)?
|
||||
} else {
|
||||
section.index().0
|
||||
} as u8;
|
||||
for (address, reloc) in section.relocations() {
|
||||
let reloc_target = match reloc.target() {
|
||||
RelocationTarget::Symbol(idx) => {
|
||||
@@ -208,7 +214,7 @@ fn resolve_relocations(
|
||||
(module_id, reloc_target)
|
||||
};
|
||||
let target_section_index = target_symbol.section_index().unwrap();
|
||||
let target_section = if let Some((_, sections)) =
|
||||
let target_section = if let Some((_, sections, _)) =
|
||||
existing_headers.get(&(target_module_id as u32))
|
||||
{
|
||||
match_section_index(&modules[target_module_id].0, target_section_index, sections)?
|
||||
@@ -231,19 +237,21 @@ fn resolve_relocations(
|
||||
Ok(resolved)
|
||||
}
|
||||
|
||||
type RelInfo = (RelHeader, Vec<RelSectionHeader>, Option<Vec<SectionDef>>);
|
||||
|
||||
fn make(args: MakeArgs) -> Result<()> {
|
||||
let total = Instant::now();
|
||||
|
||||
// Load existing REL headers (if specified)
|
||||
let mut existing_headers = BTreeMap::<u32, (RelHeader, Vec<RelSectionHeader>)>::new();
|
||||
let mut existing_headers = BTreeMap::<u32, RelInfo>::new();
|
||||
if let Some(config_path) = &args.config {
|
||||
let config: ProjectConfig = serde_yaml::from_reader(&mut buf_reader(config_path)?)?;
|
||||
for module_config in &config.modules {
|
||||
let _span = info_span!("module", name = %module_config.name()).entered();
|
||||
let (header, sections) = load_rel(module_config).with_context(|| {
|
||||
let info = load_rel(module_config).with_context(|| {
|
||||
format!("While loading REL '{}'", module_config.object.display())
|
||||
})?;
|
||||
existing_headers.insert(header.module_id, (header, sections));
|
||||
existing_headers.insert(info.0.module_id, info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,14 +324,19 @@ fn make(args: MakeArgs) -> Result<()> {
|
||||
bss_align: None,
|
||||
section_count: None,
|
||||
quiet: args.no_warn,
|
||||
section_align: None,
|
||||
};
|
||||
if let Some((header, _)) = existing_headers.get(&(module_id as u32)) {
|
||||
if let Some((header, _, section_defs)) = existing_headers.get(&(module_id as u32)) {
|
||||
info.version = header.version;
|
||||
info.name_offset = Some(header.name_offset);
|
||||
info.name_size = Some(header.name_size);
|
||||
info.align = header.align;
|
||||
info.bss_align = header.bss_align;
|
||||
info.section_count = Some(header.num_sections as usize);
|
||||
info.section_align = section_defs
|
||||
.as_ref()
|
||||
.map(|defs| defs.iter().map(|def| def.align).collect())
|
||||
.unwrap_or_default();
|
||||
}
|
||||
let rel_path = path.with_extension("rel");
|
||||
let mut w = buf_writer(&rel_path)?;
|
||||
|
||||
Reference in New Issue
Block a user