mutek/bytecode.h header reference
[Kernel services module]

The source code of this header can be browsed online.

Description [link] 

This kernel service provides a simple and small bytecode virtual machine with a customisable instruction set. A set of generic instructions is provided which can be extended.

The virtual machine state contains a program counter register as well as 16 general purpose registers. Opcodes words are 16 bits wide. The most significant bit of the opcode word is always zero for generic instructions, leaving half of the opcode space for custom opcodes.

Once the virtual machine state has benn initialized using the bc_init function, the bc_run function can start execution of the bytecode. It will return on the first encountered custom instruction, leaving the caller with the task of performing the custom operation. This makes the meaning of custom instructions context dependent; different parts of the kernel and application can have there own interpretation of custom bytecode instructions.

The bytecode program can be resumed at any time once a custom instruction has been handled. The C code is free to access the virtual registers and change the value of the program counter to point at any entry point.

Relying on bytecode is useful in various situations:

  • A bytecode program may be executed in a sandbox or live in the same memory space as the C code.

  • Repetitive operations requiring complex processing or complex invocation can be encoded as a single 16 bits opcode.

  • When a simple program using a specific set of blocking operations needs to be executed, custom instructions may actually be implemented using asynchronous operations. The bytecode may be resumed when the operation terminates.

  • The resumable bytecode has the advantage of requiring less than 100 bytes of execution state on a 32 bits architecture. It does not require a dedicated thread and associated execution stack in order to implement blocking operations.

When a processor specific backend is available, bytecode programs which does not require sandboxing can be translated into machine code at compile time rather than relying on the virtual machine. This requires definition of the CONFIG_MUTEK_BYTECODE_NATIVE token. This allows fast execution while retaining the resumable bytecode feature.

Bytecode debug and trace [link] 

Bytecode instructions and C functions are available to dump the virtual machine state and enable execution trace. This requires definition of the CONFIG_MUTEK_BYTECODE_DEBUG and CONFIG_MUTEK_BYTECODE_TRACE tokens.

See also bc_set_trace and bc_dump.

Bytecode portability [link] 

The virtual machine register width depends on the width of the registers of the host processor. It is at least 32 bits wide and large enough to hold a pointer. Memory accesses are performed using the endianess of the host processor. These rules enable efficient execution of the bytecode on any platform.

Nonetheless, the instruction set is designed to allow writing bytecode programs which are portable across platforms.

Most ALU instructions only work on the lower 32 bits of the virtual machine registers. On 64 bits architectures, the upper half of the destination register is zeroed by these instructions. Other instructions like add and sub work on the full register width because they are useful to handle pointers. This requires use of additional sign extension and zero extension instructions as appropriate.

The CONFIG_MUTEK_BYTECODE_VM64 token can be used to test portability of bytecode programs.

Bytecode program syntax [link] 

A bytecode source file is basically an assembly source file composed of generic and custom bytecode instructions. Custom instruction sets are described in perl modules which can be loaded dynamically by the assembler tool.

C style expressions can be used where constants are expected. Moreover, the bitpos() operator is available which computes a bit index from a power of 2 constant.

The bytecode source file is piped in the scripts/decl_filter.pl script before being assembled. This allows inclusion of C headers files as well as use of _sizeof, _offsetof and _const operators on C declarations in the bytecode program.

The following general purpose directives are available:

  • .define name expr : define an expression macro. The C preprocessor is also available in bytecode programs and configuration tokens can be tested.

  • .backend name : use a specific output backend. bytecode may be specified in order to prevent generation of native machine code for the program.

  • .name name : set the bytecode program name.

  • .custom name [mode, mode ...] : load a custom instruction set module and optionally restrict modes which are allowed for instructions of the module.

  • .mode m : declare the default mode used in the current .func.

  • .export label : export a label as a global symbol.

ALU instructions use a 2 registers form with the first register used as both the source and destination register.

See tests/pool/bytecode for an example application.

Static analysis [link] 

The bytecode assembler is capable of performing register usage checking provided that some directive are used to declare the role of registers. Checking is most efficient when the whole bytecode program is written using functions.

