summaryrefslogtreecommitdiffstats
path: root/vendor/object/src/write/elf/object.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/object/src/write/elf/object.rs')
-rw-r--r--vendor/object/src/write/elf/object.rs115
1 files changed, 86 insertions, 29 deletions
diff --git a/vendor/object/src/write/elf/object.rs b/vendor/object/src/write/elf/object.rs
index 068ada6bd..8b9eadaf8 100644
--- a/vendor/object/src/write/elf/object.rs
+++ b/vendor/object/src/write/elf/object.rs
@@ -1,10 +1,10 @@
use alloc::vec::Vec;
-use crate::elf;
use crate::write::elf::writer::*;
use crate::write::string::StringId;
use crate::write::*;
use crate::AddressSize;
+use crate::{elf, pod};
#[derive(Clone, Copy)]
struct ComdatOffsets {
@@ -27,33 +27,88 @@ struct SymbolOffsets {
str_id: Option<StringId>,
}
+// Public methods.
+impl<'a> Object<'a> {
+ /// Add a property with a u32 value to the ELF ".note.gnu.property" section.
+ ///
+ /// Requires `feature = "elf"`.
+ pub fn add_elf_gnu_property_u32(&mut self, property: u32, value: u32) {
+ if self.format != BinaryFormat::Elf {
+ return;
+ }
+
+ let align = if self.elf_is_64() { 8 } else { 4 };
+ let mut data = Vec::with_capacity(32);
+ let n_name = b"GNU\0";
+ data.extend_from_slice(pod::bytes_of(&elf::NoteHeader32 {
+ n_namesz: U32::new(self.endian, n_name.len() as u32),
+ n_descsz: U32::new(self.endian, util::align(3 * 4, align) as u32),
+ n_type: U32::new(self.endian, elf::NT_GNU_PROPERTY_TYPE_0),
+ }));
+ data.extend_from_slice(n_name);
+ // This happens to already be aligned correctly.
+ debug_assert_eq!(util::align(data.len(), align), data.len());
+ data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, property)));
+ // Value size
+ data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, 4)));
+ data.extend_from_slice(pod::bytes_of(&U32::new(self.endian, value)));
+ util::write_align(&mut data, align);
+
+ let section = self.section_id(StandardSection::GnuProperty);
+ self.append_section_data(section, &data, align as u64);
+ }
+}
+
+// Private methods.
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::Data),
- 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,
+ SectionFlags::Elf {
+ sh_flags: u64::from(elf::SHF_ALLOC),
+ },
+ ),
}
}
@@ -151,6 +206,13 @@ impl<'a> Object<'a> {
}
}
+ pub(crate) fn elf_is_64(&self) -> bool {
+ match self.architecture.address_size().unwrap() {
+ AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false,
+ AddressSize::U64 => true,
+ }
+ }
+
pub(crate) fn elf_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> {
// Create reloc section header names so we can reference them.
let is_rela = self.elf_has_relocation_addend()?;
@@ -174,11 +236,7 @@ impl<'a> Object<'a> {
.collect();
// Start calculating offsets of everything.
- let is_64 = match self.architecture.address_size().unwrap() {
- AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false,
- AddressSize::U64 => true,
- };
- let mut writer = Writer::new(self.endian, is_64, buffer);
+ let mut writer = Writer::new(self.endian, self.elf_is_64(), buffer);
writer.reserve_file_header();
// Calculate size of section data.
@@ -321,12 +379,9 @@ impl<'a> Object<'a> {
}
}
for (index, section) in self.sections.iter().enumerate() {
- let len = section.data.len();
- if len != 0 {
- writer.write_align(section.align as usize);
- debug_assert_eq!(section_offsets[index].offset, writer.len());
- writer.write(&section.data);
- }
+ writer.write_align(section.align as usize);
+ debug_assert_eq!(section_offsets[index].offset, writer.len());
+ writer.write(&section.data);
}
// Write symbols.
@@ -767,7 +822,9 @@ impl<'a> Object<'a> {
} else {
match section.kind {
SectionKind::Text => elf::SHF_ALLOC | elf::SHF_EXECINSTR,
- SectionKind::Data => elf::SHF_ALLOC | elf::SHF_WRITE,
+ SectionKind::Data | SectionKind::ReadOnlyDataWithRel => {
+ elf::SHF_ALLOC | elf::SHF_WRITE
+ }
SectionKind::Tls => elf::SHF_ALLOC | elf::SHF_WRITE | elf::SHF_TLS,
SectionKind::UninitializedData => elf::SHF_ALLOC | elf::SHF_WRITE,
SectionKind::UninitializedTls => elf::SHF_ALLOC | elf::SHF_WRITE | elf::SHF_TLS,