From 761a940f9ed9fb16985518448db355ae6380427c Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 10 Jun 2024 17:39:40 -0600 Subject: [PATCH] Match original "exec" for REL sections mwld writes empty code sections as NULL type in the PLF, but sometimes the original REL has the exec flag set for these sections. Match the original value. --- src/cmd/rel.rs | 6 +++++- src/util/rel.rs | 16 ++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/cmd/rel.rs b/src/cmd/rel.rs index 89ab519..9d7137b 100644 --- a/src/cmd/rel.rs +++ b/src/cmd/rel.rs @@ -346,8 +346,11 @@ fn make(args: MakeArgs) -> Result<()> { section_count: None, quiet: args.no_warn, section_align: None, + section_exec: None, }; - if let Some((header, _, section_defs)) = existing_headers.get(&(module_id as u32)) { + if let Some((header, section_headers, 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); @@ -358,6 +361,7 @@ fn make(args: MakeArgs) -> Result<()> { .as_ref() .map(|defs| defs.iter().map(|def| def.align).collect()) .unwrap_or_default(); + info.section_exec = Some(section_headers.iter().map(|s| s.exec()).collect()); } let rel_path = path.with_extension("rel"); let mut w = buf_writer(&rel_path)?; diff --git a/src/util/rel.rs b/src/util/rel.rs index 14fe23c..229ba7c 100644 --- a/src/util/rel.rs +++ b/src/util/rel.rs @@ -688,6 +688,10 @@ pub struct RelWriteInfo { pub quiet: bool, /// Override individual section alignment in the file. pub section_align: Option>, + /// Override individual section executable status in the file. + /// This is used to match empty sections: mwld will emit them with + /// NULL type, but the original REL may have them marked executable. + pub section_exec: Option>, } pub const PERMITTED_SECTIONS: [&str; 7] = @@ -1006,12 +1010,12 @@ where offset = current_data_offset; current_data_offset += section.size() as u32; } - RelSectionHeader::new( - offset, - section.size() as u32, - section.kind() == object::SectionKind::Text, - ) - .to_writer(w, Endian::Big)?; + let exec = info + .section_exec + .as_ref() + .and_then(|m| m.get(section_index as usize).copied()) + .unwrap_or(section.kind() == object::SectionKind::Text); + RelSectionHeader::new(offset, section.size() as u32, exec).to_writer(w, Endian::Big)?; permitted_section_idx += 1; } else { RelSectionHeader::new(0, 0, false).to_writer(w, Endian::Big)?;