The following directives are available to declare register usage:

  • .assert expr : make the compilation fail if the expression does not reduce to 1.

  • .global %1 [aliasA] [, %7 [aliasB] ...] : declare some registers as always initialized.

  • .const %1 [aliasA] [, %7 [aliasB] ...] : declare some registers as always initialized which should not be modified by the bytecode.

  • .entry %1 [, %7 ...] : export the previous label as a global symbol and declare some registers as initialized at this point. This is better to use functions as bytecode entry-points.

  • .func name, .endfunc : declare a function. This is similar to declaring a label but allows better static analysis on function calls.

  • .proto name, .endproto : declare a function prototype.

  • .input %1 [aliasA] [, %7 [aliasB] ...] : declare some registers used as input parameters by the current function or prototype.

  • .output %1 [aliasA] [, %7 [aliasB] ...] : declare some registers used return values by the current function or prototype.

  • .clobber %1 [aliasA] [, %7 [aliasB] ...] : declare some registers used as temporaries which are left clobbered by the current function or prototype.

  • .preserve %1 [aliasA] [, %7 [aliasB] ...] : declare some registers used as temporaries which are saved and restored by the current function or prototype.

  • .implement name : make the current function inherit from register declarations of the specified function prototype.

Generic instruction set [link] 

The following operations are available to load values into registers:

Instruction
Description
cst8 reg, value
Set a register to an unsigned 8 bits constant.
cst16 reg, value, shift
Set a register to an signed constant in range [-2**16, 2**16-1]. The constant may be shifted by a mulitple of 8 bits. This uses 2 opcode words.
cst32 reg, value, shift
Set a register to an signed constant in range [-2**32, 2**32-1]. The constant may be shifted by a mulitple of 8 bits. This uses 3 opcode words.
mov reg, reg
Copy a value between 2 registers.

The following operations are available to perform usual integer operations on register values:

Instruction
Description
add8 reg, value
Add a signed 8 bits value to a register.
add reg, reg
Add the value of the source register to the destination register.
sub reg, reg
Subtract the value of the source register from the destination register.
neg reg
Subtract the value from zero.
mul32 reg, reg
Multiply the values of the source register and destination registers.
div32 reg, reg
Perform a division, store both quotient and modulus in registers.
or32 reg, reg
32 bits bitwise or.
xor32 reg, reg
32 bits bitwise exclusive or.
and32 reg, reg
32 bits bitwise and.
not32 reg
32 bits bitwise not.
shl32 reg, reg
32 bits variable left shift.
shr32 reg, reg
32 bits variable right shift.
sha32 reg, reg
32 bits variable right arithmetic shift.
shi32l reg, bit_index
Left shift a register by a constant amount. Amount must be in the range [0,31].
shi32r reg, bit_index
Right shift a register by a constant amount. Amount must be in the range [0,31].
shi32a reg, bit_index
Right arithmetic shift a register by a constant amount. Amount must be in the range [0,31].
msbs32 reg
Find the position of the most significant bit set in range [0, 31].
exts reg, bit_index
Sign extend a register using the specified sign bit in the set {7, 15, 31}.
extz reg, bit_index
Clear all bits in a register above specified bit in the range [0,31].
swapN reg
Exchange bytes of a 16 bits or 32 bits values.
swapNle reg
Exchange bytes only when running on a big endian processor, used to access little endian data in portable way.
swapNbe reg
Exchange bytes only when running on a little endian processor, used to access big endian data in portable way.
rand32 reg
Set the register to a random value

The following comparison operations are available:

Instruction
Description
eq reg, reg
Compare two registers and skip the next instruction if they are not equal.
neq reg, reg
Compare two registers and skip the next instruction if they are equal.
eq0 reg
Skip the next instruction if the register is not zero.
neq0 reg
Skip the next instruction if the register is zero.
lt reg, reg
Perform an unsigned comparison of two registers and skip the next instruction if first reg >= second reg.
lteq reg, reg
Perform an unsigned comparison of two registers and skip the next instruction if first reg > second reg.
lts reg
Perform an signed comparison of reg with r0 and skip the next instruction if reg >= r0.
lteqs reg
Perform an signed comparison of reg with r0 and skip the next instruction if reg > r0.

The following bit oriented operations are available:

Instruction
Description
tst32c reg, bit_index
Extract a bit from a register and skip the next instruction if the bit is not cleared. Bit index is in the range [0,31].
tst32s reg, bit_index
Extract a bit from a register and skip the next instruction if the bit is not set. Bit index is in the range [0,31].
bit32c reg, bit_index
Clear a bit in a register. Bit index is in the range [0,31].
bit32s reg, bit_index
Set a bit in a register. Bit index is in the range [0,31].

The following branch instructions are available:

Instruction
Description
end
Terminate bytecode execution.
jmp8 label
Jump relative. The branch target must be in range [-128, +127] from this instruction.
jmp[16,32] label
Jump absolute.
jmp[16,32]r label
Jump relative.
call8 reg, label
Jump relative and save the return address in a register. The branch target must be in range [-128, +127] from this instruction.
call[16,32] reg, label
Jump absolute and save the return address in a register.
call[16,32]r reg, label
Jump relative and save the return address in a register.
ret reg
Return to the address saved in a link register.
jmp reg
Jump to the address specified by a register.
call reg, proto
Jump to the address specified by a register and save the return address in the same register. The function prototype is used for register usage checking.
loop reg, label
If the jump target is backward, this instruction decrements the register which should not be initially zero and branch if the result is not zero. If the jump target is forward, this instruction decrement the register if its initial value is not zero. If the register initial value is zero, the branch is taken and the register is left untouched.

