summaryrefslogtreecommitdiffstats
path: root/third_party/rust/goblin/src/elf/section_header.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/goblin/src/elf/section_header.rs')
-rw-r--r--third_party/rust/goblin/src/elf/section_header.rs581
1 files changed, 581 insertions, 0 deletions
diff --git a/third_party/rust/goblin/src/elf/section_header.rs b/third_party/rust/goblin/src/elf/section_header.rs
new file mode 100644
index 0000000000..3bd891cc46
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/section_header.rs
@@ -0,0 +1,581 @@
+macro_rules! elf_section_header {
+ ($size:ident) => {
+ // XXX: Do not import scroll traits here.
+ // See: https://github.com/rust-lang/rust/issues/65090#issuecomment-538668155
+
+ #[repr(C)]
+ #[derive(Copy, Clone, Eq, PartialEq, Default)]
+ #[cfg_attr(
+ feature = "alloc",
+ derive(scroll::Pread, scroll::Pwrite, scroll::SizeWith)
+ )]
+ /// Section Headers are typically used by humans and static linkers for additional information or how to relocate the object
+ ///
+ /// **NOTE** section headers are strippable from a binary without any loss of portability/executability; _do not_ rely on them being there!
+ pub struct SectionHeader {
+ /// Section name (string tbl index)
+ pub sh_name: u32,
+ /// Section type
+ pub sh_type: u32,
+ /// Section flags
+ pub sh_flags: $size,
+ /// Section virtual addr at execution
+ pub sh_addr: $size,
+ /// Section file offset
+ pub sh_offset: $size,
+ /// Section size in bytes
+ pub sh_size: $size,
+ /// Link to another section
+ pub sh_link: u32,
+ /// Additional section information
+ pub sh_info: u32,
+ /// Section alignment
+ pub sh_addralign: $size,
+ /// Entry size if section holds table
+ pub sh_entsize: $size,
+ }
+
+ use plain;
+ // Declare that this is a plain type.
+ unsafe impl plain::Plain for SectionHeader {}
+
+ impl ::core::fmt::Debug for SectionHeader {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+ f.debug_struct("SectionHeader")
+ .field("sh_name", &self.sh_name)
+ .field("sh_type", &sht_to_str(self.sh_type))
+ .field("sh_flags", &format_args!("0x{:x}", self.sh_flags))
+ .field("sh_addr", &format_args!("0x{:x}", self.sh_addr))
+ .field("sh_offset", &format_args!("0x{:x}", self.sh_offset))
+ .field("sh_size", &format_args!("0x{:x}", self.sh_size))
+ .field("sh_link", &format_args!("0x{:x}", self.sh_link))
+ .field("sh_info", &format_args!("0x{:x}", self.sh_info))
+ .field("sh_addralign", &format_args!("0x{:x}", self.sh_addralign))
+ .field("sh_entsize", &format_args!("0x{:x}", self.sh_entsize))
+ .finish()
+ }
+ }
+ };
+}
+
+/// Undefined section.
+pub const SHN_UNDEF: u32 = 0;
+/// Start of reserved indices.
+pub const SHN_LORESERVE: u32 = 0xff00;
+/// Start of processor-specific.
+pub const SHN_LOPROC: u32 = 0xff00;
+/// Order section before all others (Solaris).
+pub const SHN_BEFORE: u32 = 0xff00;
+/// Order section after all others (Solaris).
+pub const SHN_AFTER: u32 = 0xff01;
+/// End of processor-specific.
+pub const SHN_HIPROC: u32 = 0xff1f;
+/// Start of OS-specific.
+pub const SHN_LOOS: u32 = 0xff20;
+/// End of OS-specific.
+pub const SHN_HIOS: u32 = 0xff3f;
+/// Associated symbol is absolute.
+pub const SHN_ABS: u32 = 0xfff1;
+/// Associated symbol is common.
+pub const SHN_COMMON: u32 = 0xfff2;
+/// Index is in extra table.
+pub const SHN_XINDEX: u32 = 0xffff;
+/// End of reserved indices.
+pub const SHN_HIRESERVE: u32 = 0xffff;
+
+// === Legal values for sh_type (section type). ===
+/// Section header table entry unused.
+pub const SHT_NULL: u32 = 0;
+/// Program data.
+pub const SHT_PROGBITS: u32 = 1;
+/// Symbol table.
+pub const SHT_SYMTAB: u32 = 2;
+/// String table.
+pub const SHT_STRTAB: u32 = 3;
+/// Relocation entries with addends.
+pub const SHT_RELA: u32 = 4;
+/// Symbol hash table.
+pub const SHT_HASH: u32 = 5;
+/// Dynamic linking information.
+pub const SHT_DYNAMIC: u32 = 6;
+/// Notes.
+pub const SHT_NOTE: u32 = 7;
+/// Program space with no data (bss).
+pub const SHT_NOBITS: u32 = 8;
+/// Relocation entries, no addends.
+pub const SHT_REL: u32 = 9;
+/// Reserved.
+pub const SHT_SHLIB: u32 = 10;
+/// Dynamic linker symbol table.
+pub const SHT_DYNSYM: u32 = 11;
+/// Array of constructors.
+pub const SHT_INIT_ARRAY: u32 = 14;
+/// Array of destructors.
+pub const SHT_FINI_ARRAY: u32 = 15;
+/// Array of pre-constructors.
+pub const SHT_PREINIT_ARRAY: u32 = 16;
+/// Section group.
+pub const SHT_GROUP: u32 = 17;
+/// Extended section indeces.
+pub const SHT_SYMTAB_SHNDX: u32 = 18;
+/// Number of defined types.
+pub const SHT_NUM: u32 = 19;
+/// Start OS-specific.
+pub const SHT_LOOS: u32 = 0x6000_0000;
+/// Object attributes.
+pub const SHT_GNU_ATTRIBUTES: u32 = 0x6fff_fff5;
+/// GNU-style hash table.
+pub const SHT_GNU_HASH: u32 = 0x6fff_fff6;
+/// Prelink library list.
+pub const SHT_GNU_LIBLIST: u32 = 0x6fff_fff7;
+/// Checksum for DSO content.
+pub const SHT_CHECKSUM: u32 = 0x6fff_fff8;
+/// Sun-specific low bound.
+pub const SHT_LOSUNW: u32 = 0x6fff_fffa;
+pub const SHT_SUNW_MOVE: u32 = 0x6fff_fffa;
+pub const SHT_SUNW_COMDAT: u32 = 0x6fff_fffb;
+pub const SHT_SUNW_SYMINFO: u32 = 0x6fff_fffc;
+/// Version definition section.
+pub const SHT_GNU_VERDEF: u32 = 0x6fff_fffd;
+/// Version needs section.
+pub const SHT_GNU_VERNEED: u32 = 0x6fff_fffe;
+/// Version symbol table.
+pub const SHT_GNU_VERSYM: u32 = 0x6fff_ffff;
+/// Sun-specific high bound.
+pub const SHT_HISUNW: u32 = 0x6fff_ffff;
+/// End OS-specific type.
+pub const SHT_HIOS: u32 = 0x6fff_ffff;
+/// Start of processor-specific.
+pub const SHT_LOPROC: u32 = 0x7000_0000;
+/// X86-64 unwind information.
+pub const SHT_X86_64_UNWIND: u32 = 0x7000_0001;
+/// End of processor-specific.
+pub const SHT_HIPROC: u32 = 0x7fff_ffff;
+/// Start of application-specific.
+pub const SHT_LOUSER: u32 = 0x8000_0000;
+/// End of application-specific.
+pub const SHT_HIUSER: u32 = 0x8fff_ffff;
+
+// Legal values for sh_flags (section flags)
+/// Writable.
+pub const SHF_WRITE: u32 = 0x1;
+/// Occupies memory during execution.
+pub const SHF_ALLOC: u32 = 0x2;
+/// Executable.
+pub const SHF_EXECINSTR: u32 = 0x4;
+/// Might be merged.
+pub const SHF_MERGE: u32 = 0x10;
+/// Contains nul-terminated strings.
+pub const SHF_STRINGS: u32 = 0x20;
+/// `sh_info' contains SHT index.
+pub const SHF_INFO_LINK: u32 = 0x40;
+/// Preserve order after combining.
+pub const SHF_LINK_ORDER: u32 = 0x80;
+/// Non-standard OS specific handling required.
+pub const SHF_OS_NONCONFORMING: u32 = 0x100;
+/// Section is member of a group.
+pub const SHF_GROUP: u32 = 0x200;
+/// Section hold thread-local data.
+pub const SHF_TLS: u32 = 0x400;
+/// Section with compressed data.
+pub const SHF_COMPRESSED: u32 = 0x800;
+/// OS-specific..
+pub const SHF_MASKOS: u32 = 0x0ff0_0000;
+/// Processor-specific.
+pub const SHF_MASKPROC: u32 = 0xf000_0000;
+/// Special ordering requirement (Solaris).
+pub const SHF_ORDERED: u32 = 1 << 30;
+/// Number of "regular" section header flags
+pub const SHF_NUM_REGULAR_FLAGS: usize = 12;
+/// Section is excluded unless referenced or allocated (Solaris).
+pub const SHF_EXCLUDE: u32 = 0x80000000; // 1U << 31
+
+pub const SHF_FLAGS: [u32; SHF_NUM_REGULAR_FLAGS] = [
+ SHF_WRITE,
+ SHF_ALLOC,
+ SHF_EXECINSTR,
+ SHF_MERGE,
+ SHF_STRINGS,
+ SHF_INFO_LINK,
+ SHF_LINK_ORDER,
+ SHF_OS_NONCONFORMING,
+ SHF_GROUP,
+ SHF_TLS,
+ SHF_COMPRESSED,
+ SHF_ORDERED,
+];
+
+pub fn sht_to_str(sht: u32) -> &'static str {
+ match sht {
+ SHT_NULL => "SHT_NULL",
+ SHT_PROGBITS => "SHT_PROGBITS",
+ SHT_SYMTAB => "SHT_SYMTAB",
+ SHT_STRTAB => "SHT_STRTAB",
+ SHT_RELA => "SHT_RELA",
+ SHT_HASH => "SHT_HASH",
+ SHT_DYNAMIC => "SHT_DYNAMIC",
+ SHT_NOTE => "SHT_NOTE",
+ SHT_NOBITS => "SHT_NOBITS",
+ SHT_REL => "SHT_REL",
+ SHT_SHLIB => "SHT_SHLIB",
+ SHT_DYNSYM => "SHT_DYNSYM",
+ SHT_INIT_ARRAY => "SHT_INIT_ARRAY",
+ SHT_FINI_ARRAY => "SHT_FINI_ARRAY",
+ SHT_PREINIT_ARRAY => "SHT_PREINIT_ARRAY",
+ SHT_GROUP => "SHT_GROUP",
+ SHT_SYMTAB_SHNDX => "SHT_SYMTAB_SHNDX",
+ SHT_NUM => "SHT_NUM",
+ SHT_LOOS => "SHT_LOOS",
+ SHT_GNU_ATTRIBUTES => "SHT_GNU_ATTRIBUTES",
+ SHT_GNU_HASH => "SHT_GNU_HASH",
+ SHT_GNU_LIBLIST => "SHT_GNU_LIBLIST",
+ SHT_CHECKSUM => "SHT_CHECKSUM",
+ SHT_SUNW_MOVE => "SHT_SUNW_MOVE",
+ SHT_SUNW_COMDAT => "SHT_SUNW_COMDAT",
+ SHT_SUNW_SYMINFO => "SHT_SUNW_SYMINFO",
+ SHT_GNU_VERDEF => "SHT_GNU_VERDEF",
+ SHT_GNU_VERNEED => "SHT_GNU_VERNEED",
+ SHT_GNU_VERSYM => "SHT_GNU_VERSYM",
+ SHT_LOPROC => "SHT_LOPROC",
+ SHT_X86_64_UNWIND => "SHT_X86_64_UNWIND",
+ SHT_HIPROC => "SHT_HIPROC",
+ SHT_LOUSER => "SHT_LOUSER",
+ SHT_HIUSER => "SHT_HIUSER",
+ _ => "UNKNOWN_SHT",
+ }
+}
+
+pub fn shf_to_str(shf: u32) -> &'static str {
+ match shf {
+ SHF_WRITE => "SHF_WRITE",
+ SHF_ALLOC => "SHF_ALLOC",
+ SHF_EXECINSTR => "SHF_EXECINSTR",
+ SHF_MERGE => "SHF_MERGE",
+ SHF_STRINGS => "SHF_STRINGS",
+ SHF_INFO_LINK => "SHF_INFO_LINK",
+ SHF_LINK_ORDER => "SHF_LINK_ORDER",
+ SHF_OS_NONCONFORMING => "SHF_OS_NONCONFORMING",
+ SHF_GROUP => "SHF_GROUP",
+ SHF_TLS => "SHF_TLS",
+ SHF_COMPRESSED => "SHF_COMPRESSED",
+ //SHF_MASKOS..SHF_MASKPROC => "SHF_OSFLAG",
+ SHF_ORDERED => "SHF_ORDERED",
+ _ => "SHF_UNKNOWN",
+ }
+}
+
+macro_rules! elf_section_header_std_impl { ($size:ty) => {
+
+ #[cfg(test)]
+ mod tests {
+ use super::*;
+ #[test]
+ fn size_of() {
+ assert_eq!(::std::mem::size_of::<SectionHeader>(), SIZEOF_SHDR);
+ }
+ }
+
+ if_alloc! {
+ use crate::elf::section_header::SectionHeader as ElfSectionHeader;
+
+ use plain::Plain;
+ use alloc::vec::Vec;
+
+ if_std! {
+ use crate::error::Result;
+
+ use std::fs::File;
+ use std::io::{Read, Seek};
+ use std::io::SeekFrom::Start;
+ }
+
+ impl From<SectionHeader> for ElfSectionHeader {
+ fn from(sh: SectionHeader) -> Self {
+ ElfSectionHeader {
+ sh_name: sh.sh_name as usize,
+ sh_type: sh.sh_type,
+ sh_flags: u64::from(sh.sh_flags),
+ sh_addr: u64::from(sh.sh_addr),
+ sh_offset: u64::from(sh.sh_offset),
+ sh_size: u64::from(sh.sh_size),
+ sh_link: sh.sh_link,
+ sh_info: sh.sh_info,
+ sh_addralign: u64::from(sh.sh_addralign),
+ sh_entsize: u64::from(sh.sh_entsize),
+ }
+ }
+ }
+ impl From<ElfSectionHeader> for SectionHeader {
+ fn from(sh: ElfSectionHeader) -> Self {
+ SectionHeader {
+ sh_name : sh.sh_name as u32,
+ sh_type : sh.sh_type,
+ sh_flags : sh.sh_flags as $size,
+ sh_addr : sh.sh_addr as $size,
+ sh_offset : sh.sh_offset as $size,
+ sh_size : sh.sh_size as $size,
+ sh_link : sh.sh_link,
+ sh_info : sh.sh_info,
+ sh_addralign: sh.sh_addralign as $size,
+ sh_entsize : sh.sh_entsize as $size,
+ }
+ }
+ }
+
+ impl SectionHeader {
+ // FIXME: > 65535 sections
+ pub fn from_bytes(bytes: &[u8], shnum: usize) -> Vec<SectionHeader> {
+ let mut shdrs = vec![SectionHeader::default(); shnum];
+ shdrs.copy_from_bytes(bytes).expect("buffer is too short for given number of entries");
+ shdrs
+ }
+
+ #[cfg(feature = "std")]
+ // FIXME: > 65535 sections
+ pub fn from_fd(fd: &mut File, offset: u64, shnum: usize) -> Result<Vec<SectionHeader>> {
+ let mut shdrs = vec![SectionHeader::default(); shnum];
+ fd.seek(Start(offset))?;
+ unsafe {
+ fd.read_exact(plain::as_mut_bytes(&mut *shdrs))?;
+ }
+ Ok(shdrs)
+ }
+ }
+ } // end if_alloc
+};}
+
+pub mod section_header32 {
+ pub use crate::elf::section_header::*;
+
+ elf_section_header!(u32);
+
+ pub const SIZEOF_SHDR: usize = 40;
+
+ elf_section_header_std_impl!(u32);
+}
+
+pub mod section_header64 {
+
+ pub use crate::elf::section_header::*;
+
+ elf_section_header!(u64);
+
+ pub const SIZEOF_SHDR: usize = 64;
+
+ elf_section_header_std_impl!(u64);
+}
+
+///////////////////////////////
+// Std/analysis/Unified Structs
+///////////////////////////////
+
+if_alloc! {
+ use crate::error;
+ use core::fmt;
+ use core::result;
+ use core::ops::Range;
+ use scroll::ctx;
+ use crate::container::{Container, Ctx};
+
+ #[cfg(feature = "endian_fd")]
+ use alloc::vec::Vec;
+
+ #[derive(Default, PartialEq, Clone)]
+ /// A unified SectionHeader - convertable to and from 32-bit and 64-bit variants
+ pub struct SectionHeader {
+ /// Section name (string tbl index)
+ pub sh_name: usize,
+ /// Section type
+ pub sh_type: u32,
+ /// Section flags
+ pub sh_flags: u64,
+ /// Section virtual addr at execution
+ pub sh_addr: u64,
+ /// Section file offset
+ pub sh_offset: u64,
+ /// Section size in bytes
+ pub sh_size: u64,
+ /// Link to another section
+ pub sh_link: u32,
+ /// Additional section information
+ pub sh_info: u32,
+ /// Section alignment
+ pub sh_addralign: u64,
+ /// Entry size if section holds table
+ pub sh_entsize: u64,
+ }
+
+ impl SectionHeader {
+ /// Return the size of the underlying program header, given a `container`
+ #[inline]
+ pub fn size(ctx: Ctx) -> usize {
+ use scroll::ctx::SizeWith;
+ Self::size_with(&ctx)
+ }
+ pub fn new() -> Self {
+ SectionHeader {
+ sh_name: 0,
+ sh_type: SHT_PROGBITS,
+ sh_flags: u64::from(SHF_ALLOC),
+ sh_addr: 0,
+ sh_offset: 0,
+ sh_size: 0,
+ sh_link: 0,
+ sh_info: 0,
+ sh_addralign: 2 << 8,
+ sh_entsize: 0,
+ }
+ }
+ /// Returns this section header's file offset range,
+ /// if the section occupies space in fhe file.
+ pub fn file_range(&self) -> Option<Range<usize>> {
+ // Sections with type SHT_NOBITS have no data in the file itself,
+ // they only exist in memory.
+ if self.sh_type == SHT_NOBITS {
+ None
+ } else {
+ Some(self.sh_offset as usize..(self.sh_offset as usize).saturating_add(self.sh_size as usize))
+ }
+ }
+ /// Returns this section header's virtual memory range
+ pub fn vm_range(&self) -> Range<usize> {
+ self.sh_addr as usize..(self.sh_addr as usize).saturating_add(self.sh_size as usize)
+ }
+ /// Parse `count` section headers from `bytes` at `offset`, using the given `ctx`
+ #[cfg(feature = "endian_fd")]
+ pub fn parse(bytes: &[u8], mut offset: usize, mut count: usize, ctx: Ctx) -> error::Result<Vec<SectionHeader>> {
+ use scroll::Pread;
+ // Zero offset means no section headers, not even the null section header.
+ if offset == 0 {
+ return Ok(Vec::new());
+ }
+ let empty_sh = bytes.gread_with::<SectionHeader>(&mut offset, ctx)?;
+ if count == 0 as usize {
+ // Zero count means either no section headers if offset is also zero (checked
+ // above), or the number of section headers overflows SHN_LORESERVE, in which
+ // case the count is stored in the sh_size field of the null section header.
+ count = empty_sh.sh_size as usize;
+ }
+
+ // Sanity check to avoid OOM
+ if count > bytes.len() / Self::size(ctx) {
+ return Err(error::Error::BufferTooShort(count, "section headers"));
+ }
+ let mut section_headers = Vec::with_capacity(count);
+ section_headers.push(empty_sh);
+ for _ in 1..count {
+ let shdr = bytes.gread_with(&mut offset, ctx)?;
+ section_headers.push(shdr);
+ }
+ Ok(section_headers)
+ }
+ pub fn check_size(&self, size: usize) -> error::Result<()> {
+ if self.sh_type == SHT_NOBITS {
+ return Ok(());
+ }
+ let (end, overflow) = self.sh_offset.overflowing_add(self.sh_size);
+ if overflow || end > size as u64 {
+ let message = format!("Section {} size ({}) + offset ({}) is out of bounds. Overflowed: {}",
+ self.sh_name, self.sh_offset, self.sh_size, overflow);
+ return Err(error::Error::Malformed(message));
+ }
+ let (_, overflow) = self.sh_addr.overflowing_add(self.sh_size);
+ if overflow {
+ let message = format!("Section {} size ({}) + addr ({}) is out of bounds. Overflowed: {}",
+ self.sh_name, self.sh_addr, self.sh_size, overflow);
+ return Err(error::Error::Malformed(message));
+ }
+ Ok(())
+ }
+ pub fn is_relocation(&self) -> bool {
+ self.sh_type == SHT_RELA
+ }
+ pub fn is_executable(&self) -> bool {
+ self.is_alloc() && self.sh_flags as u32 & SHF_EXECINSTR == SHF_EXECINSTR
+ }
+ pub fn is_writable(&self) -> bool {
+ self.is_alloc() && self.sh_flags as u32 & SHF_WRITE == SHF_WRITE
+ }
+ pub fn is_alloc(&self) -> bool {
+ self.sh_flags as u32 & SHF_ALLOC == SHF_ALLOC
+ }
+ }
+
+ impl fmt::Debug for SectionHeader {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("SectionHeader")
+ .field("sh_name", &self.sh_name)
+ .field("sh_type", &sht_to_str(self.sh_type))
+ .field("sh_flags", &format_args!("0x{:x}", self.sh_flags))
+ .field("sh_addr", &format_args!("0x{:x}", self.sh_addr))
+ .field("sh_offset", &format_args!("0x{:x}", self.sh_offset))
+ .field("sh_size", &format_args!("0x{:x}", self.sh_size))
+ .field("sh_link", &format_args!("0x{:x}", self.sh_link))
+ .field("sh_info", &format_args!("0x{:x}", self.sh_info))
+ .field("sh_addralign", &format_args!("0x{:x}", self.sh_addralign))
+ .field("sh_entsize", &format_args!("0x{:x}", self.sh_entsize))
+ .finish()
+ }
+ }
+
+ impl ctx::SizeWith<Ctx> for SectionHeader {
+ fn size_with( &Ctx { container, .. }: &Ctx) -> usize {
+ match container {
+ Container::Little => {
+ section_header32::SIZEOF_SHDR
+ },
+ Container::Big => {
+ section_header64::SIZEOF_SHDR
+ },
+ }
+ }
+ }
+
+ impl<'a> ctx::TryFromCtx<'a, Ctx> for SectionHeader {
+ type Error = crate::error::Error;
+ fn try_from_ctx(bytes: &'a [u8], Ctx {container, le}: Ctx) -> result::Result<(Self, usize), Self::Error> {
+ use scroll::Pread;
+ let res = match container {
+ Container::Little => {
+ (bytes.pread_with::<section_header32::SectionHeader>(0, le)?.into(), section_header32::SIZEOF_SHDR)
+ },
+ Container::Big => {
+ (bytes.pread_with::<section_header64::SectionHeader>(0, le)?.into(), section_header64::SIZEOF_SHDR)
+ }
+ };
+ Ok(res)
+ }
+ }
+
+ impl ctx::TryIntoCtx<Ctx> for SectionHeader {
+ type Error = crate::error::Error;
+ fn try_into_ctx(self, bytes: &mut [u8], Ctx {container, le}: Ctx) -> result::Result<usize, Self::Error> {
+ use scroll::Pwrite;
+ match container {
+ Container::Little => {
+ let shdr: section_header32::SectionHeader = self.into();
+ Ok(bytes.pwrite_with(shdr, 0, le)?)
+ },
+ Container::Big => {
+ let shdr: section_header64::SectionHeader = self.into();
+ Ok(bytes.pwrite_with(shdr, 0, le)?)
+ }
+ }
+ }
+ }
+ impl ctx::IntoCtx<Ctx> for SectionHeader {
+ fn into_ctx(self, bytes: &mut [u8], Ctx {container, le}: Ctx) {
+ use scroll::Pwrite;
+ match container {
+ Container::Little => {
+ let shdr: section_header32::SectionHeader = self.into();
+ bytes.pwrite_with(shdr, 0, le).unwrap();
+ },
+ Container::Big => {
+ let shdr: section_header64::SectionHeader = self.into();
+ bytes.pwrite_with(shdr, 0, le).unwrap();
+ }
+ }
+ }
+ }
+} // end if_alloc