use crate::{
Result,
elf::{ElfLayout, ElfPhdr},
os::{Mmap, ProtFlags},
relocation::RelocAddr,
};
use core::ffi::c_void;
use super::{rounddown, roundup};
#[allow(unused)]
pub(crate) struct ELFRelro {
addr: RelocAddr,
len: usize,
page_size: usize,
mprotect: unsafe fn(*mut c_void, usize, ProtFlags) -> Result<()>,
}
impl ELFRelro {
pub(crate) fn new<M: Mmap, L: ElfLayout>(
phdr: &ElfPhdr<L>,
base: RelocAddr,
page_size: usize,
) -> ELFRelro {
ELFRelro {
addr: base.offset(phdr.p_vaddr()),
len: phdr.p_memsz(),
page_size,
mprotect: M::mprotect,
}
}
#[inline]
pub(crate) fn relro(&self) -> Result<()> {
let addr = self.addr.into_inner();
let end = roundup(addr + self.len, self.page_size);
let start = rounddown(addr, self.page_size);
let start_addr = start as *mut c_void;
unsafe {
(self.mprotect)(start_addr, end - start, ProtFlags::PROT_READ)?;
}
Ok(())
}
}