The following memory access instructions are available:

Instruction
Description
ld[8,16,32,64] data_reg, addr_reg
Load a value from a memory address given by a register into an other register.
ld[8,16,32,64]i data_reg, addr_reg
Load a value from a memory address given by a register into an other register then add the width of the access to the address register.
ld[8,16,32,64]e data_reg, addr_reg, offset
Load a value from a memory address given by a register and a 16 bits signed offset into an other register.
st[8,16,32,64] data_reg, addr_reg
Store a value to a memory address given by a register from an other register.
st[8,16,32,64]i data_reg, addr_reg
Store a value to a memory address given by a register from an other register then add the width of the access to the address register.
st[8,16,32,64]d data_reg, addr_reg
Subtract the width of the access to the address register then store a value from an other register to the resulting memory address.
st[8,16,32,64]e data_reg, addr_reg, offset
Store a value from a register to a memory address given by an other register and a 16 bits signed offset.

Zero extension is performed by load instructions. In order to achieve portability, additional ld, st, ldi, sti, std, lde and ste instructions are available to perform memory accesses with a width suitable to handle pointers.

The following miscellaneous instructions are available:

Instruction
Description
dump
Dump registers to debug output.
abort
Terminate bytecode execution and report an error.
die
Terminate by calling the libc abort function.
trace mode
Enable or disable debug trace.
ccall reg
Call a C function. The address of the function is in the source register. Bytecode in compiled form will not be portable.
laddr[16,32,64] reg, label
Set a register to the absolute address of a bytecode label.
laddr[16,32]r reg, label
Set a register to the pc relative address of a bytecode label.
gaddr reg, label
Set a register to the address of a global symbol. Bytecode in compiled form will not be portable.
mode m
Select custom bytecode interpretation mode in range [0, 15].

Some instructions are provided to handle packing of some register values as an array of bytes. The storage space of vm registers is used to store the array, clobbering the original register values. When in packed form, register values are meaningless for other generic bytecode instructions. Packed values can be used by custom operations which needs to deal with byte buffers. They may be accessed from the C code using the bc_get_bytepack function. The following array packing and unpacking instructions are available:

Instruction
Description
pack8 reg_1st, reg_count
Converts multiple vm register values to an array of bytes. The value of a single register is stored as a single byte in the array.
pack16le reg_1st, reg_count, byte_count
Converts multiple vm register values to an array of bytes. The value of a single register is stored as a pair of bytes in the array, with the less significant byte stored first.
pack16be reg_1st, reg_count, byte_count
Converts multiple vm register values to an array of bytes. The value of a single register is stored as a pair of bytes in the array, with the most significant byte stored first.
pack32le reg_1st, reg_count, byte_count
Converts multiple vm register values to an array of bytes. The value of a single register is stored as 4 bytes in the array, with the less significant byte stored first.
pack32be reg_1st, reg_count, byte_count
Converts multiple vm register values to an array of bytes. The value of a single register is stored as 4 bytes in the array, with the most significant byte stored first.
unpack8 reg_1st, reg_count
Converts an array of bytes to multiple vm register values. The value of a single register is loaded from a single byte of the array.
unpack16le reg_1st, reg_count, byte_count
Converts an array of bytes to multiple vm register values. The value of a single register is loaded from a pair of bytes of the array, with the less significant byte stored first.
unpack16be reg_1st, reg_count, byte_count
Converts an array of bytes to multiple vm register values. The value of a single register is loaded from a pair of bytes of the array, with the most significant byte stored first.
unpack32le reg_1st, reg_count, byte_count
Converts an array of bytes to multiple vm register values. The value of a single register is loaded from 4 bytes of the array, with the less significant byte stored first.
unpack32be reg_1st, reg_count, byte_count
Converts an array of bytes to multiple vm register values. The value of a single register is loaded from 4 bytes of the array, with the most significant byte stored first.

The following instructions are available to dump raw data in the program:

Instruction
Description
data8 value, ...
Dump at least one 8 bits word value in the program.
data[16,32] value, ...
Dump at least one aligned multi-bytes value with platform endianess.
data[16,32][le,be] value, ...
Dump at least one aligned multi-bytes value with specified endianess.
str "string"
Dump a character string.
strc "string"
Dump a null terminated string.
strp "string"
Dump a pascal string (with a leading length byte).

