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)?;