Implement SectionHeader parsing with the Parse trait
Also move SectionHeader into section.rs Also, refactor the code for reading section data and section names from the section string table to be more idiomatic
This commit is contained in:
parent
ae9e24420d
commit
fcac7d79cc
94
src/lib.rs
94
src/lib.rs
@ -6,6 +6,7 @@ use std::io::{Read, Seek};
|
||||
pub mod gabi;
|
||||
pub mod types;
|
||||
pub mod segment;
|
||||
pub mod section;
|
||||
pub mod parse;
|
||||
|
||||
use parse::Parse;
|
||||
@ -159,86 +160,32 @@ impl File {
|
||||
let mut sections = Vec::<Section>::default();
|
||||
|
||||
// Parse the section headers
|
||||
let mut name_idxs: Vec<u32> = Vec::new();
|
||||
io_file.seek(io::SeekFrom::Start(ehdr.e_shoff))?;
|
||||
for _ in 0..ehdr.e_shnum {
|
||||
let name: String = String::new();
|
||||
let shtype: types::SectionType;
|
||||
let flags: types::SectionFlag;
|
||||
let addr: u64;
|
||||
let offset: u64;
|
||||
let size: u64;
|
||||
let link: u32;
|
||||
let info: u32;
|
||||
let addralign: u64;
|
||||
let entsize: u64;
|
||||
|
||||
name_idxs.push(utils::read_u32(ehdr.endianness, io_file)?);
|
||||
shtype = types::SectionType(utils::read_u32(ehdr.endianness, io_file)?);
|
||||
if ehdr.class == gabi::ELFCLASS32 {
|
||||
flags = types::SectionFlag(utils::read_u32(ehdr.endianness, io_file)? as u64);
|
||||
addr = utils::read_u32(ehdr.endianness, io_file)? as u64;
|
||||
offset = utils::read_u32(ehdr.endianness, io_file)? as u64;
|
||||
size = utils::read_u32(ehdr.endianness, io_file)? as u64;
|
||||
link = utils::read_u32(ehdr.endianness, io_file)?;
|
||||
info = utils::read_u32(ehdr.endianness, io_file)?;
|
||||
addralign = utils::read_u32(ehdr.endianness, io_file)? as u64;
|
||||
entsize = utils::read_u32(ehdr.endianness, io_file)? as u64;
|
||||
} else {
|
||||
flags = types::SectionFlag(utils::read_u64(ehdr.endianness, io_file)?);
|
||||
addr = utils::read_u64(ehdr.endianness, io_file)?;
|
||||
offset = utils::read_u64(ehdr.endianness, io_file)?;
|
||||
size = utils::read_u64(ehdr.endianness, io_file)?;
|
||||
link = utils::read_u32(ehdr.endianness, io_file)?;
|
||||
info = utils::read_u32(ehdr.endianness, io_file)?;
|
||||
addralign = utils::read_u64(ehdr.endianness, io_file)?;
|
||||
entsize = utils::read_u64(ehdr.endianness, io_file)?;
|
||||
}
|
||||
|
||||
sections.push(Section {
|
||||
shdr: types::SectionHeader {
|
||||
name: name,
|
||||
shtype: shtype,
|
||||
flags: flags,
|
||||
addr: addr,
|
||||
offset: offset,
|
||||
size: size,
|
||||
link: link,
|
||||
info: info,
|
||||
addralign: addralign,
|
||||
entsize: entsize,
|
||||
},
|
||||
let shdr = section::SectionHeader::parse(ehdr.endianness, ehdr.class, io_file)?;
|
||||
sections.push(
|
||||
Section {
|
||||
name: String::new(),
|
||||
shdr: shdr,
|
||||
data: Vec::new(),
|
||||
});
|
||||
}
|
||||
|
||||
// Read the section data
|
||||
let mut s_i: usize = 0;
|
||||
loop {
|
||||
if s_i == ehdr.e_shnum as usize { break; }
|
||||
|
||||
let off = sections[s_i].shdr.offset;
|
||||
let size = sections[s_i].shdr.size;
|
||||
io_file.seek(io::SeekFrom::Start(off))?;
|
||||
let mut data = vec![0; size as usize];
|
||||
if sections[s_i].shdr.shtype != types::SHT_NOBITS {
|
||||
io_file.read_exact(&mut data)?;
|
||||
for section in sections.iter_mut() {
|
||||
if section.shdr.sh_type == section::SHT_NOBITS {
|
||||
continue;
|
||||
}
|
||||
sections[s_i].data = data;
|
||||
|
||||
s_i += 1;
|
||||
io_file.seek(io::SeekFrom::Start(section.shdr.sh_offset))?;
|
||||
section.data.resize(section.shdr.sh_size as usize, 0u8);
|
||||
io_file.read_exact(&mut section.data)?;
|
||||
}
|
||||
|
||||
// Parse the section names from the string header string table
|
||||
s_i = 0;
|
||||
loop {
|
||||
if s_i == ehdr.e_shnum as usize { break; }
|
||||
|
||||
sections[s_i].shdr.name = utils::get_string(
|
||||
§ions[ehdr.e_shstrndx as usize].data,
|
||||
name_idxs[s_i] as usize)?;
|
||||
|
||||
s_i += 1;
|
||||
// Parse the section names from the section header string table
|
||||
for i in 0..sections.len() {
|
||||
let shstr_data = §ions[ehdr.e_shstrndx as usize].data;
|
||||
sections[i].name = utils::get_string(shstr_data, sections[i].shdr.sh_name as usize)?;
|
||||
}
|
||||
|
||||
Ok(File {
|
||||
@ -250,8 +197,8 @@ impl File {
|
||||
|
||||
pub fn get_symbols(&self, section: &Section) -> Result<Vec<types::Symbol>, ParseError> {
|
||||
let mut symbols = Vec::new();
|
||||
if section.shdr.shtype == types::SHT_SYMTAB || section.shdr.shtype == types::SHT_DYNSYM {
|
||||
let link = &self.sections[section.shdr.link as usize].data;
|
||||
if section.shdr.sh_type == section::SHT_SYMTAB || section.shdr.sh_type == section::SHT_DYNSYM {
|
||||
let link = &self.sections[section.shdr.sh_link as usize].data;
|
||||
let mut io_section = io::Cursor::new(§ion.data);
|
||||
while (io_section.position() as usize) < section.data.len() {
|
||||
self.parse_symbol(&mut io_section, &mut symbols, link)?;
|
||||
@ -299,13 +246,14 @@ impl File {
|
||||
pub fn get_section<T: AsRef<str>>(&self, name: T) -> Option<&Section> {
|
||||
self.sections
|
||||
.iter()
|
||||
.find(|section| section.shdr.name == name.as_ref() )
|
||||
.find(|section| section.name == name.as_ref() )
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Section {
|
||||
pub shdr: types::SectionHeader,
|
||||
pub name: String,
|
||||
pub shdr: section::SectionHeader,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
|
301
src/section.rs
Normal file
301
src/section.rs
Normal file
@ -0,0 +1,301 @@
|
||||
use gabi;
|
||||
use parse::Parse;
|
||||
use types;
|
||||
use utils;
|
||||
|
||||
/// Encapsulates the contents of an ELF Section Header
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SectionHeader {
|
||||
/// Section Name
|
||||
pub sh_name: u32,
|
||||
/// Section Type
|
||||
pub sh_type: SectionType,
|
||||
/// Section Flags
|
||||
pub sh_flags: SectionFlag,
|
||||
/// in-memory address where this section is loaded
|
||||
pub sh_addr: u64,
|
||||
/// Byte-offset into the file where this section starts
|
||||
pub sh_offset: u64,
|
||||
/// Section size in bytes
|
||||
pub sh_size: u64,
|
||||
/// Defined by section type
|
||||
pub sh_link: u32,
|
||||
/// Defined by section type
|
||||
pub sh_info: u32,
|
||||
/// address alignment
|
||||
pub sh_addralign: u64,
|
||||
/// size of an entry if section data is an array of entries
|
||||
pub sh_entsize: u64,
|
||||
}
|
||||
|
||||
impl<R> Parse<R> for SectionHeader
|
||||
where
|
||||
R: std::io::Read,
|
||||
{
|
||||
fn parse(
|
||||
endian: types::Endian,
|
||||
class: types::Class,
|
||||
reader: &mut R,
|
||||
) -> Result<Self, crate::ParseError> {
|
||||
if class == gabi::ELFCLASS32 {
|
||||
return Ok(SectionHeader {
|
||||
sh_name: utils::read_u32(endian, reader)?,
|
||||
sh_type: SectionType(utils::read_u32(endian, reader)?),
|
||||
sh_flags: SectionFlag(utils::read_u32(endian, reader)? as u64),
|
||||
sh_addr: utils::read_u32(endian, reader)? as u64,
|
||||
sh_offset: utils::read_u32(endian, reader)? as u64,
|
||||
sh_size: utils::read_u32(endian, reader)? as u64,
|
||||
sh_link: utils::read_u32(endian, reader)?,
|
||||
sh_info: utils::read_u32(endian, reader)?,
|
||||
sh_addralign: utils::read_u32(endian, reader)? as u64,
|
||||
sh_entsize: utils::read_u32(endian, reader)? as u64,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(SectionHeader {
|
||||
sh_name: utils::read_u32(endian, reader)?,
|
||||
sh_type: SectionType(utils::read_u32(endian, reader)?),
|
||||
sh_flags: SectionFlag(utils::read_u64(endian, reader)?),
|
||||
sh_addr: utils::read_u64(endian, reader)?,
|
||||
sh_offset: utils::read_u64(endian, reader)?,
|
||||
sh_size: utils::read_u64(endian, reader)?,
|
||||
sh_link: utils::read_u32(endian, reader)?,
|
||||
sh_info: utils::read_u32(endian, reader)?,
|
||||
sh_addralign: utils::read_u64(endian, reader)?,
|
||||
sh_entsize: utils::read_u64(endian, reader)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SectionHeader {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Section Header: Name: {} Type: {} Flags: {} Addr: {:#010x} Offset: {:#06x} Size: {:#06x} Link: {} Info: {:#x} AddrAlign: {} EntSize: {}",
|
||||
self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset,
|
||||
self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represens ELF Section type
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SectionType(pub u32);
|
||||
/// Inactive section with undefined values
|
||||
pub const SHT_NULL: SectionType = SectionType(0);
|
||||
/// Information defined by the program, includes executable code and data
|
||||
pub const SHT_PROGBITS: SectionType = SectionType(1);
|
||||
/// Section data contains a symbol table
|
||||
pub const SHT_SYMTAB: SectionType = SectionType(2);
|
||||
/// Section data contains a string table
|
||||
pub const SHT_STRTAB: SectionType = SectionType(3);
|
||||
/// Section data contains relocation entries with explicit addends
|
||||
pub const SHT_RELA: SectionType = SectionType(4);
|
||||
/// Section data contains a symbol hash table. Must be present for dynamic linking
|
||||
pub const SHT_HASH: SectionType = SectionType(5);
|
||||
/// Section data contains information for dynamic linking
|
||||
pub const SHT_DYNAMIC: SectionType = SectionType(6);
|
||||
/// Section data contains information that marks the file in some way
|
||||
pub const SHT_NOTE: SectionType = SectionType(7);
|
||||
/// Section data occupies no space in the file but otherwise resembles SHT_PROGBITS
|
||||
pub const SHT_NOBITS: SectionType = SectionType(8);
|
||||
/// Section data contains relocation entries without explicit addends
|
||||
pub const SHT_REL: SectionType = SectionType(9);
|
||||
/// Section is reserved but has unspecified semantics
|
||||
pub const SHT_SHLIB: SectionType = SectionType(10);
|
||||
/// Section data contains a minimal set of dynamic linking symbols
|
||||
pub const SHT_DYNSYM: SectionType = SectionType(11);
|
||||
/// Section data contains an array of constructors
|
||||
pub const SHT_INIT_ARRAY: SectionType = SectionType(14);
|
||||
/// Section data contains an array of destructors
|
||||
pub const SHT_FINI_ARRAY: SectionType = SectionType(15);
|
||||
/// Section data contains an array of pre-constructors
|
||||
pub const SHT_PREINIT_ARRAY: SectionType = SectionType(16);
|
||||
/// Section group
|
||||
pub const SHT_GROUP: SectionType = SectionType(17);
|
||||
/// Extended symbol table section index
|
||||
pub const SHT_SYMTAB_SHNDX: SectionType = SectionType(18);
|
||||
/// Number of reserved SHT_* values
|
||||
pub const SHT_NUM: SectionType = SectionType(19);
|
||||
/// Object attributes
|
||||
pub const SHT_GNU_ATTRIBUTES: SectionType = SectionType(0x6ffffff5);
|
||||
/// GNU-style hash section
|
||||
pub const SHT_GNU_HASH: SectionType = SectionType(0x6ffffff6);
|
||||
/// Pre-link library list
|
||||
pub const SHT_GNU_LIBLIST: SectionType = SectionType(0x6ffffff7);
|
||||
/// Version definition section
|
||||
pub const SHT_GNU_VERDEF: SectionType = SectionType(0x6ffffffd);
|
||||
/// Version needs section
|
||||
pub const SHT_GNU_VERNEED: SectionType = SectionType(0x6ffffffe);
|
||||
/// Version symbol table
|
||||
pub const SHT_GNU_VERSYM: SectionType = SectionType(0x6fffffff);
|
||||
|
||||
impl std::fmt::Debug for SectionType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{:#x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SectionType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let str = match *self {
|
||||
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_GNU_ATTRIBUTES => "SHT_GNU_ATTRIBUTES",
|
||||
SHT_GNU_HASH => "SHT_GNU_HASH",
|
||||
SHT_GNU_LIBLIST => "SHT_GNU_LIBLIST",
|
||||
SHT_GNU_VERDEF => "SHT_GNU_VERDEF",
|
||||
SHT_GNU_VERNEED => "SHT_GNU_VERNEED",
|
||||
SHT_GNU_VERSYM => "SHT_GNU_VERSYM",
|
||||
_ => "Unknown",
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Wrapper type for SectionFlag
|
||||
///
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SectionFlag(pub u64);
|
||||
/// Empty flags
|
||||
pub const SHF_NONE: SectionFlag = SectionFlag(0);
|
||||
/// Writable
|
||||
pub const SHF_WRITE: SectionFlag = SectionFlag(1);
|
||||
/// Occupies memory during execution
|
||||
pub const SHF_ALLOC: SectionFlag = SectionFlag(2);
|
||||
/// Executable
|
||||
pub const SHF_EXECINSTR: SectionFlag = SectionFlag(4);
|
||||
/// Might be merged
|
||||
pub const SHF_MERGE: SectionFlag = SectionFlag(16);
|
||||
/// Contains nul-terminated strings
|
||||
pub const SHF_STRINGS: SectionFlag = SectionFlag(32);
|
||||
/// `sh_info' contains SHT index
|
||||
pub const SHF_INFO_LINK: SectionFlag = SectionFlag(64);
|
||||
/// Preserve order after combining
|
||||
pub const SHF_LINK_ORDER: SectionFlag = SectionFlag(128);
|
||||
/// Non-standard OS specific handling required
|
||||
pub const SHF_OS_NONCONFORMING: SectionFlag = SectionFlag(256);
|
||||
/// Section is member of a group
|
||||
pub const SHF_GROUP: SectionFlag = SectionFlag(512);
|
||||
/// Section hold thread-local data
|
||||
pub const SHF_TLS: SectionFlag = SectionFlag(1024);
|
||||
|
||||
impl std::fmt::Debug for SectionFlag {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{:#x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SectionFlag {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{:#x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use gabi;
|
||||
use parse::Parse;
|
||||
use section::{SectionFlag, SectionHeader, SectionType};
|
||||
use types::{Class, Endian};
|
||||
|
||||
#[test]
|
||||
fn parse_shdr32_fuzz_too_short() {
|
||||
let data = [0u8; 40];
|
||||
for n in 0..40 {
|
||||
let slice = data.split_at(n).0;
|
||||
assert!(SectionHeader::parse(
|
||||
Endian(gabi::ELFDATA2LSB),
|
||||
Class(gabi::ELFCLASS32),
|
||||
&mut slice.as_ref()
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_shdr32_works() {
|
||||
let mut data = [0u8; 40];
|
||||
for n in 0u8..40 {
|
||||
data[n as usize] = n;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
SectionHeader::parse(
|
||||
Endian(gabi::ELFDATA2LSB),
|
||||
Class(gabi::ELFCLASS32),
|
||||
&mut data.as_ref()
|
||||
)
|
||||
.unwrap(),
|
||||
SectionHeader {
|
||||
sh_name: 0x03020100,
|
||||
sh_type: SectionType(0x07060504),
|
||||
sh_flags: SectionFlag(0xB0A0908),
|
||||
sh_addr: 0x0F0E0D0C,
|
||||
sh_offset: 0x13121110,
|
||||
sh_size: 0x17161514,
|
||||
sh_link: 0x1B1A1918,
|
||||
sh_info: 0x1F1E1D1C,
|
||||
sh_addralign: 0x23222120,
|
||||
sh_entsize: 0x27262524,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_shdr64_fuzz_too_short() {
|
||||
let data = [0u8; 64];
|
||||
for n in 0..64 {
|
||||
let slice = data.split_at(n).0;
|
||||
assert!(SectionHeader::parse(
|
||||
Endian(gabi::ELFDATA2LSB),
|
||||
Class(gabi::ELFCLASS64),
|
||||
&mut slice.as_ref()
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_shdr64_works() {
|
||||
let mut data = [0u8; 64];
|
||||
for n in 0u8..64 {
|
||||
data[n as usize] = n;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
SectionHeader::parse(
|
||||
Endian(gabi::ELFDATA2MSB),
|
||||
Class(gabi::ELFCLASS64),
|
||||
&mut data.as_ref()
|
||||
)
|
||||
.unwrap(),
|
||||
SectionHeader {
|
||||
sh_name: 0x00010203,
|
||||
sh_type: SectionType(0x04050607),
|
||||
sh_flags: SectionFlag(0x08090A0B0C0D0E0F),
|
||||
sh_addr: 0x1011121314151617,
|
||||
sh_offset: 0x18191A1B1C1D1E1F,
|
||||
sh_size: 0x2021222324252627,
|
||||
sh_link: 0x28292A2B,
|
||||
sh_info: 0x2C2D2E2F,
|
||||
sh_addralign: 0x3031323334353637,
|
||||
sh_entsize: 0x38393A3B3C3D3E3F,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
164
src/types.rs
164
src/types.rs
@ -397,170 +397,6 @@ impl fmt::Display for FileHeader {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represens ELF Section type
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SectionType(pub u32);
|
||||
/// Inactive section with undefined values
|
||||
pub const SHT_NULL: SectionType = SectionType(0);
|
||||
/// Information defined by the program, includes executable code and data
|
||||
pub const SHT_PROGBITS: SectionType = SectionType(1);
|
||||
/// Section data contains a symbol table
|
||||
pub const SHT_SYMTAB: SectionType = SectionType(2);
|
||||
/// Section data contains a string table
|
||||
pub const SHT_STRTAB: SectionType = SectionType(3);
|
||||
/// Section data contains relocation entries with explicit addends
|
||||
pub const SHT_RELA: SectionType = SectionType(4);
|
||||
/// Section data contains a symbol hash table. Must be present for dynamic linking
|
||||
pub const SHT_HASH: SectionType = SectionType(5);
|
||||
/// Section data contains information for dynamic linking
|
||||
pub const SHT_DYNAMIC: SectionType = SectionType(6);
|
||||
/// Section data contains information that marks the file in some way
|
||||
pub const SHT_NOTE: SectionType = SectionType(7);
|
||||
/// Section data occupies no space in the file but otherwise resembles SHT_PROGBITS
|
||||
pub const SHT_NOBITS: SectionType = SectionType(8);
|
||||
/// Section data contains relocation entries without explicit addends
|
||||
pub const SHT_REL: SectionType = SectionType(9);
|
||||
/// Section is reserved but has unspecified semantics
|
||||
pub const SHT_SHLIB: SectionType = SectionType(10);
|
||||
/// Section data contains a minimal set of dynamic linking symbols
|
||||
pub const SHT_DYNSYM: SectionType = SectionType(11);
|
||||
/// Section data contains an array of constructors
|
||||
pub const SHT_INIT_ARRAY: SectionType = SectionType(14);
|
||||
/// Section data contains an array of destructors
|
||||
pub const SHT_FINI_ARRAY: SectionType = SectionType(15);
|
||||
/// Section data contains an array of pre-constructors
|
||||
pub const SHT_PREINIT_ARRAY: SectionType = SectionType(16);
|
||||
/// Section group
|
||||
pub const SHT_GROUP: SectionType = SectionType(17);
|
||||
/// Extended symbol table section index
|
||||
pub const SHT_SYMTAB_SHNDX: SectionType = SectionType(18);
|
||||
/// Number of reserved SHT_* values
|
||||
pub const SHT_NUM: SectionType = SectionType(19);
|
||||
/// Object attributes
|
||||
pub const SHT_GNU_ATTRIBUTES: SectionType = SectionType(0x6ffffff5);
|
||||
/// GNU-style hash section
|
||||
pub const SHT_GNU_HASH: SectionType = SectionType(0x6ffffff6);
|
||||
/// Pre-link library list
|
||||
pub const SHT_GNU_LIBLIST: SectionType = SectionType(0x6ffffff7);
|
||||
/// Version definition section
|
||||
pub const SHT_GNU_VERDEF: SectionType = SectionType(0x6ffffffd);
|
||||
/// Version needs section
|
||||
pub const SHT_GNU_VERNEED: SectionType = SectionType(0x6ffffffe);
|
||||
/// Version symbol table
|
||||
pub const SHT_GNU_VERSYM: SectionType = SectionType(0x6fffffff);
|
||||
|
||||
impl fmt::Debug for SectionType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:#x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SectionType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let str = match *self {
|
||||
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_GNU_ATTRIBUTES => "SHT_GNU_ATTRIBUTES",
|
||||
SHT_GNU_HASH => "SHT_GNU_HASH",
|
||||
SHT_GNU_LIBLIST => "SHT_GNU_LIBLIST",
|
||||
SHT_GNU_VERDEF => "SHT_GNU_VERDEF",
|
||||
SHT_GNU_VERNEED => "SHT_GNU_VERNEED",
|
||||
SHT_GNU_VERSYM => "SHT_GNU_VERSYM",
|
||||
_ => "Unknown",
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Wrapper type for SectionFlag
|
||||
///
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SectionFlag(pub u64);
|
||||
/// Empty flags
|
||||
pub const SHF_NONE: SectionFlag = SectionFlag(0);
|
||||
/// Writable
|
||||
pub const SHF_WRITE: SectionFlag = SectionFlag(1);
|
||||
/// Occupies memory during execution
|
||||
pub const SHF_ALLOC: SectionFlag = SectionFlag(2);
|
||||
/// Executable
|
||||
pub const SHF_EXECINSTR: SectionFlag = SectionFlag(4);
|
||||
/// Might be merged
|
||||
pub const SHF_MERGE: SectionFlag = SectionFlag(16);
|
||||
/// Contains nul-terminated strings
|
||||
pub const SHF_STRINGS: SectionFlag = SectionFlag(32);
|
||||
/// `sh_info' contains SHT index
|
||||
pub const SHF_INFO_LINK: SectionFlag = SectionFlag(64);
|
||||
/// Preserve order after combining
|
||||
pub const SHF_LINK_ORDER: SectionFlag = SectionFlag(128);
|
||||
/// Non-standard OS specific handling required
|
||||
pub const SHF_OS_NONCONFORMING: SectionFlag = SectionFlag(256);
|
||||
/// Section is member of a group
|
||||
pub const SHF_GROUP: SectionFlag = SectionFlag(512);
|
||||
/// Section hold thread-local data
|
||||
pub const SHF_TLS: SectionFlag = SectionFlag(1024);
|
||||
|
||||
impl fmt::Debug for SectionFlag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:#x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SectionFlag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:#x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Encapsulates the contents of an ELF Section Header
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SectionHeader {
|
||||
/// Section Name
|
||||
pub name: String,
|
||||
/// Section Type
|
||||
pub shtype: SectionType,
|
||||
/// Section Flags
|
||||
pub flags: SectionFlag,
|
||||
/// in-memory address where this section is loaded
|
||||
pub addr: u64,
|
||||
/// Byte-offset into the file where this section starts
|
||||
pub offset: u64,
|
||||
/// Section size in bytes
|
||||
pub size: u64,
|
||||
/// Defined by section type
|
||||
pub link: u32,
|
||||
/// Defined by section type
|
||||
pub info: u32,
|
||||
/// address alignment
|
||||
pub addralign: u64,
|
||||
/// size of an entry if section data is an array of entries
|
||||
pub entsize: u64,
|
||||
}
|
||||
|
||||
impl fmt::Display for SectionHeader {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Section Header: Name: {} Type: {} Flags: {} Addr: {:#010x} Offset: {:#06x} Size: {:#06x} Link: {} Info: {:#x} AddrAlign: {} EntSize: {}",
|
||||
self.name, self.shtype, self.flags, self.addr, self.offset,
|
||||
self.size, self.link, self.info, self.addralign, self.entsize)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct SymbolType(pub u8);
|
||||
/// Unspecified symbol type
|
||||
|
Loading…
x
Reference in New Issue
Block a user