See also CONFIG_MUTEK_BYTECODE_DEBUG, bc_set_trace and bc_ccall_function_t.

Generic opcodes table [link] 

instruction
operands
opcode 16 bits word(s)
format
end
0000 0000 0000 0000
0
dump
0000 0000 0000 0001
0
abort
0000 0000 0000 0010
0
die
0000 0000 0000 0011
0
nop
0000 0000 0000 0100
0
trace
m
0000 0000 0000 1mmm
0
add8
r, +/-v
0000 vvvv vvvv rrrr
0
cst8
r, v
0001 vvvv vvvv rrrr
0
call8
r, lbl
0010 llll llll rrrr
0
jmp8
lbl
0010 llll llll 0000
0
ret
r
0010 0000 0000 rrrr
0
call
r
0010 1111 1111 rrrr
0
loop
r, lbl
0011 0lll llll rrrr
0
{un,}pack8
r, c
0011 1ccc oooo rrrr
4
{un,}pack{16,32}{le,be}
r, c, b
0011 1ccc oooo rrrr
4
swap{16,32}{le,be,}
r
0011 1000 oooo rrrr
4
eq
a, b
0100 0000 bbbb aaaa a > b
1
neq
a, b
0100 0000 bbbb aaaa a < b
1
eq0
a
0100 0000 bbbb aaaa a == b
1
mov
a, b
0100 0001 bbbb aaaa a != b
1
neq0
a
0100 0001 bbbb aaaa a == b
1
lt
a, b
0100 0010 bbbb aaaa a != b
1
exts
a, 7
0100 0010 bbbb aaaa a == b
1
lts
a, b
0100 0011 bbbb aaaa a != b
1
exts
a, 15
0100 0011 bbbb aaaa a == b
1
lteq
a, b
0100 0100 bbbb aaaa a != b
1
exts
a, 31
0100 0100 bbbb aaaa a == b
1
lteqs
a, b
0100 0101 bbbb aaaa a != b
1
---
a
0100 0101 bbbb aaaa a == b
1
add
a, b
0100 0110 bbbb aaaa a != b
1
---
a
0100 0110 bbbb aaaa a == b
1
sub
a, b
0100 0111 bbbb aaaa a != b
1
neg
a
0100 0111 bbbb aaaa a == b
1
or32
a, b
0100 1000 bbbb aaaa a != b
1
rand32
a
0100 1000 bbbb aaaa a == b
1
xor32
a, b
0100 1001 bbbb aaaa a != b
1
ccall
a
0100 1001 bbbb aaaa a == b
1
and32
a, b
0100 1010 bbbb aaaa a != b
1
---
a
0100 1010 bbbb aaaa a == b
1
sha32
a, b
0100 1011 bbbb aaaa a != b
1
not32
a
0100 1011 bbbb aaaa a == b
1
shl32
a, b
0100 1100 bbbb aaaa a != b
1
---
a
0100 1100 bbbb aaaa a == b
1
shr32
a, b
0100 1101 bbbb aaaa a != b
1
---
a
0100 1101 bbbb aaaa a == b
1
mul32
a, b
0100 1110 bbbb aaaa
1
div32
a, b
0100 1111 bbbb aaaa a != b
1
msbs32
a
0100 1111 bbbb aaaa a == b
1
tst32[c,s]
r, bit
0101 00sb bbbb rrrr
2
bit32[c,s]
r, bit
0101 01sb bbbb rrrr
2
shi32[l,r]
r, bit
0101 10rb bbbb rrrr
2
shi32a
r, bit
0101 110b bbbb rrrr
2
extz
r, bit
0101 111b bbbb rrrr
2
ld[8,16,32,64][i]
r, ra
0110 ss0i aaaa rrrr
3
st[8,16,32,64][i]
r, ra
0110 ss1i aaaa rrrr
3
st[8,16,32,64]d
r, ra
0111 ss10 aaaa rrrr
3
ld[8,16,32,64]e
r, ra, +/-v
0111 ss01 aaaa rrrr, v
3
st[8,16,32,64]e
r, ra, +/-v
0111 ss11 aaaa rrrr, v
3
gaddr
r, lbl
0111 0000 0000 rrrr, v?
3
mode
mode
0111 0000 0001 mmmm
3
pick
r, mask
0111 0100 0000 mmmm, v m != 0
3
place
r, mask
0111 0100 0001 mmmm, v m != 0
3
cst[16,32]
r, v, b
0111 xs00 1bbb rrrr, v, v?
3
laddr[16,32][r]
r, lbl
0111 Rs00 0x1- rrrr, v, v?
3
jmp[16,32][r]
lbl
0111 Rs00 0100 rrrr, v, v?
3
call[16,32][r]
r, lbl
0111 Rs00 0101 rrrr, v, v?
3
custom
1--- ---- ---- ----

