Skip to content

Commit

Permalink
write/elf: .note.gnu.properties should have SHF_ALLOC
Browse files Browse the repository at this point in the history
  • Loading branch information
philipc committed May 3, 2023
1 parent ebd44bb commit e91df1d
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 63 deletions.
32 changes: 20 additions & 12 deletions src/write/coff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand Down
57 changes: 38 additions & 19 deletions src/write/elf/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,32 +64,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),
},
),
}
}

Expand Down
46 changes: 37 additions & 9 deletions src/write/macho.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand Down
22 changes: 13 additions & 9 deletions src/write/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,10 @@ impl<'a> Object<'a> {
.get(&section)
.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
})
}

Expand All @@ -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);
}
Expand All @@ -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),
Expand All @@ -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)
Expand All @@ -272,10 +276,10 @@ impl<'a> Object<'a> {
&self,
section: StandardSection,
value: &[u8],
) -> (&'static [u8], Vec<u8>, SectionKind) {
let (segment, section, kind) = self.section_info(section);
) -> (&'static [u8], Vec<u8>, 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)]
Expand Down
39 changes: 25 additions & 14 deletions src/write/xcoff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}
Expand Down
1 change: 1 addition & 0 deletions tests/round_trip/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ fn gnu_property_inner<Elf: FileHeader<Endian = Endianness>>(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();
Expand Down

0 comments on commit e91df1d

Please sign in to comment.