use async_trait::async_trait;
use rand::rngs::ThreadRng;
use rand::seq::IndexedRandom;
use rand::{Rng, rng};
use regex::Regex;
use crate::args::AppConfig;
use crate::data::CFILES_LIST;
use crate::io::{csleep, newline, print};
use crate::modules::Module;
fn gen_header(arch: &str, rng: &mut ThreadRng) -> String {
const RARE_CMDS: &[&str] = &["SYSTBL ", "SYSHDR "];
const CMDS: &[&str] = &["WRAP ", "CHK ", "UPD "];
let cmd = if rng.random_bool(1.0 / 15.0) {
RARE_CMDS.choose(rng).unwrap_or(&"")
} else {
CMDS.choose(rng).unwrap_or(&"")
};
let cfile = &CFILES_LIST.choose(rng).unwrap_or(&"");
let mut file = format!("{}h", &cfile[..cfile.len() - 1]);
if file.starts_with("arch") {
let re = Regex::new(r"arch/([a-z0-9_])+/").unwrap();
file = re
.replace(&file, format!("arch/{arch}/").as_str())
.into_owned();
}
format!(" {cmd} {file}")
}
fn gen_object(arch: &str, rng: &mut ThreadRng) -> String {
const RARE_CMDS: &[&str] = &["HOSTCC ", "AS "];
let cmd = if rng.random_bool(1.0 / 15.0) {
RARE_CMDS.choose(rng).unwrap_or(&"")
} else if rng.random_bool(0.33) {
"AR "
} else {
"CC "
};
let cfile = &CFILES_LIST.choose(rng).unwrap_or(&"");
let mut file = format!("{}o", cfile[..cfile.len() - 1].to_owned());
if file.starts_with("arch") {
let re = Regex::new(r"arch/([a-z0-9_])+/").unwrap();
file = re
.replace(&file, format!("arch/{arch}/").as_str())
.into_owned();
}
format!(" {cmd} {file}")
}
fn gen_special(arch: &str, rng: &mut ThreadRng) -> String {
const SPECIALS: &[&str] = &[
"HOSTLD arch/ARCH/tools/relocs",
"HOSTLD scripts/mod/modpost",
"MKELF scripts/mod/elfconfig.h",
"LDS arch/ARCH/entry/vdso/vdso32/vdso32.lds",
"LDS arch/ARCH/kernel/vmlinux.lds",
"LDS arch/ARCH/realmode/rm/realmode.lds",
"LDS arch/ARCH/boot/compressed/vmlinux.lds",
"EXPORTS arch/ARCH/lib/lib-ksyms.o",
"EXPORTS lib/lib-ksyms.o",
"MODPOST vmlinux.o",
"SORTEX vmlinux",
"SYSMAP System.map",
"VOFFSET arch/ARCH/boot/compressed/../voffset.h",
"OBJCOPY arch/ARCH/entry/vdso/vdso32.so",
"OBJCOPY arch/ARCH/realmode/rm/realmode.bin",
"OBJCOPY arch/ARCH/boot/compressed/vmlinux.bin",
"OBJCOPY arch/ARCH/boot/vmlinux.bin",
"VDSO2C arch/ARCH/entry/vdso/vdso-image-32.c",
"VDSO arch/ARCH/entry/vdso/vdso32.so.dbg",
"RELOCS arch/ARCH/realmode/rm/realmode.relocs",
"PASYMS arch/ARCH/realmode/rm/pasyms.h",
"XZKERN arch/ARCH/boot/compressed/vmlinux.bin.xz",
"MKPIGGY arch/ARCH/boot/compressed/piggy.S",
"DATAREL arch/ARCH/boot/compressed/vmlinux",
"ZOFFSET arch/ARCH/boot/zoffset.h",
];
let special = SPECIALS.choose(rng).unwrap_or(&"").to_string();
let special = special.replace("ARCH", arch);
format!(" {special}")
}
fn gen_line(arch: &str, rng: &mut ThreadRng) -> String {
if rng.random_bool(1.0 / 50.0) {
gen_special(arch, rng)
} else if rng.random_bool(0.1) {
gen_header(arch, rng)
} else {
gen_object(arch, rng)
}
}
pub struct KernelCompile;
#[async_trait(?Send)]
impl Module for KernelCompile {
fn name(&self) -> &'static str {
"kernel_compile"
}
fn signature(&self) -> String {
"sudo make install".to_string()
}
async fn run(&self, appconfig: &AppConfig) {
let mut rng = rng();
let num_lines = rng.random_range(50..500);
const ARCHES: &[&str] = &[
"alpha",
"arc",
"arm",
"arm64",
"blackfin",
"c6x",
"cris",
"frv",
"h8300",
"hexagon",
"ia64",
"m32r",
"m68k",
"metag",
"microblaze",
"mips",
"mn10300",
"nios2",
"openrisc",
"parisc",
"powerpc",
"s390",
"score",
"sh",
"sparc",
"tile",
"um",
"unicore32",
"x86",
"xtensa",
];
let arch = ARCHES.choose(&mut rng).unwrap_or(&"x86");
for _ in 1..num_lines {
let line = gen_line(arch, &mut rng);
let sleep_length = rng.random_range(10..1000);
print(line).await;
newline().await;
csleep(sleep_length).await;
if appconfig.should_exit() {
return;
}
}
print(format!("BUILD arch/{arch}/boot/bzImage")).await;
newline().await;
newline().await;
let bytes: u32 = rng.random_range(9000..1_000_000);
let padded_bytes: u32 = rng.random_range(bytes..1_100_000);
print(format!(
"Setup is {bytes} bytes (padded to {padded_bytes} bytes)."
))
.await;
newline().await;
let system: u32 = rng.random_range(300..3000);
print(format!("System is {system} kB")).await;
newline().await;
let crc: u32 = rng.random_range(0x1000_0000..0xffff_ffff);
print(format!("CRC {crc:x}")).await;
newline().await;
print(format!("Kernel: arch/{arch}/boot/bzImage is ready (#1)")).await;
newline().await;
newline().await;
}
}