Members [link] 

Types [link] 

Functions [link] 

  • error_t bc_desc_init(struct bc_descriptor_s *desc, const void *code, size_t len, enum bc_flags_s flags)
  • void bc_dump(const struct bc_context_s *ctx, bool_t regs)
  • void bc_enable_bp(struct bc_context_s *ctx, uint_fast8_t idx, bool_t en)
  • void bc_enable_bps(struct bc_context_s *ctx, uint16_t mask)
  • uint8_t * bc_get_bytepack(const struct bc_context_s *ctx, uint_fast8_t i)
  • uint8_t * bc_get_bytepack_safe(const struct bc_context_s *ctx, uint_fast8_t i, size_t bytes)
  • uint_fast16_t bc_get_cycles(const struct bc_context_s *ctx)
  • uint_fast8_t bc_get_mode(const struct bc_context_s *ctx)
  • const void * bc_get_pc(const struct bc_context_s *ctx)
  • uintptr_t bc_get_reg(const struct bc_context_s *ctx, uint_fast8_t i)
  • uint32_t bc_get_sandbox_pc(const struct bc_context_s *ctx)
  • void bc_init(struct bc_context_s *ctx, const struct bc_descriptor_s *desc)
  • void bc_init_sandbox(struct bc_context_s *ctx, const struct bc_descriptor_s *desc, void *data_base, size_t data_size, uint_fast16_t cycles)
  • error_t bc_load(struct bc_descriptor_s *desc, const uint8_t *blob, size_t len)
  • const char * bc_opname(uint16_t op)
  • bc_opcode_t bc_run(struct bc_context_s *ctx)
  • error_t bc_set_bp(struct bc_context_s *ctx, uint_fast8_t idx, uintptr_t pc)
  • void bc_set_cycles(struct bc_context_s *ctx, uint_fast16_t cycles)
  • void bc_set_mode(struct bc_context_s *ctx, uint_fast8_t mode)
  • void bc_set_pc(struct bc_context_s *ctx, const void *pc)
  • void bc_set_reg(struct bc_context_s *ctx, uint_fast8_t i, uintptr_t value)
  • void bc_set_regs(struct bc_context_s *ctx, uint16_t mask, ...)
  • void bc_set_regs_va(struct bc_context_s *ctx, uint16_t mask, va_list ap)
  • error_t bc_set_sandbox_pc(struct bc_context_s *ctx, uint32_t pc)
  • void bc_set_trace(struct bc_context_s *ctx, enum bc_trace_e mode)
  • void bc_skip(struct bc_context_s *ctx)
  • bool_t bc_test_bp(const struct bc_context_s *ctx, const void *pc)
  • void * bc_translate_addr(struct bc_context_s *ctx, bc_reg_t addr, size_t size, bool_t writable)

Macros [link] 

Members detail [link] 

#define BC_CCALL_FUNCTION(n) [link] 

This macro is declared in mutek/bytecode.h source file, line 886.

See also BC_CCALL_FUNCTION.

#define BC_REG_FORMAT [link] 

This macro is declared in mutek/bytecode.h source file, line 474.

Preprocessor condition: INT_REG_SIZE <= 32 and not defined( CONFIG_MUTEK_BYTECODE_VM64 )

#define BC_REG_FORMAT [link] 

This macro is declared in mutek/bytecode.h source file, line 478.

Preprocessor condition: not ( INT_REG_SIZE <= 32 and not defined( CONFIG_MUTEK_BYTECODE_VM64 ))

#define BC_STATUS_CUSTOM(op) [link] 

This macro is declared in mutek/bytecode.h source file, line 519.

This macro tests if the return status of bc_run is a custom opcode or a value specified in enum bc_run_status_e

#define MUTEK_BYTECODE_H_ [link] 

This macro is declared in mutek/bytecode.h source file, line 21.

#define _BC_TRACE_ALL [link] 

This macro is declared in mutek/bytecode.h source file, line 489.

#define _BC_TRACE_JUMP [link] 

This macro is declared in mutek/bytecode.h source file, line 490.

#define _BC_TRACE_REGS [link] 

This macro is declared in mutek/bytecode.h source file, line 491.

typedef bc_reg_t (bc_ccall_function_t)(const struct bc_context_s *ctx) [link] 

This typedef is declared in mutek/bytecode.h source file, line 889.

C function type invoked by the ccall instruction.

This declaration involves expansion of the BC_CCALL_FUNCTION macro.

struct bc_context_s [link] 

This struct is declared in gfx/bytecode.h source file, line 34.

This struct defines the virtual machine context.

