From 4b41166d5f5895acb8ec079f99ba20579b0b3f75 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Thu, 16 Feb 2023 20:32:24 +0100 Subject: [PATCH] more --- elven-forest/src/main.rs | 4 +++- elven-parser/src/consts.rs | 44 +++++++++++++++++++++++++++++++++++--- elven-parser/src/read.rs | 2 +- elven-parser/src/write.rs | 21 +++++++++++++----- elven-wald/src/lib.rs | 4 ++-- 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/elven-forest/src/main.rs b/elven-forest/src/main.rs index d32b48d..fc3a2b5 100644 --- a/elven-forest/src/main.rs +++ b/elven-forest/src/main.rs @@ -2,7 +2,7 @@ use std::{fmt::Display, fs::File}; use anyhow::Context; use elven_parser::{ - consts::{self as c, DynamicTag, PhFlags, PhType, ShType, SymbolVisibility, RX86_64}, + consts::{self as c, DynamicTag, PhFlags, PhType, ShFlags, ShType, SymbolVisibility, RX86_64}, read::{Addr, ElfReadError, ElfReader, Offset, Sym, SymInfo}, }; use memmap2::Mmap; @@ -28,6 +28,7 @@ struct SectionTable { r#type: ShType, size: Addr, offset: Addr, + flags: ShFlags, } #[derive(Tabled)] @@ -113,6 +114,7 @@ fn print_file(path: &str) -> anyhow::Result<()> { r#type: sh.r#type, size: Addr(sh.size), offset: Addr(sh.offset.0), + flags: sh.flags, }) }) .collect::, ElfReadError>>()?; diff --git a/elven-parser/src/consts.rs b/elven-parser/src/consts.rs index d546061..1429033 100644 --- a/elven-parser/src/consts.rs +++ b/elven-parser/src/consts.rs @@ -68,14 +68,14 @@ macro_rules! const_group_with_fmt { self.partial_cmp(&other.0) } } - + impl From<$ty> for $struct_name { fn from(ty: $ty) -> $struct_name { $struct_name(ty) } } - + impl From<$struct_name> for $ty { fn from(wrap: $struct_name) -> $ty { wrap.0 @@ -225,6 +225,40 @@ pub const SHT_LOSUNW: u32 = 0x6ffffffa; /* Sun-specific low bound. */ pub const SHT_HISUNW: u32 = 0x6fffffff; /* Sun-specific high bound. */ pub const SHT_HIOS: u32 = 0x6fffffff; /* End OS-specific type */ +bitflags! { + #[derive(Zeroable, Pod)] + #[repr(transparent)] + pub struct ShFlags: u64 { + const SHF_WRITE = (1 << 0); /* Writable */ + const SHF_ALLOC = (1 << 1); /* Occupies memory during execution */ + const SHF_EXECINSTR = (1 << 2); /* Executable */ + const SHF_MERGE = (1 << 4); /* Might be merged */ + const SHF_STRINGS = (1 << 5); /* Contains nul-terminated strings */ + const SHF_INFO_LINK = (1 << 6); /* `sh_info' contains SHT index */ + const SHF_LINK_ORDER = (1 << 7); /* Preserve order after combining */ + const SHF_OS_NONCONFORMING = (1 << 8); /* Non-standard OS specific handling required */ + const SHF_GROUP = (1 << 9); /* Section is member of a group. */ + const SHF_TLS = (1 << 10); /* Section hold thread-local data. */ + const SHF_COMPRESSED = (1 << 11); /* Section with compressed data. */ + const SHF_GNU_RETAIN = (1 << 21); /* Not to be GCed by linker. */ + const SHF_ORDERED = (1 << 30); /* Special ordering requirement (Solaris). */ + const SHF_EXCLUDE = (1 << 31); /* Section is excluded unless referenced or allocated (Solaris).*/ + } +} + +pub const SHF_MASKOS: u64 = 0x0ff00000; /* OS-specific. */ +pub const SHF_MASKPROC: u64 = 0xf0000000; /* Processor-specific */ + +impl Display for ShFlags { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.is_empty() { + f.write_str("") + } else { + write!(f, "{:?}", self) + } + } +} + // ------------------ // Program headers // ------------------ @@ -268,7 +302,11 @@ bitflags! { impl Display for PhFlags { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self) + if self.is_empty() { + f.write_str("") + } else { + write!(f, "{:?}", self) + } } } diff --git a/elven-parser/src/read.rs b/elven-parser/src/read.rs index f37b9b5..ad83360 100644 --- a/elven-parser/src/read.rs +++ b/elven-parser/src/read.rs @@ -149,7 +149,7 @@ pub struct Phdr { pub struct Shdr { pub name: ShStringIdx, pub r#type: c::ShType, - pub flags: u64, + pub flags: c::ShFlags, pub addr: Addr, pub offset: Offset, pub size: u64, diff --git a/elven-parser/src/write.rs b/elven-parser/src/write.rs index 4e16966..e508196 100644 --- a/elven-parser/src/write.rs +++ b/elven-parser/src/write.rs @@ -1,6 +1,8 @@ use bytemuck::Pod; -use crate::consts::{Machine, PhFlags, PhType, SectionIdx, ShType, Type, SHT_NULL, SHT_STRTAB}; +use crate::consts::{ + Machine, PhFlags, PhType, SectionIdx, ShFlags, ShType, Type, SHT_NULL, SHT_STRTAB, +}; use crate::read::{self, Addr, ElfHeader, ElfIdent, Offset, Phdr, ShStringIdx, Shdr}; use std::io::Write; use std::mem::size_of; @@ -41,7 +43,7 @@ pub struct SectionRelativeAbsoluteAddr { pub struct Section { pub name: read::ShStringIdx, pub r#type: ShType, - pub flags: u64, + pub flags: ShFlags, pub fixed_entsize: Option, pub addr_align: Option, pub content: Vec, @@ -85,7 +87,7 @@ impl ElfWriter { // The null string. name: read::ShStringIdx(0), r#type: ShType(SHT_NULL), - flags: 0, + flags: ShFlags::empty(), content: Vec::new(), fixed_entsize: None, addr_align: None, @@ -95,7 +97,7 @@ impl ElfWriter { // The first string which happens to be .shstrtab below. name: read::ShStringIdx(1), r#type: ShType(SHT_STRTAB), - flags: 0, + flags: ShFlags::empty(), // Set up the null string and also the .shstrtab, our section. content: b"\0.shstrtab\0".to_vec(), fixed_entsize: None, @@ -268,7 +270,7 @@ impl ElfWriter { let null_sh = Shdr { name: ShStringIdx(0), r#type: ShType(SHT_NULL), - flags: 0, + flags: ShFlags::empty(), addr: Addr(0), offset: Offset(0), size: 0, @@ -315,6 +317,15 @@ impl ElfWriter { assert_eq!(output.len(), layout.section_content_end_offset); + if cfg!(debug_assertions) { + for offset in &layout.section_content_offsets { + assert!( + (offset.0 as usize) < output.len(), + "section offset is out of bounds: {offset:?}" + ); + } + } + Ok(output) } } diff --git a/elven-wald/src/lib.rs b/elven-wald/src/lib.rs index 00ef573..b197d9a 100644 --- a/elven-wald/src/lib.rs +++ b/elven-wald/src/lib.rs @@ -4,7 +4,7 @@ extern crate tracing; use anyhow::{bail, Context, Result}; use clap::Parser; use elven_parser::{ - consts::{self as c, PhFlags, SectionIdx, ShType, PT_LOAD, SHT_PROGBITS}, + consts::{self as c, PhFlags, SectionIdx, ShFlags, ShType, PT_LOAD, SHT_PROGBITS}, read::{Addr, ElfIdent, ElfReader, Offset}, write::{self, ElfWriter, ProgramHeader, Section, SectionRelativeAbsoluteAddr}, }; @@ -89,7 +89,7 @@ fn write_output(text: &[u8], entry_offset_from_text: u64) -> Result<()> { let text_section = write.add_section(Section { name: text_name, r#type: ShType(SHT_PROGBITS), - flags: 0, + flags: ShFlags::SHF_ALLOC | ShFlags::SHF_EXECINSTR, fixed_entsize: None, content: text.to_vec(), addr_align: None,