diff --git a/src/write/coff.rs b/src/write/coff.rs index 36c70b05..d2f7ccc6 100644 --- a/src/write/coff.rs +++ b/src/write/coff.rs @@ -37,33 +37,41 @@ impl<'a> Object<'a> { pub(crate) fn coff_section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match section { - StandardSection::Text => (&[], &b".text"[..], SectionKind::Text), - StandardSection::Data => (&[], &b".data"[..], SectionKind::Data), + StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None), + StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None), StandardSection::ReadOnlyData | StandardSection::ReadOnlyDataWithRel - | StandardSection::ReadOnlyString => (&[], &b".rdata"[..], SectionKind::ReadOnlyData), - StandardSection::UninitializedData => { - (&[], &b".bss"[..], SectionKind::UninitializedData) - } + | StandardSection::ReadOnlyString => ( + &[], + &b".rdata"[..], + SectionKind::ReadOnlyData, + SectionFlags::None, + ), + StandardSection::UninitializedData => ( + &[], + &b".bss"[..], + SectionKind::UninitializedData, + SectionFlags::None, + ), // TLS sections are data sections with a special name. - StandardSection::Tls => (&[], &b".tls$"[..], SectionKind::Data), + StandardSection::Tls => (&[], &b".tls$"[..], SectionKind::Data, SectionFlags::None), StandardSection::UninitializedTls => { // Unsupported section. - (&[], &[], SectionKind::UninitializedTls) + (&[], &[], SectionKind::UninitializedTls, SectionFlags::None) } StandardSection::TlsVariables => { // Unsupported section. - (&[], &[], SectionKind::TlsVariables) + (&[], &[], SectionKind::TlsVariables, SectionFlags::None) } StandardSection::Common => { // Unsupported section. - (&[], &[], SectionKind::Common) + (&[], &[], SectionKind::Common, SectionFlags::None) } StandardSection::GnuProperty => { // Unsupported section. - (&[], &[], SectionKind::Note) + (&[], &[], SectionKind::Note, SectionFlags::None) } } } diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs index d1ed9961..5d9f2a40 100644 --- a/src/write/elf/object.rs +++ b/src/write/elf/object.rs @@ -67,32 +67,51 @@ impl<'a> Object<'a> { pub(crate) fn elf_section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match section { - StandardSection::Text => (&[], &b".text"[..], SectionKind::Text), - StandardSection::Data => (&[], &b".data"[..], SectionKind::Data), - StandardSection::ReadOnlyData | StandardSection::ReadOnlyString => { - (&[], &b".rodata"[..], SectionKind::ReadOnlyData) - } - StandardSection::ReadOnlyDataWithRel => { - (&[], b".data.rel.ro", SectionKind::ReadOnlyDataWithRel) - } - StandardSection::UninitializedData => { - (&[], &b".bss"[..], SectionKind::UninitializedData) - } - StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls), - StandardSection::UninitializedTls => { - (&[], &b".tbss"[..], SectionKind::UninitializedTls) - } + StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None), + StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None), + StandardSection::ReadOnlyData | StandardSection::ReadOnlyString => ( + &[], + &b".rodata"[..], + SectionKind::ReadOnlyData, + SectionFlags::None, + ), + StandardSection::ReadOnlyDataWithRel => ( + &[], + b".data.rel.ro", + SectionKind::ReadOnlyDataWithRel, + SectionFlags::None, + ), + StandardSection::UninitializedData => ( + &[], + &b".bss"[..], + SectionKind::UninitializedData, + SectionFlags::None, + ), + StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls, SectionFlags::None), + StandardSection::UninitializedTls => ( + &[], + &b".tbss"[..], + SectionKind::UninitializedTls, + SectionFlags::None, + ), StandardSection::TlsVariables => { // Unsupported section. - (&[], &[], SectionKind::TlsVariables) + (&[], &[], SectionKind::TlsVariables, SectionFlags::None) } StandardSection::Common => { // Unsupported section. - (&[], &[], SectionKind::Common) + (&[], &[], SectionKind::Common, SectionFlags::None) } - StandardSection::GnuProperty => (&[], &b".note.gnu.property"[..], SectionKind::Note), + StandardSection::GnuProperty => ( + &[], + &b".note.gnu.property"[..], + SectionKind::Note, + SectionFlags::Elf { + sh_flags: u64::from(elf::SHF_ALLOC), + }, + ), } } diff --git a/src/write/macho.rs b/src/write/macho.rs index b5e51c90..65628790 100644 --- a/src/write/macho.rs +++ b/src/write/macho.rs @@ -80,43 +80,71 @@ impl<'a> Object<'a> { pub(crate) fn macho_section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match section { - StandardSection::Text => (&b"__TEXT"[..], &b"__text"[..], SectionKind::Text), - StandardSection::Data => (&b"__DATA"[..], &b"__data"[..], SectionKind::Data), - StandardSection::ReadOnlyData => { - (&b"__TEXT"[..], &b"__const"[..], SectionKind::ReadOnlyData) - } + StandardSection::Text => ( + &b"__TEXT"[..], + &b"__text"[..], + SectionKind::Text, + SectionFlags::None, + ), + StandardSection::Data => ( + &b"__DATA"[..], + &b"__data"[..], + SectionKind::Data, + SectionFlags::None, + ), + StandardSection::ReadOnlyData => ( + &b"__TEXT"[..], + &b"__const"[..], + SectionKind::ReadOnlyData, + SectionFlags::None, + ), StandardSection::ReadOnlyDataWithRel => ( &b"__DATA"[..], &b"__const"[..], SectionKind::ReadOnlyDataWithRel, + SectionFlags::None, ), StandardSection::ReadOnlyString => ( &b"__TEXT"[..], &b"__cstring"[..], SectionKind::ReadOnlyString, + SectionFlags::None, ), StandardSection::UninitializedData => ( &b"__DATA"[..], &b"__bss"[..], SectionKind::UninitializedData, + SectionFlags::None, + ), + StandardSection::Tls => ( + &b"__DATA"[..], + &b"__thread_data"[..], + SectionKind::Tls, + SectionFlags::None, ), - StandardSection::Tls => (&b"__DATA"[..], &b"__thread_data"[..], SectionKind::Tls), StandardSection::UninitializedTls => ( &b"__DATA"[..], &b"__thread_bss"[..], SectionKind::UninitializedTls, + SectionFlags::None, ), StandardSection::TlsVariables => ( &b"__DATA"[..], &b"__thread_vars"[..], SectionKind::TlsVariables, + SectionFlags::None, + ), + StandardSection::Common => ( + &b"__DATA"[..], + &b"__common"[..], + SectionKind::Common, + SectionFlags::None, ), - StandardSection::Common => (&b"__DATA"[..], &b"__common"[..], SectionKind::Common), StandardSection::GnuProperty => { // Unsupported section. - (&[], &[], SectionKind::Note) + (&[], &[], SectionKind::Note, SectionFlags::None) } } } diff --git a/src/write/mod.rs b/src/write/mod.rs index f2474257..711ff16d 100644 --- a/src/write/mod.rs +++ b/src/write/mod.rs @@ -180,8 +180,10 @@ impl<'a> Object<'a> { .get(§ion) .cloned() .unwrap_or_else(|| { - let (segment, name, kind) = self.section_info(section); - self.add_section(segment.to_vec(), name.to_vec(), kind) + let (segment, name, kind, flags) = self.section_info(section); + let id = self.add_section(segment.to_vec(), name.to_vec(), kind); + self.section_mut(id).flags = flags; + id }) } @@ -206,7 +208,7 @@ impl<'a> Object<'a> { let section = &self.sections[id.0]; for standard_section in StandardSection::all() { if !self.standard_sections.contains_key(standard_section) { - let (segment, name, kind) = self.section_info(*standard_section); + let (segment, name, kind, _flags) = self.section_info(*standard_section); if segment == &*section.segment && name == &*section.name && kind == section.kind { self.standard_sections.insert(*standard_section, id); } @@ -219,7 +221,7 @@ impl<'a> Object<'a> { fn section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match self.format { #[cfg(feature = "coff")] BinaryFormat::Coff => self.coff_section_info(section), @@ -245,8 +247,10 @@ impl<'a> Object<'a> { self.set_subsections_via_symbols(); self.section_id(section) } else { - let (segment, name, kind) = self.subsection_info(section, name); - self.add_section(segment.to_vec(), name, kind) + let (segment, name, kind, flags) = self.subsection_info(section, name); + let id = self.add_section(segment.to_vec(), name, kind); + self.section_mut(id).flags = flags; + id }; let offset = self.append_section_data(section_id, data, align); (section_id, offset) @@ -272,10 +276,10 @@ impl<'a> Object<'a> { &self, section: StandardSection, value: &[u8], - ) -> (&'static [u8], Vec, SectionKind) { - let (segment, section, kind) = self.section_info(section); + ) -> (&'static [u8], Vec, SectionKind, SectionFlags) { + let (segment, section, kind, flags) = self.section_info(section); let name = self.subsection_name(section, value); - (segment, name, kind) + (segment, name, kind, flags) } #[allow(unused_variables)] diff --git a/src/write/xcoff.rs b/src/write/xcoff.rs index 70d8d594..6c9a8038 100644 --- a/src/write/xcoff.rs +++ b/src/write/xcoff.rs @@ -26,31 +26,42 @@ impl<'a> Object<'a> { pub(crate) fn xcoff_section_info( &self, section: StandardSection, - ) -> (&'static [u8], &'static [u8], SectionKind) { + ) -> (&'static [u8], &'static [u8], SectionKind, SectionFlags) { match section { - StandardSection::Text => (&[], &b".text"[..], SectionKind::Text), - StandardSection::Data => (&[], &b".data"[..], SectionKind::Data), + StandardSection::Text => (&[], &b".text"[..], SectionKind::Text, SectionFlags::None), + StandardSection::Data => (&[], &b".data"[..], SectionKind::Data, SectionFlags::None), StandardSection::ReadOnlyData | StandardSection::ReadOnlyDataWithRel - | StandardSection::ReadOnlyString => (&[], &b".rdata"[..], SectionKind::ReadOnlyData), - StandardSection::UninitializedData => { - (&[], &b".bss"[..], SectionKind::UninitializedData) - } - StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls), - StandardSection::UninitializedTls => { - (&[], &b".tbss"[..], SectionKind::UninitializedTls) - } + | StandardSection::ReadOnlyString => ( + &[], + &b".rdata"[..], + SectionKind::ReadOnlyData, + SectionFlags::None, + ), + StandardSection::UninitializedData => ( + &[], + &b".bss"[..], + SectionKind::UninitializedData, + SectionFlags::None, + ), + StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls, SectionFlags::None), + StandardSection::UninitializedTls => ( + &[], + &b".tbss"[..], + SectionKind::UninitializedTls, + SectionFlags::None, + ), StandardSection::TlsVariables => { // Unsupported section. - (&[], &[], SectionKind::TlsVariables) + (&[], &[], SectionKind::TlsVariables, SectionFlags::None) } StandardSection::Common => { // Unsupported section. - (&[], &[], SectionKind::Common) + (&[], &[], SectionKind::Common, SectionFlags::None) } StandardSection::GnuProperty => { // Unsupported section. - (&[], &[], SectionKind::Note) + (&[], &[], SectionKind::Note, SectionFlags::None) } } } diff --git a/tests/round_trip/elf.rs b/tests/round_trip/elf.rs index ee30b3ea..cd89b312 100644 --- a/tests/round_trip/elf.rs +++ b/tests/round_trip/elf.rs @@ -243,6 +243,7 @@ fn gnu_property_inner>(architecture: Archit sections.section_name(endian, section).unwrap(), b".note.gnu.property" ); + assert_eq!(section.sh_flags(endian).into(), u64::from(elf::SHF_ALLOC)); let mut notes = section.notes(endian, bytes).unwrap().unwrap(); let note = notes.next().unwrap().unwrap(); let mut props = note.gnu_properties(endian).unwrap();