FieldDescription
bc_reg_t v[16];
union <anonymous> {
uintptr_t pc;Bytecode resume execution pointer. For native code, this is a pointer to the machine code instruction. For vm bytecode, this is a 16 bits aligned pointer to the next instruction word with the bit 0 indicating if the next instruction must be skipped on resume.
const void * vpc;
};
const struct bc_descriptor_s * desc;
uint8_t skip;
uint8_t mode;
void * data_base;address of writable data segment when sandboxed
uintptr_t data_end;mask address of writable data segment when sandboxed
uint16_t max_cycles;maximum number of executed cycles by a single call to bc_run_sandbox
uintptr_t bp_list[CONFIG_MUTEK_BYTECODE_BREAKPOINTS];
uint16_t bp_mask;
bool_t bp_skip:1;
enum bc_trace_e trace:3;
bool_t sandbox:1;See bc_init_sandbox.

error_t bc_desc_init(struct bc_descriptor_s *desc, const void *code, size_t len, enum bc_flags_s flags) [link] 

This function is declared in mutek/bytecode.h source file, line 660.

This function initializes a bytecode descriptor. This can be used in place of bc_load when some raw bytecode is loaded in memory.

struct bc_descriptor_s [link] 

This struct is declared in device/class/spi.h source file, line 421.

This struct is the bytecode descriptor header

FieldDescription
const void * code;
bc_run_t * run;
uint32_t flags;

void bc_dump(const struct bc_context_s *ctx, bool_t regs) [link] 

This function is declared in mutek/bytecode.h source file, line 835.

This function dumps the virtual machine state. If the CONFIG_MUTEK_BYTECODE_DEBUG token is not defined, this function has no effect.

void bc_enable_bp(struct bc_context_s *ctx, uint_fast8_t idx, bool_t en) [link] 

This function is declared in mutek/bytecode.h source file, line 775.

This function function enable or disable a breakpoint.

See also CONFIG_MUTEK_BYTECODE_BREAKPOINTS.

void bc_enable_bps(struct bc_context_s *ctx, uint16_t mask) [link] 

This function is declared in mutek/bytecode.h source file, line 788.

This function function enable or disable multiple breakpoints.

See also CONFIG_MUTEK_BYTECODE_BREAKPOINTS.

uint8_t * bc_get_bytepack(const struct bc_context_s *ctx, uint_fast8_t i) [link] 

This function is declared in mutek/bytecode.h source file, line 684.

This function returns a pointer to a packed array of bytes stored in virtual machine register storage. See the pack and unpack instructions.

uint8_t * bc_get_bytepack_safe(const struct bc_context_s *ctx, uint_fast8_t i, size_t bytes) [link] 

This function is declared in mutek/bytecode.h source file, line 695.

This function returns a pointer to a packed array of bytes stored in virtual machine register storage. When the index of the register is to high for the specified number of bytes, a pointer to register 0 is retured instead.

uint_fast16_t bc_get_cycles(const struct bc_context_s *ctx) [link] 

This function is declared in mutek/bytecode.h source file, line 628.

This is available when CONFIG_MUTEK_BYTECODE_SANDBOX is defined.

See also bc_set_cycles.

uint_fast8_t bc_get_mode(const struct bc_context_s *ctx) [link] 

This function is declared in mutek/bytecode.h source file, line 818.

This function returns the current bytecode execution mode

const void * bc_get_pc(const struct bc_context_s *ctx) [link] 

This function is declared in mutek/bytecode.h source file, line 713.

This function returns the value of the virtual machine program counter in the host address space.

See also bc_get_sandbox_pc.

uintptr_t bc_get_reg(const struct bc_context_s *ctx, uint_fast8_t i) [link] 

This function is declared in mutek/bytecode.h source file, line 676.

This function returns the value of one of the 16 virtual machine registers

uint32_t bc_get_sandbox_pc(const struct bc_context_s *ctx) [link] 

This function is declared in mutek/bytecode.h source file, line 738.

This function returns the program counter of a sandboxed virtual machine.

This is available when CONFIG_MUTEK_BYTECODE_SANDBOX is defined.

void bc_init(struct bc_context_s *ctx, const struct bc_descriptor_s *desc) [link] 

This function is declared in mutek/bytecode.h source file, line 583.

This function initializes the virtual machine. The initial value of the registers is undefined.

void bc_init_sandbox(struct bc_context_s *ctx, const struct bc_descriptor_s *desc, void *data_base, size_t data_size, uint_fast16_t cycles) [link] 

This function is declared in mutek/bytecode.h source file, line 611.

