pub struct Writer<'a> { /* private fields */ }
Expand description
A helper for writing ELF files.
Writing uses a two phase approach. The first phase builds up all of the information that may need to be known ahead of time:
- build string tables
- reserve section indices
- reserve symbol indices
- reserve file ranges for headers and sections
Some of the information has ordering requirements. For example, strings must be added to string tables before reserving the file range for the string table. Symbol indices must be reserved after reserving the section indices they reference. There are debug asserts to check some of these requirements.
The second phase writes everything out in order. Thus the caller must ensure writing is in the same order that file ranges were reserved. There are debug asserts to assist with checking this.
Implementations§
source§impl<'a> Writer<'a>
impl<'a> Writer<'a>
sourcepub fn new(
endian: Endianness,
is_64: bool,
buffer: &'a mut dyn WritableBuffer
) -> Self
pub fn new( endian: Endianness, is_64: bool, buffer: &'a mut dyn WritableBuffer ) -> Self
Create a new Writer
for the given endianness and ELF class.
sourcepub fn reserved_len(&self) -> usize
pub fn reserved_len(&self) -> usize
Return the current file length that has been reserved.
sourcepub fn reserve(&mut self, len: usize, align_start: usize) -> usize
pub fn reserve(&mut self, len: usize, align_start: usize) -> usize
Reserve a file range with the given size and starting alignment.
Returns the aligned offset of the start of the range.
sourcepub fn write_align(&mut self, align_start: usize)
pub fn write_align(&mut self, align_start: usize)
Write alignment padding bytes.
sourcepub fn reserve_until(&mut self, offset: usize)
pub fn reserve_until(&mut self, offset: usize)
Reserve the file range up to the given file offset.
sourcepub fn reserve_file_header(&mut self)
pub fn reserve_file_header(&mut self)
Reserve the range for the file header.
This must be at the start of the file.
sourcepub fn write_file_header(&mut self, header: &FileHeader) -> Result<()>
pub fn write_file_header(&mut self, header: &FileHeader) -> Result<()>
Write the file header.
This must be at the start of the file.
Fields that can be derived from known information are automatically set by this function.
sourcepub fn reserve_program_headers(&mut self, num: u32)
pub fn reserve_program_headers(&mut self, num: u32)
Reserve the range for the program headers.
sourcepub fn write_align_program_headers(&mut self)
pub fn write_align_program_headers(&mut self)
Write alignment padding bytes prior to the program headers.
sourcepub fn write_program_header(&mut self, header: &ProgramHeader)
pub fn write_program_header(&mut self, header: &ProgramHeader)
Write a program header.
sourcepub fn reserve_null_section_index(&mut self) -> SectionIndex
pub fn reserve_null_section_index(&mut self) -> SectionIndex
Reserve the section index for the null section header.
The null section header is usually automatically reserved, but this can be used to force an empty section table.
This must be called before Self::reserve_section_headers
.
sourcepub fn reserve_section_index(&mut self) -> SectionIndex
pub fn reserve_section_index(&mut self) -> SectionIndex
Reserve a section table index.
Automatically also reserves the null section header if required.
This must be called before Self::reserve_section_headers
.
sourcepub fn reserve_section_headers(&mut self)
pub fn reserve_section_headers(&mut self)
Reserve the range for the section headers.
This function does nothing if no sections were reserved.
This must be called after Self::reserve_section_index
and other functions that reserve section indices.
sourcepub fn write_null_section_header(&mut self)
pub fn write_null_section_header(&mut self)
Write the null section header.
This must be the first section header that is written. This function does nothing if no sections were reserved.
sourcepub fn write_section_header(&mut self, section: &SectionHeader)
pub fn write_section_header(&mut self, section: &SectionHeader)
Write a section header.
sourcepub fn add_section_name(&mut self, name: &'a [u8]) -> StringId
pub fn add_section_name(&mut self, name: &'a [u8]) -> StringId
Add a section name to the section header string table.
This will be stored in the .shstrtab
section.
This must be called before Self::reserve_shstrtab
.
sourcepub fn reserve_shstrtab(&mut self)
pub fn reserve_shstrtab(&mut self)
Reserve the range for the section header string table.
This range is used for a section named .shstrtab
.
This function does nothing if no sections were reserved.
This must be called after Self::add_section_name
.
and other functions that reserve section names and indices.
sourcepub fn write_shstrtab(&mut self)
pub fn write_shstrtab(&mut self)
Write the section header string table.
This function does nothing if the section was not reserved.
sourcepub fn reserve_shstrtab_section_index(&mut self) -> SectionIndex
pub fn reserve_shstrtab_section_index(&mut self) -> SectionIndex
Reserve the section index for the section header string table.
This must be called before Self::reserve_shstrtab
and Self::reserve_section_headers
.
sourcepub fn write_shstrtab_section_header(&mut self)
pub fn write_shstrtab_section_header(&mut self)
Write the section header for the section header string table.
This function does nothing if the section index was not reserved.
sourcepub fn add_string(&mut self, name: &'a [u8]) -> StringId
pub fn add_string(&mut self, name: &'a [u8]) -> StringId
Add a string to the string table.
This will be stored in the .strtab
section.
This must be called before Self::reserve_strtab
.
sourcepub fn strtab_needed(&self) -> bool
pub fn strtab_needed(&self) -> bool
Return true if .strtab
is needed.
sourcepub fn reserve_strtab(&mut self)
pub fn reserve_strtab(&mut self)
Reserve the range for the string table.
This range is used for a section named .strtab
.
This function does nothing if no strings or symbols were defined.
This must be called after Self::add_string
.
sourcepub fn write_strtab(&mut self)
pub fn write_strtab(&mut self)
Write the string table.
This function does nothing if the section was not reserved.
sourcepub fn reserve_strtab_section_index(&mut self) -> SectionIndex
pub fn reserve_strtab_section_index(&mut self) -> SectionIndex
Reserve the section index for the string table.
This must be called before Self::reserve_section_headers
.
sourcepub fn write_strtab_section_header(&mut self)
pub fn write_strtab_section_header(&mut self)
Write the section header for the string table.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_null_symbol_index(&mut self) -> SymbolIndex
pub fn reserve_null_symbol_index(&mut self) -> SymbolIndex
Reserve the null symbol table entry.
This will be stored in the .symtab
section.
The null symbol table entry is usually automatically reserved, but this can be used to force an empty symbol table.
This must be called before Self::reserve_symtab
.
sourcepub fn reserve_symbol_index(
&mut self,
section_index: Option<SectionIndex>
) -> SymbolIndex
pub fn reserve_symbol_index( &mut self, section_index: Option<SectionIndex> ) -> SymbolIndex
Reserve a symbol table entry.
This will be stored in the .symtab
section.
section_index
is used to determine whether .symtab_shndx
is required.
Automatically also reserves the null symbol if required. Callers may assume that the returned indices will be sequential starting at 1.
This must be called before Self::reserve_symtab
and
Self::reserve_symtab_shndx
.
sourcepub fn symbol_count(&self) -> u32
pub fn symbol_count(&self) -> u32
Return the number of reserved symbol table entries.
Includes the null symbol.
sourcepub fn reserve_symtab(&mut self)
pub fn reserve_symtab(&mut self)
Reserve the range for the symbol table.
This range is used for a section named .symtab
.
This function does nothing if no symbols were reserved.
This must be called after Self::reserve_symbol_index
.
sourcepub fn write_null_symbol(&mut self)
pub fn write_null_symbol(&mut self)
Write the null symbol.
This must be the first symbol that is written. This function does nothing if no symbols were reserved.
sourcepub fn write_symbol(&mut self, sym: &Sym)
pub fn write_symbol(&mut self, sym: &Sym)
Write a symbol.
sourcepub fn reserve_symtab_section_index(&mut self) -> SectionIndex
pub fn reserve_symtab_section_index(&mut self) -> SectionIndex
Reserve the section index for the symbol table.
This must be called before Self::reserve_section_headers
.
sourcepub fn symtab_index(&mut self) -> SectionIndex
pub fn symtab_index(&mut self) -> SectionIndex
Return the section index of the symbol table.
sourcepub fn write_symtab_section_header(&mut self, num_local: u32)
pub fn write_symtab_section_header(&mut self, num_local: u32)
Write the section header for the symbol table.
This function does nothing if the section index was not reserved.
sourcepub fn symtab_shndx_needed(&self) -> bool
pub fn symtab_shndx_needed(&self) -> bool
Return true if .symtab_shndx
is needed.
sourcepub fn reserve_symtab_shndx(&mut self)
pub fn reserve_symtab_shndx(&mut self)
Reserve the range for the extended section indices for the symbol table.
This range is used for a section named .symtab_shndx
.
This also reserves a section index.
This function does nothing if extended section indices are not needed.
This must be called after Self::reserve_symbol_index
.
sourcepub fn write_symtab_shndx(&mut self)
pub fn write_symtab_shndx(&mut self)
Write the extended section indices for the symbol table.
This function does nothing if the section was not reserved.
sourcepub fn reserve_symtab_shndx_section_index(&mut self) -> SectionIndex
pub fn reserve_symtab_shndx_section_index(&mut self) -> SectionIndex
Reserve the section index for the extended section indices symbol table.
You should check Self::symtab_shndx_needed
before calling this
unless you have other means of knowing if this section is needed.
This must be called before Self::reserve_section_headers
.
sourcepub fn write_symtab_shndx_section_header(&mut self)
pub fn write_symtab_shndx_section_header(&mut self)
Write the section header for the extended section indices for the symbol table.
This function does nothing if the section index was not reserved.
sourcepub fn add_dynamic_string(&mut self, name: &'a [u8]) -> StringId
pub fn add_dynamic_string(&mut self, name: &'a [u8]) -> StringId
Add a string to the dynamic string table.
This will be stored in the .dynstr
section.
This must be called before Self::reserve_dynstr
.
sourcepub fn get_dynamic_string(&self, name: &'a [u8]) -> StringId
pub fn get_dynamic_string(&self, name: &'a [u8]) -> StringId
Get a string that was previously added to the dynamic string table.
Panics if the string was not added.
sourcepub fn dynstr_needed(&self) -> bool
pub fn dynstr_needed(&self) -> bool
Return true if .dynstr
is needed.
sourcepub fn reserve_dynstr(&mut self)
pub fn reserve_dynstr(&mut self)
Reserve the range for the dynamic string table.
This range is used for a section named .dynstr
.
This function does nothing if no dynamic strings or symbols were defined.
This must be called after Self::add_dynamic_string
.
sourcepub fn write_dynstr(&mut self)
pub fn write_dynstr(&mut self)
Write the dynamic string table.
This function does nothing if the section was not reserved.
sourcepub fn reserve_dynstr_section_index(&mut self) -> SectionIndex
pub fn reserve_dynstr_section_index(&mut self) -> SectionIndex
Reserve the section index for the dynamic string table.
This must be called before Self::reserve_section_headers
.
sourcepub fn dynstr_index(&mut self) -> SectionIndex
pub fn dynstr_index(&mut self) -> SectionIndex
Return the section index of the dynamic string table.
sourcepub fn write_dynstr_section_header(&mut self, sh_addr: u64)
pub fn write_dynstr_section_header(&mut self, sh_addr: u64)
Write the section header for the dynamic string table.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_null_dynamic_symbol_index(&mut self) -> SymbolIndex
pub fn reserve_null_dynamic_symbol_index(&mut self) -> SymbolIndex
Reserve the null dynamic symbol table entry.
This will be stored in the .dynsym
section.
The null dynamic symbol table entry is usually automatically reserved, but this can be used to force an empty dynamic symbol table.
This must be called before Self::reserve_dynsym
.
sourcepub fn reserve_dynamic_symbol_index(&mut self) -> SymbolIndex
pub fn reserve_dynamic_symbol_index(&mut self) -> SymbolIndex
Reserve a dynamic symbol table entry.
This will be stored in the .dynsym
section.
Automatically also reserves the null symbol if required. Callers may assume that the returned indices will be sequential starting at 1.
This must be called before Self::reserve_dynsym
.
sourcepub fn dynamic_symbol_count(&mut self) -> u32
pub fn dynamic_symbol_count(&mut self) -> u32
Return the number of reserved dynamic symbols.
Includes the null symbol.
sourcepub fn reserve_dynsym(&mut self)
pub fn reserve_dynsym(&mut self)
Reserve the range for the dynamic symbol table.
This range is used for a section named .dynsym
.
This function does nothing if no dynamic symbols were reserved.
This must be called after Self::reserve_dynamic_symbol_index
.
sourcepub fn write_null_dynamic_symbol(&mut self)
pub fn write_null_dynamic_symbol(&mut self)
Write the null dynamic symbol.
This must be the first dynamic symbol that is written. This function does nothing if no dynamic symbols were reserved.
sourcepub fn write_dynamic_symbol(&mut self, sym: &Sym)
pub fn write_dynamic_symbol(&mut self, sym: &Sym)
Write a dynamic symbol.
sourcepub fn reserve_dynsym_section_index(&mut self) -> SectionIndex
pub fn reserve_dynsym_section_index(&mut self) -> SectionIndex
Reserve the section index for the dynamic symbol table.
This must be called before Self::reserve_section_headers
.
sourcepub fn dynsym_index(&mut self) -> SectionIndex
pub fn dynsym_index(&mut self) -> SectionIndex
Return the section index of the dynamic symbol table.
sourcepub fn write_dynsym_section_header(&mut self, sh_addr: u64, num_local: u32)
pub fn write_dynsym_section_header(&mut self, sh_addr: u64, num_local: u32)
Write the section header for the dynamic symbol table.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_dynamic(&mut self, dynamic_num: usize)
pub fn reserve_dynamic(&mut self, dynamic_num: usize)
Reserve the range for the .dynamic
section.
This function does nothing if dynamic_num
is zero.
sourcepub fn write_align_dynamic(&mut self)
pub fn write_align_dynamic(&mut self)
Write alignment padding bytes prior to the .dynamic
section.
This function does nothing if the section was not reserved.
sourcepub fn write_dynamic_string(&mut self, tag: u32, id: StringId)
pub fn write_dynamic_string(&mut self, tag: u32, id: StringId)
Write a dynamic string entry.
sourcepub fn write_dynamic(&mut self, d_tag: u32, d_val: u64)
pub fn write_dynamic(&mut self, d_tag: u32, d_val: u64)
Write a dynamic value entry.
sourcepub fn reserve_dynamic_section_index(&mut self) -> SectionIndex
pub fn reserve_dynamic_section_index(&mut self) -> SectionIndex
Reserve the section index for the dynamic table.
sourcepub fn write_dynamic_section_header(&mut self, sh_addr: u64)
pub fn write_dynamic_section_header(&mut self, sh_addr: u64)
Write the section header for the dynamic table.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_hash(&mut self, bucket_count: u32, chain_count: u32)
pub fn reserve_hash(&mut self, bucket_count: u32, chain_count: u32)
Reserve a file range for a SysV hash section.
symbol_count
is the number of symbols in the hash,
not the total number of symbols.
sourcepub fn write_hash<F>(&mut self, bucket_count: u32, chain_count: u32, hash: F)where
F: Fn(u32) -> Option<u32>,
pub fn write_hash<F>(&mut self, bucket_count: u32, chain_count: u32, hash: F)where F: Fn(u32) -> Option<u32>,
Write a SysV hash section.
chain_count
is the number of symbols in the hash.
The argument to hash
will be in the range 0..chain_count
.
sourcepub fn reserve_hash_section_index(&mut self) -> SectionIndex
pub fn reserve_hash_section_index(&mut self) -> SectionIndex
Reserve the section index for the SysV hash table.
sourcepub fn write_hash_section_header(&mut self, sh_addr: u64)
pub fn write_hash_section_header(&mut self, sh_addr: u64)
Write the section header for the SysV hash table.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_gnu_hash(
&mut self,
bloom_count: u32,
bucket_count: u32,
symbol_count: u32
)
pub fn reserve_gnu_hash( &mut self, bloom_count: u32, bucket_count: u32, symbol_count: u32 )
Reserve a file range for a GNU hash section.
symbol_count
is the number of symbols in the hash,
not the total number of symbols.
sourcepub fn write_gnu_hash<F>(
&mut self,
symbol_base: u32,
bloom_shift: u32,
bloom_count: u32,
bucket_count: u32,
symbol_count: u32,
hash: F
)where
F: Fn(u32) -> u32,
pub fn write_gnu_hash<F>( &mut self, symbol_base: u32, bloom_shift: u32, bloom_count: u32, bucket_count: u32, symbol_count: u32, hash: F )where F: Fn(u32) -> u32,
Write a GNU hash section.
symbol_count
is the number of symbols in the hash.
The argument to hash
will be in the range 0..symbol_count
.
This requires that symbols are already sorted by bucket.
sourcepub fn reserve_gnu_hash_section_index(&mut self) -> SectionIndex
pub fn reserve_gnu_hash_section_index(&mut self) -> SectionIndex
Reserve the section index for the GNU hash table.
sourcepub fn write_gnu_hash_section_header(&mut self, sh_addr: u64)
pub fn write_gnu_hash_section_header(&mut self, sh_addr: u64)
Write the section header for the GNU hash table.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_gnu_versym(&mut self)
pub fn reserve_gnu_versym(&mut self)
Reserve the range for the .gnu.version
section.
This function does nothing if no dynamic symbols were reserved.
sourcepub fn write_null_gnu_versym(&mut self)
pub fn write_null_gnu_versym(&mut self)
Write the null symbol version entry.
This must be the first symbol version that is written. This function does nothing if no dynamic symbols were reserved.
sourcepub fn write_gnu_versym(&mut self, versym: u16)
pub fn write_gnu_versym(&mut self, versym: u16)
Write a symbol version entry.
sourcepub fn reserve_gnu_versym_section_index(&mut self) -> SectionIndex
pub fn reserve_gnu_versym_section_index(&mut self) -> SectionIndex
Reserve the section index for the .gnu.version
section.
sourcepub fn write_gnu_versym_section_header(&mut self, sh_addr: u64)
pub fn write_gnu_versym_section_header(&mut self, sh_addr: u64)
Write the section header for the .gnu.version
section.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_gnu_verdef(&mut self, verdef_count: usize, verdaux_count: usize)
pub fn reserve_gnu_verdef(&mut self, verdef_count: usize, verdaux_count: usize)
Reserve the range for the .gnu.version_d
section.
sourcepub fn write_align_gnu_verdef(&mut self)
pub fn write_align_gnu_verdef(&mut self)
Write alignment padding bytes prior to a .gnu.version_d
section.
sourcepub fn write_gnu_verdef(&mut self, verdef: &Verdef)
pub fn write_gnu_verdef(&mut self, verdef: &Verdef)
Write a version definition entry.
sourcepub fn write_gnu_verdaux(&mut self, name: StringId)
pub fn write_gnu_verdaux(&mut self, name: StringId)
Write a version definition auxiliary entry.
sourcepub fn reserve_gnu_verdef_section_index(&mut self) -> SectionIndex
pub fn reserve_gnu_verdef_section_index(&mut self) -> SectionIndex
Reserve the section index for the .gnu.version_d
section.
sourcepub fn write_gnu_verdef_section_header(&mut self, sh_addr: u64)
pub fn write_gnu_verdef_section_header(&mut self, sh_addr: u64)
Write the section header for the .gnu.version_d
section.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_gnu_verneed(
&mut self,
verneed_count: usize,
vernaux_count: usize
)
pub fn reserve_gnu_verneed( &mut self, verneed_count: usize, vernaux_count: usize )
Reserve the range for the .gnu.version_r
section.
sourcepub fn write_align_gnu_verneed(&mut self)
pub fn write_align_gnu_verneed(&mut self)
Write alignment padding bytes prior to a .gnu.version_r
section.
sourcepub fn write_gnu_verneed(&mut self, verneed: &Verneed)
pub fn write_gnu_verneed(&mut self, verneed: &Verneed)
Write a version need entry.
sourcepub fn write_gnu_vernaux(&mut self, vernaux: &Vernaux)
pub fn write_gnu_vernaux(&mut self, vernaux: &Vernaux)
Write a version need auxiliary entry.
sourcepub fn reserve_gnu_verneed_section_index(&mut self) -> SectionIndex
pub fn reserve_gnu_verneed_section_index(&mut self) -> SectionIndex
Reserve the section index for the .gnu.version_r
section.
sourcepub fn write_gnu_verneed_section_header(&mut self, sh_addr: u64)
pub fn write_gnu_verneed_section_header(&mut self, sh_addr: u64)
Write the section header for the .gnu.version_r
section.
This function does nothing if the section index was not reserved.
sourcepub fn reserve_gnu_attributes_section_index(&mut self) -> SectionIndex
pub fn reserve_gnu_attributes_section_index(&mut self) -> SectionIndex
Reserve the section index for the .gnu.attributes
section.
sourcepub fn reserve_gnu_attributes(&mut self, gnu_attributes_size: usize)
pub fn reserve_gnu_attributes(&mut self, gnu_attributes_size: usize)
Reserve the range for the .gnu.attributes
section.
sourcepub fn write_gnu_attributes_section_header(&mut self)
pub fn write_gnu_attributes_section_header(&mut self)
Write the section header for the .gnu.attributes
section.
This function does nothing if the section index was not reserved.
sourcepub fn write_gnu_attributes(&mut self, data: &[u8])
pub fn write_gnu_attributes(&mut self, data: &[u8])
Write the data for the .gnu.attributes
section.
sourcepub fn reserve_relocations(&mut self, count: usize, is_rela: bool) -> usize
pub fn reserve_relocations(&mut self, count: usize, is_rela: bool) -> usize
Reserve a file range for the given number of relocations.
Returns the offset of the range.
sourcepub fn write_align_relocation(&mut self)
pub fn write_align_relocation(&mut self)
Write alignment padding bytes prior to a relocation section.
sourcepub fn write_relocation(&mut self, is_rela: bool, rel: &Rel)
pub fn write_relocation(&mut self, is_rela: bool, rel: &Rel)
Write a relocation.
sourcepub fn write_relocation_section_header(
&mut self,
name: StringId,
section: SectionIndex,
symtab: SectionIndex,
offset: usize,
count: usize,
is_rela: bool
)
pub fn write_relocation_section_header( &mut self, name: StringId, section: SectionIndex, symtab: SectionIndex, offset: usize, count: usize, is_rela: bool )
Write the section header for a relocation section.
section
is the index of the section the relocations apply to,
or 0 if none.
symtab
is the index of the symbol table the relocations refer to,
or 0 if none.
offset
is the file offset of the relocations.
sourcepub fn reserve_comdat(&mut self, count: usize) -> usize
pub fn reserve_comdat(&mut self, count: usize) -> usize
Reserve a file range for a COMDAT section.
count
is the number of sections in the COMDAT group.
Returns the offset of the range.
sourcepub fn write_comdat_header(&mut self)
pub fn write_comdat_header(&mut self)
Write GRP_COMDAT
at the start of the COMDAT section.
sourcepub fn write_comdat_entry(&mut self, entry: SectionIndex)
pub fn write_comdat_entry(&mut self, entry: SectionIndex)
Write an entry in a COMDAT section.
sourcepub fn write_comdat_section_header(
&mut self,
name: StringId,
symtab: SectionIndex,
symbol: SymbolIndex,
offset: usize,
count: usize
)
pub fn write_comdat_section_header( &mut self, name: StringId, symtab: SectionIndex, symbol: SymbolIndex, offset: usize, count: usize )
Write the section header for a COMDAT section.
sourcepub fn attributes_writer(&self) -> AttributesWriter
pub fn attributes_writer(&self) -> AttributesWriter
Return a helper for writing an attributes section.