pub struct Section { /* private fields */ }Expand description
One section: a name, a kind, flags, an alignment, its
contents (bytes, or for Bss only a size), an address, and the
Relocations that patch it.
Build one with new and the with_* methods, or grow its contents
in place with append and reserve, which
handle padding and alignment.
In a relocatable object the address is normally zero and offsets within the section are what symbols and relocations refer to. In an executable, every loadable section has its final address.
§Examples
use object_lang::{Section, SectionKind};
let mut rodata = Section::new(".rodata", SectionKind::ReadOnlyData);
let hello = rodata.append(b"hello\0", 1)?;
let table = rodata.append(&[1, 0, 0, 0, 2, 0, 0, 0], 8)?;
assert_eq!((hello, table), (0, 8)); // padded up to the table's alignment
assert_eq!(rodata.align(), 8);
assert_eq!(rodata.size(), 16);Implementations§
Source§impl Section
impl Section
Sourcepub fn new(name: impl Into<String>, kind: SectionKind) -> Self
pub fn new(name: impl Into<String>, kind: SectionKind) -> Self
An empty section of this kind, with the kind’s default flags, alignment 1, address 0, and no relocations.
§Examples
use object_lang::{Section, SectionKind};
let text = Section::new(".text", SectionKind::Text);
assert_eq!(text.flags(), SectionKind::Text.default_flags());
assert_eq!((text.align(), text.size()), (1, 0));Sourcepub fn with_flags(self, flags: SectionFlags) -> Self
pub fn with_flags(self, flags: SectionFlags) -> Self
Replaces the flags. validate checks that the kind
allows them.
§Examples
use object_lang::{Section, SectionFlags, SectionKind};
let tdata = Section::new(".tdata", SectionKind::Data)
.with_flags(SectionKind::Data.default_flags() | SectionFlags::TLS);
assert!(tdata.flags().contains(SectionFlags::TLS));Sourcepub fn with_align(self, align: u64) -> Self
pub fn with_align(self, align: u64) -> Self
Sourcepub fn with_entry_size(self, entry_size: u64) -> Self
pub fn with_entry_size(self, entry_size: u64) -> Self
Sets the size of each entry, for sections of fixed-size entries such as
MERGE sections (zero otherwise).
§Examples
use object_lang::{Section, SectionFlags, SectionKind};
let strings = Section::new(".rodata.str1.1", SectionKind::ReadOnlyData)
.with_flags(SectionFlags::ALLOC | SectionFlags::MERGE | SectionFlags::STRINGS)
.with_entry_size(1);
assert_eq!(strings.entry_size(), 1);Sourcepub fn with_address(self, address: u64) -> Self
pub fn with_address(self, address: u64) -> Self
Sets the address: the final load address in an executable.
§Examples
use object_lang::{Section, SectionKind};
let text = Section::new(".text", SectionKind::Text).with_address(0x40_1000);
assert_eq!(text.address(), 0x40_1000);Sourcepub fn with_bss_size(self, size: u64) -> Self
pub fn with_bss_size(self, size: u64) -> Self
Sourcepub fn append(&mut self, bytes: &[u8], align: u64) -> Result<u64, ModelError>
pub fn append(&mut self, bytes: &[u8], align: u64) -> Result<u64, ModelError>
Appends bytes, first padding with zeros to a multiple of align, and returns
the offset the bytes start at. Raises the section’s alignment to align if lower.
§Errors
ModelError::InvalidAlignmentifalignis not a power of two.ModelError::AppendToBssif the section isBss, which holds no bytes; usereserve.ModelError::SizeOverflowif the section would outgrow memory.
§Examples
use object_lang::{Section, SectionKind};
let mut text = Section::new(".text", SectionKind::Text);
assert_eq!(text.append(&[0x90], 1)?, 0);
assert_eq!(text.append(&[0xc3], 16)?, 16);
assert_eq!(text.size(), 17);Sourcepub fn reserve(&mut self, size: u64, align: u64) -> Result<u64, ModelError>
pub fn reserve(&mut self, size: u64, align: u64) -> Result<u64, ModelError>
Reserves size zero bytes at the next multiple of align and returns their
offset. A Bss section only grows its size; any other kind
appends zero bytes. Raises the section’s alignment to align if lower.
§Errors
ModelError::InvalidAlignmentifalignis not a power of two.ModelError::SizeOverflowif the size would overflow (or, for a section that holds bytes, not fit in memory).
§Examples
use object_lang::{Section, SectionKind};
let mut bss = Section::new(".bss", SectionKind::Bss);
assert_eq!(bss.reserve(4, 4)?, 0);
assert_eq!(bss.reserve(8, 8)?, 8);
assert_eq!(bss.size(), 16);Sourcepub fn add_relocation(&mut self, relocation: Relocation)
pub fn add_relocation(&mut self, relocation: Relocation)
Adds a relocation that patches this section. Checked by
validate.
§Examples
use object_lang::{
Architecture, Object, Relocation, RelocationTarget, Section, SectionKind, Symbol,
X86_64Reloc,
};
let mut obj = Object::relocatable(Architecture::X86_64);
let target = obj.add_symbol(Symbol::undefined("table"));
let mut data = Section::new(".data", SectionKind::Data).with_data(vec![0; 8]);
data.add_relocation(Relocation::new(0, X86_64Reloc::Abs64, RelocationTarget::Symbol(target), 0));
obj.add_section(data);
assert!(obj.validate().is_ok());Sourcepub fn name(&self) -> &str
pub fn name(&self) -> &str
The section’s name.
§Examples
use object_lang::{Section, SectionKind};
assert_eq!(Section::new(".text", SectionKind::Text).name(), ".text");Sourcepub const fn kind(&self) -> SectionKind
pub const fn kind(&self) -> SectionKind
What the section holds.
§Examples
use object_lang::{Section, SectionKind};
assert_eq!(Section::new(".bss", SectionKind::Bss).kind(), SectionKind::Bss);Sourcepub const fn flags(&self) -> SectionFlags
pub const fn flags(&self) -> SectionFlags
The section’s flags.
§Examples
use object_lang::{Section, SectionFlags, SectionKind};
assert!(Section::new(".text", SectionKind::Text).flags().contains(SectionFlags::EXEC));Sourcepub const fn align(&self) -> u64
pub const fn align(&self) -> u64
The alignment in bytes.
§Examples
use object_lang::{Section, SectionKind};
assert_eq!(Section::new(".data", SectionKind::Data).with_align(8).align(), 8);Sourcepub const fn entry_size(&self) -> u64
pub const fn entry_size(&self) -> u64
The size of each fixed-size entry, or zero.
§Examples
use object_lang::{Section, SectionKind};
assert_eq!(Section::new(".data", SectionKind::Data).entry_size(), 0);Sourcepub const fn address(&self) -> u64
pub const fn address(&self) -> u64
The address: the load address in an executable, normally zero in a relocatable object.
§Examples
use object_lang::{Section, SectionKind};
assert_eq!(Section::new(".text", SectionKind::Text).address(), 0);Sourcepub fn relocations(&self) -> &[Relocation]
pub fn relocations(&self) -> &[Relocation]
The relocations that patch this section, in the order added.
§Examples
use object_lang::{Section, SectionKind};
assert!(Section::new(".text", SectionKind::Text).relocations().is_empty());