This function initializes the virtual machine in sandbox mode. When working in sandbox mode, address are translated and the following checks are performed:

  • Execution of instructions are not allowed outside of the code segment specified in the bytecode descriptor. Code base address inside the virtual machine is 0.

  • Load and store instructions addresses are translated from 0x80000000 to the data_base address. Loads below 0x8000000 are translated to the code segment.

  • The ccall instruction can not be used.

  • The abort instruction is equivalent to die.

When in sandbox mode on a 64 bits target, instructions wont touch registers above bit 31. This makes the sandbox a 32 bits virtual machine.

The cycles parameter specifies the initial number of cycles executed by the bc_run function before it returns BC_RUN_STATUS_CYCLES.

This is available when CONFIG_MUTEK_BYTECODE_SANDBOX is defined.

error_t bc_load(struct bc_descriptor_s *desc, const uint8_t *blob, size_t len) [link] 

This function is declared in mutek/bytecode.h source file, line 653.

This function initializes a bytecode descriptor from a bytecode loadable blob. The format of the blob is:

  • flags in 16 bits little endian representation

  • words count in 16 bits little endian representation

  • instruction words

The blob pointer must be 16 bits aligned.

See also bc_desc_init.

typedef uint16_t bc_opcode_t [link] 

This typedef is declared in mutek/bytecode.h source file, line 470.

const char * bc_opname(uint16_t op) [link] 

This function is declared in mutek/bytecode.h source file, line 830.

This function returns the instruction name from an opcode.

This is available when CONFIG_MUTEK_BYTECODE_VM is defined.

typedef uint32_t bc_reg_t [link] 

This typedef is declared in mutek/bytecode.h source file, line 473.

Alternate declarations with same identifier: [1], [2].

Preprocessor condition: INT_REG_SIZE <= 32 and not defined( CONFIG_MUTEK_BYTECODE_VM64 )

typedef uint64_t bc_reg_t [link] 

This typedef is declared in mutek/bytecode.h source file, line 477.

Alternate declarations with same identifier: [1], [2].

Preprocessor condition: not ( INT_REG_SIZE <= 32 and not defined( CONFIG_MUTEK_BYTECODE_VM64 ))

bc_opcode_t bc_run(struct bc_context_s *ctx) [link] 

This function is declared in mutek/bytecode.h source file, line 861.

This function starts or resumes executions of the bytecode.

It returns under the following conditions:

  • When the end instruction is encountered, the function returns BC_RUN_STATUS_END.

  • When an error occurs, the function returns BC_RUN_STATUS_FAULT.

  • When a custom instruction is encountered, the opcode of the instruction is returned. The opcode is a 16 bits value not less than 0x8000. The caller must handle the custom instruction and resume execution of the bytecode.

  • When sandboxing is used and the maximum number of cycles has been reached, the function returns BC_RUN_STATUS_CYCLES. The limit can be updated and the bytecode may then be resumed.

  • When breakpoints are used, the function may return BC_RUN_STATUS_BREAK. The bytecode may then be resumed.

This function will either run the virtual machine or jump to the machine compiled bytecode. The type of bytecode is guessed from the descriptor.

enum bc_run_status_e [link] 

This enum is declared in mutek/bytecode.h source file, line 511.

This enum specifes status codes returned by the bc_run function.

See also BC_STATUS_CUSTOM.

IdentifierDescription
BC_RUN_STATUS_END
BC_RUN_STATUS_CYCLES
BC_RUN_STATUS_BREAK
BC_RUN_STATUS_FAULT

error_t bc_set_bp(struct bc_context_s *ctx, uint_fast8_t idx, uintptr_t pc) [link] 

This function is declared in mutek/bytecode.h source file, line 758.

This function function set the address of a breakpoint. This does not enable the breakpoint.

See also bc_enable_bp and CONFIG_MUTEK_BYTECODE_BREAKPOINTS.

void bc_set_cycles(struct bc_context_s *ctx, uint_fast16_t cycles) [link] 

This function is declared in mutek/bytecode.h source file, line 620.

This function updates the remaining number of cycles before the bc_run function returns BC_RUN_STATUS_CYCLES.

This is available when CONFIG_MUTEK_BYTECODE_SANDBOX is defined.

void bc_set_mode(struct bc_context_s *ctx, uint_fast8_t mode) [link] 

This function is declared in mutek/bytecode.h source file, line 824.

This function sets the current bytecode execution mode

void bc_set_pc(struct bc_context_s *ctx, const void *pc) [link] 

This function is declared in mutek/bytecode.h source file, line 721.

This function changes the value of the virtual machine program counter in the host address space.

See also bc_set_sandbox_pc.

void bc_set_reg(struct bc_context_s *ctx, uint_fast8_t i, uintptr_t value) [link] 

This function is declared in mutek/bytecode.h source file, line 705.

