Module kerbalobjects::ko

source ·
Expand description

Kerbal Object files

The module for describing, reading, and writing Kerbal Object files

There must be at least the null section, and the .shstrtab, which are automatically added for you using KOFile::new().

Each section added must have an entry in the section header table, or you will get an error attempting to validate the file. Also all section header table entries must correspond to a section. The series of new_<section name> functions create a section header automatically for you, then you later add the section to the KOFile using .add_<section name>.

use kerbalobjects::ko::symbols::{KOSymbol, SymBind, SymType};
use kerbalobjects::ko::{Instr, KOFile};
use kerbalobjects::{KOSValue, Opcode};
use kerbalobjects::ko::SectionIdx;
use kerbalobjects::ko::sections::DataIdx;
use std::io::Write;
use std::path::PathBuf;

let mut ko = KOFile::new();

let mut data_section = ko.new_data_section(".data");
let mut start = ko.new_func_section("_start");
let mut symtab = ko.new_symtab(".symtab");
let mut symstrtab = ko.new_strtab(".symstrtab");

// Set up the main code function section
let one = data_section.add_checked(KOSValue::Int16(1));

start.add(Instr::TwoOp(
    Opcode::Bscp,
    one,
    data_section.add_checked(KOSValue::Int16(0)),
));
start.add(Instr::ZeroOp(Opcode::Argb));
start.add(Instr::OneOp(
    Opcode::Push,
    data_section.add_checked(KOSValue::ArgMarker),
));
start.add(Instr::OneOp(
    Opcode::Push,
    data_section.add_checked(KOSValue::StringValue("Hello, world!".into())),
));
start.add(Instr::TwoOp(
    Opcode::Call,
    data_section.add_checked(KOSValue::String("".into())),
    data_section.add_checked(KOSValue::String("print()".into())),
));
start.add(Instr::ZeroOp(Opcode::Pop));
start.add(Instr::OneOp(Opcode::Escp, one));

// Set up our symbols
let file_symbol = KOSymbol::new(
    symstrtab.add("test.kasm"),
    DataIdx::PLACEHOLDER,
    0,
    SymBind::Global,
    SymType::File,
    SectionIdx::NULL,
);
let start_symbol = KOSymbol::new(
    symstrtab.add("_start"),
    DataIdx::PLACEHOLDER,
    start.size() as u16,
    SymBind::Global,
    SymType::Func,
    start.section_index(),
);

symtab.add(file_symbol);
symtab.add(start_symbol);

ko.add_data_section(data_section);
ko.add_func_section(start);
ko.add_str_tab(symstrtab);
ko.add_sym_tab(symtab);

// Write the file out to disk
let mut file_buffer = Vec::with_capacity(2048);

let ko = ko.validate().expect("Could not update KO headers properly");
ko.write(&mut file_buffer);

let file_path = PathBuf::from("test.ko");
let mut file =
    std::fs::File::create(file_path).expect("Output file could not be created: test.ko");

file.write_all(file_buffer.as_slice())
    .expect("File test.ko could not be written to.");

Re-exports

  • pub use instructions::Instr;

Modules

  • Errors specifically for when parsing a KO file
  • kOS instructions as stored in a KO file.
  • A collection of the sections that can be contained within a KO file
  • Describes symbols contained within a KO file’s symbol table

Structs

  • An in-memory representation of a KO file
  • The header of a Kerbal Object file
  • A wrapper type that represents an index into a section header table of a KO file.
  • A finalized Kerbal Object file that can be written to a byte buffer, or converted into a KOFile