squid 2.0.3

A RISC-V emulator with AOT compilation for fuzzing
Documentation
use crate::{
    frontend::{
        ao::BasicBlock,
        ChunkContent,
        Elf,
        HasId,
        Pointer,
    },
    riscv::register::GpRegister,
};

pub(crate) struct HandleRelaxationPass {}

impl HandleRelaxationPass {
    #[allow(clippy::new_without_default)]
    pub(crate) fn new() -> Self {
        Self {}
    }

    pub(crate) fn run(&mut self, elf: &mut Elf) -> Result<(), String> {
        for section in elf.iter_sections_mut() {
            if !section.perms().is_executable() {
                continue;
            }

            for symbol in section.iter_symbols_mut() {
                if symbol.private_name("load_gp").is_some() {
                    let mut id = None;

                    for chunk in symbol.iter_chunks() {
                        assert!(id.is_none());
                        id = Some(chunk.id());
                    }

                    let id = id.unwrap();

                    let chunk = symbol.chunk_mut(id).unwrap();
                    let addr = chunk.vaddr();
                    let ChunkContent::Code(func) = chunk.content_mut() else { unreachable!() };

                    func.cfg_mut().clear();

                    let mut bb = BasicBlock::at_vaddr(addr);
                    let null = bb.load_pointer(Pointer::Null);
                    bb.store_gp_register(GpRegister::gp, null).unwrap();
                    let ra = bb.load_gp_register(GpRegister::ra);
                    bb.jump(ra).unwrap();

                    let id = func.cfg_mut().add_basic_block(bb);
                    func.cfg_mut().set_entry(id);
                }
            }
        }

        Ok(())
    }
}