This function sets the value of one of the 16 virtual machine registers

void bc_set_regs(struct bc_context_s *ctx, uint16_t mask, ...) [link] 

This function is declared in mutek/bytecode.h source file, line 671.

This function set the value of multiple registers of the virtual machine. The mask parameter specifies which register must be initialized. An additional value of type uintptr_t must be passed for each bit set in mask.

void bc_set_regs_va(struct bc_context_s *ctx, uint16_t mask, va_list ap) [link] 

This function is declared in mutek/bytecode.h source file, line 664.

See also bc_set_regs.

error_t bc_set_sandbox_pc(struct bc_context_s *ctx, uint32_t pc) [link] 

This function is declared in mutek/bytecode.h source file, line 730.

This function changes the program counter of a sandboxed virtual machine.

This is available when CONFIG_MUTEK_BYTECODE_SANDBOX is defined.

void bc_set_trace(struct bc_context_s *ctx, enum bc_trace_e mode) [link] 

This function is declared in mutek/bytecode.h source file, line 746.

This function function enables or disable the bytecode execution trace debug output. If the CONFIG_MUTEK_BYTECODE_TRACE token is not defined, this function has no effect. The trace instruction can be used to enable and disable trace output.

void bc_skip(struct bc_context_s *ctx) [link] 

This function is declared in mutek/bytecode.h source file, line 807.

This function skip the next instruction. This can only be called if the execution has stopped on a conditional custom instruction.

A single instruction can be skipped. When executed more than once without restarting execution of the bytecode, this function does nothing.

typedef int32_t bc_sreg_t [link] 

This typedef is declared in mutek/bytecode.h source file, line 474.

Alternate declarations with same identifier: [1], [2].

Preprocessor condition: INT_REG_SIZE <= 32 and not defined( CONFIG_MUTEK_BYTECODE_VM64 )

typedef int64_t bc_sreg_t [link] 

This typedef is declared in mutek/bytecode.h source file, line 478.

Alternate declarations with same identifier: [1], [2].

Preprocessor condition: not ( INT_REG_SIZE <= 32 and not defined( CONFIG_MUTEK_BYTECODE_VM64 ))

bool_t bc_test_bp(const struct bc_context_s *ctx, const void *pc) [link] 

This function is declared in mutek/bytecode.h source file, line 797.

This function returns 1 if the provided address is an enabled breakpoint

enum bc_trace_e [link] 

This enum is declared in mutek/bytecode.h source file, line 495.

IdentifierDescription
BC_TRACE_DISABLED
BC_TRACE_ALL
BC_TRACE_JUMP
BC_TRACE_ALL_REGS
BC_TRACE_JUMP_REGS

void * bc_translate_addr(struct bc_context_s *ctx, bc_reg_t addr, size_t size, bool_t writable) [link] 

This function is declared in mutek/bytecode.h source file, line 638.

This function translates an address from the sandbox virtual machine address space to an usable pointer. This returns NULL if the address range is not valid and contiguous inside the sandbox.

When the writable argument is set, the function return NULL if the address range is not writable in the sandbox.

This is available when CONFIG_MUTEK_BYTECODE_SANDBOX is defined.

typedef struct bytecode_entry_s bytecode_entry_t [link] 

This typedef is declared in mutek/bytecode.h source file, line 506.

This typedef can be used to declare bytecode entry points.

See also bc_set_pc.

enum bc_flags_s [link] 

This enum is declared in mutek/bytecode.h source file, line 484.

This enum is for internal use only.

IdentifierDescription
BC_FLAGS_NATIVE
BC_FLAGS_SANDBOX
BC_FLAGS_SIZEMASK

enum bc_opcode_pack_e [link] 

This enum is declared in mutek/bytecode.h source file, line 867.

This enum specifies packing and byteswap opcode operations

This enum is for internal use only.

IdentifierDescription
BC_OP_PACK8
BC_OP_PACK16LE
BC_OP_PACK16BE
BC_OP_UNPACK16LE
BC_OP_UNPACK16BE
BC_OP_SWAP16LE
BC_OP_SWAP16BE
BC_OP_SWAP16
BC_OP_UNPACK8
BC_OP_PACK32LE
BC_OP_PACK32BE
BC_OP_UNPACK32LE
BC_OP_UNPACK32BE
BC_OP_SWAP32LE
BC_OP_SWAP32BE
BC_OP_SWAP32

typedef bc_opcode_t (bc_run_t)(struct bc_context_s *ctx) [link] 

This typedef is declared in mutek/bytecode.h source file, line 523.

This typedef is for internal use only.

Valid XHTML 1.0 StrictGenerated by diaxen on Thu Aug 4 15:44:06 2022 using MkDoc