Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

Commit

Permalink
[tests] [lucet-runtime] port remaining top-level tests to C API
Browse files Browse the repository at this point in the history
This required some shenanigans with the probestack definition to get it exported in the final
`lucet_runtime.so`. I left a TODO in the code to revert it once [this Rust
issue](https://github.com/rust-lang/rust/issues/36342) is fixed.
  • Loading branch information
acfoltzer committed Feb 22, 2019
1 parent 3f968ff commit be0ef55
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 244 deletions.
4 changes: 2 additions & 2 deletions lucet-runtime/lucet-runtime-internals/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub use lucet_module_data::{Global, GlobalSpec, HeapSpec};

use crate::alloc::Limits;
use crate::error::Error;
use crate::probestack::{lucet_probestack, lucet_probestack_size};
use crate::probestack::{lucet_probestack_private, lucet_probestack_size};
use crate::trapcode::{TrapCode, TrapCodeType};
use libc::c_void;
use std::slice::from_raw_parts;
Expand Down Expand Up @@ -138,7 +138,7 @@ pub trait ModuleInternal: Send + Sync {
}

// handle the special case when the probe stack is running
let probestack = lucet_probestack as *const c_void;
let probestack = lucet_probestack_private as *const c_void;
if rip >= probestack
&& rip as usize <= probestack as usize + unsafe { lucet_probestack_size } as usize
{
Expand Down
11 changes: 10 additions & 1 deletion lucet-runtime/lucet-runtime-internals/src/probestack/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
extern "C" {
pub fn lucet_probestack();
pub fn lucet_probestack_private();
pub static lucet_probestack_size: u32;
}

#[no_mangle]
pub unsafe extern "C" fn lucet_probestack() {
// TODO: this is a hack to make sure the symbol `lucet_probestack` is exported in
// `lucet_runtime.so`: see https://github.com/rust-lang/rust/issues/36342. As soon as that issue
// is resolved, we should remove this to avoid any safety issues around the weird probestack
// calling convention, and to avoid the overhead of an additional function call.
lucet_probestack_private()
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
// determine the code size, and update the constant.

.text
.globl lucet_probestack
.type lucet_probestack,@function
.globl lucet_probestack_private
.type lucet_probestack_private,@function
.align 16
lucet_probestack:
lucet_probestack_private:
// Our goal is to touch every page between %rsp+8 and %rsp+8-%rax,
// ensuring that if any pages in that range are unmapped, we will
// cause a page fault, which liblucet will recognize as a stack overflow.
Expand Down Expand Up @@ -46,10 +46,10 @@ lucet_probestack:
add %rax,%rsp

ret
.size lucet_probestack,.-lucet_probestack
.size lucet_probestack_private,.-lucet_probestack_private
.globl lucet_probestack_size
.type lucet_probestack_size,@object
lucet_probestack_size: .quad .-lucet_probestack
lucet_probestack_size: .quad .-lucet_probestack_private

/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
1 change: 1 addition & 0 deletions lucet-runtime/lucet-runtime-internals/src/vmctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ pub fn vmctx_capi_init() {
read_volatile(lucet_vmctx_terminate as *const extern "C" fn());
read_volatile(lucet_vmctx_get_delegate as *const extern "C" fn());
read_volatile(lucet_vmctx_get_func_from_idx as *const extern "C" fn());
read_volatile(crate::probestack::lucet_probestack as *const c_void);
});
}

Expand Down
19 changes: 11 additions & 8 deletions lucet-runtime/src/c_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ pub struct lucet_alloc_limits {

impl From<Limits> for lucet_alloc_limits {
fn from(limits: Limits) -> lucet_alloc_limits {
limits.into()
(&limits).into()
}
}

Expand All @@ -156,7 +156,7 @@ impl From<&Limits> for lucet_alloc_limits {

impl From<lucet_alloc_limits> for Limits {
fn from(limits: lucet_alloc_limits) -> Limits {
limits.into()
(&limits).into()
}
}

Expand Down Expand Up @@ -237,7 +237,10 @@ pub unsafe extern "C" fn lucet_dl_module_load(
mod_out.write(Arc::into_raw(m) as _);
lucet_error::Ok
})
.unwrap_or_else(|e| e.into())
.unwrap_or_else(|e| {
// eprintln!("lucet_dl_module_load error: {}", e);
e.into()
})
}

#[no_mangle]
Expand Down Expand Up @@ -573,7 +576,7 @@ mod lucet_state {

impl From<TrapCodeType> for lucet_trapcode_type {
fn from(ty: TrapCodeType) -> lucet_trapcode_type {
ty.into()
(&ty).into()
}
}

Expand Down Expand Up @@ -605,7 +608,7 @@ mod lucet_state {

impl From<TrapCode> for lucet_trapcode {
fn from(trap: TrapCode) -> lucet_trapcode {
trap.into()
(&trap).into()
}
}

Expand Down Expand Up @@ -640,7 +643,7 @@ mod lucet_state {

impl From<Option<AddrDetails>> for lucet_module_addr_details {
fn from(details: Option<AddrDetails>) -> Self {
details.into()
(&details).into()
}
}

Expand Down Expand Up @@ -722,7 +725,7 @@ mod lucet_val {

impl From<lucet_val> for Val {
fn from(val: lucet_val) -> Val {
val.into()
(&val).into()
}
}

Expand Down Expand Up @@ -750,7 +753,7 @@ mod lucet_val {

impl From<Val> for lucet_val {
fn from(val: Val) -> Self {
val.into()
(&val).into()
}
}

Expand Down
23 changes: 6 additions & 17 deletions tests/Makefile.vars
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@


# LUCET_TEST_OBJECTS:= $(addprefix build/, \
# lucet_test.o \
# guest_module.o \
# host_suite.o \
# session_suite.o \
# session_hostcalls.o \
# session.o \
# entrypoint_suite.o \
# memory_suite.o \
# strcmp_suite.o \
# stack_suite.o \
# start_suite.o \
# globals_suite.o \
# )

LUCET_TEST_OBJECTS:= $(addprefix build/, \
lucet_test.o \
test_helpers.o \
host_suite.o \
session_suite.o \
session_hostcalls.o \
session.o \
entrypoint_suite.o \
memory_suite.o \
strcmp_suite.o \
stack_suite.o \
start_suite.o \
globals_suite.o \
)

Expand Down
2 changes: 1 addition & 1 deletion tests/host_suite.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEST test_load_module(const char *path)
TEST test_load_nonexistent_module(void)
{
struct lucet_dl_module *mod;
enum lucet_error err = lucet_dl_module_load("nonexistent_sandbox", &mod);
enum lucet_error err = lucet_dl_module_load("nonexistent_sandbox", &mod);

ASSERT_ENUM_EQ(lucet_error_dl, err, lucet_error_name);

Expand Down
16 changes: 8 additions & 8 deletions tests/lucet_test.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#include "greatest.h"

SUITE_EXTERN(host_suite);
/* SUITE_EXTERN(session_suite); */
SUITE_EXTERN(session_suite);
SUITE_EXTERN(entrypoint_suite);
SUITE_EXTERN(memory_suite);
/* SUITE_EXTERN(strcmp_suite); */
/* SUITE_EXTERN(stack_suite); */
SUITE_EXTERN(strcmp_suite);
SUITE_EXTERN(stack_suite);
SUITE_EXTERN(globals_suite);
/* SUITE_EXTERN(start_suite); */
SUITE_EXTERN(start_suite);

GREATEST_MAIN_DEFS();

Expand All @@ -16,13 +16,13 @@ int main(int argc, char **argv)
GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */

RUN_SUITE(host_suite);
/* RUN_SUITE(session_suite); */
RUN_SUITE(session_suite);
RUN_SUITE(entrypoint_suite);
RUN_SUITE(memory_suite);
/* RUN_SUITE(strcmp_suite); */
/* RUN_SUITE(stack_suite); */
RUN_SUITE(strcmp_suite);
RUN_SUITE(stack_suite);
RUN_SUITE(globals_suite);
/* RUN_SUITE(start_suite); */
RUN_SUITE(start_suite);

GREATEST_MAIN_END(); /* display results */
}
81 changes: 37 additions & 44 deletions tests/session_suite.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
#include <stdio.h>

#include "greatest.h"
#include "guest_module.h"
#include "lucet.h"
#include "lucet_libc.h"
#include "session.h"
#include "test_helpers.h"

#define HELLO_MOD_PATH "session_guests/hello.so"
#define ALLOC_MOD_PATH "session_guests/alloc.so"
Expand All @@ -24,45 +24,38 @@ static void session_stdio_handler(struct lucet_libc *libc, int32_t fd, const cha
session_stdio_write(sess, fd, buf, len);
}

TEST run(const char *mod_path, struct session *session, struct lucet_state *exit_state)
TEST run(const char *mod_path, struct session *session, enum lucet_error *err_out)
{
struct lucet_pool *pool = lucet_pool_create(1, NULL);
ASSERTm("failed to create pool", pool != NULL);
struct lucet_module *mod = lucet_module_load(guest_module_path(mod_path));
ASSERTm("failed to load module", mod != NULL);
struct lucet_dl_module *mod;
ASSERT_OK(lucet_dl_module_load(guest_module_path(mod_path), &mod));

struct lucet_mmap_region *region;
ASSERT_OK(lucet_mmap_region_create(1, NULL, &region));

// Now we have all the ingredients to create an instance, and run it
struct lucet_instance *instance;
instance = lucet_instance_create(pool, mod, session);
struct lucet_instance *inst;
ASSERT_OK(lucet_mmap_region_new_instance_with_ctx(region, mod, session, &inst));

lucet_libc_set_stdio_handler(&session->libc, session_stdio_handler);

ASSERTm("lucet_instance_create returned NULL", instance != NULL);

lucet_instance_run(instance, "main", 0);

// Copy out state as of program termination
const struct lucet_state *state;
state = lucet_instance_get_state(instance);
memcpy(exit_state, state, sizeof(struct lucet_state));

lucet_instance_release(instance);
*err_out = lucet_instance_run(inst, "main", 0, (struct lucet_val[]){});

lucet_module_unload(mod);
lucet_instance_release(inst);
lucet_dl_module_release(mod);
lucet_mmap_region_release(region);

lucet_pool_decref(pool);
PASS();
}

TEST test_run_session_hello_0(void)
{
struct lucet_state end_state;
struct session session = { 0 };
enum lucet_error err;
struct session session = { 0 };
session_create(&session, (const unsigned char *) request_header[0]);

CHECK_CALL(run(HELLO_MOD_PATH, &session, &end_state));
CHECK_CALL(run(HELLO_MOD_PATH, &session, &err));

ASSERT_ENUM_EQ(lucet_state_terminated, end_state.tag, lucet_state_name);
ASSERT_ENUM_EQ(lucet_error_runtime_terminated, err, lucet_error_name);
ASSERT_ENUM_EQ(lucet_libc_term_exit, session.libc.term_reason, lucet_libc_term_reason_str);
ASSERT_EQ(0, lucet_libc_exit_code(&session.libc));

Expand All @@ -77,13 +70,13 @@ TEST test_run_session_hello_0(void)

TEST test_run_session_hello_1(void)
{
struct lucet_state end_state;
struct session session = { 0 };
enum lucet_error err;
struct session session = { 0 };
session_create(&session, (const unsigned char *) request_header[1]);

CHECK_CALL(run(HELLO_MOD_PATH, &session, &end_state));
CHECK_CALL(run(HELLO_MOD_PATH, &session, &err));

ASSERT_ENUM_EQ(lucet_state_terminated, end_state.tag, lucet_state_name);
ASSERT_ENUM_EQ(lucet_error_runtime_terminated, err, lucet_error_name);
ASSERT_ENUM_EQ(lucet_libc_term_exit, session.libc.term_reason, lucet_libc_term_reason_str);
ASSERT_EQ(0, lucet_libc_exit_code(&session.libc));

Expand All @@ -98,13 +91,13 @@ TEST test_run_session_hello_1(void)

TEST test_run_session_hello_2(void)
{
struct lucet_state end_state;
struct session session = { 0 };
enum lucet_error err;
struct session session = { 0 };
session_create(&session, (const unsigned char *) request_header[2]);

CHECK_CALL(run(HELLO_MOD_PATH, &session, &end_state));
CHECK_CALL(run(HELLO_MOD_PATH, &session, &err));

ASSERT_ENUM_EQ(lucet_state_terminated, end_state.tag, lucet_state_name);
ASSERT_ENUM_EQ(lucet_error_runtime_terminated, err, lucet_error_name);
ASSERT_ENUM_EQ(lucet_libc_term_exit, session.libc.term_reason, lucet_libc_term_reason_str);
ASSERT_EQ(-1, lucet_libc_exit_code(&session.libc));

Expand All @@ -120,13 +113,13 @@ TEST test_run_session_hello_2(void)

TEST test_run_session_hello_3(void)
{
struct lucet_state end_state;
struct session session = { 0 };
enum lucet_error err;
struct session session = { 0 };
session_create(&session, (const unsigned char *) request_header[3]);

CHECK_CALL(run(HELLO_MOD_PATH, &session, &end_state));
CHECK_CALL(run(HELLO_MOD_PATH, &session, &err));

ASSERT_ENUM_EQ(lucet_state_fault, end_state.tag, lucet_state_name);
ASSERT_ENUM_EQ(lucet_error_runtime_fault, err, lucet_error_name);

ASSERT_STR_EQm("session output",
"hello from sandbox_hello.c!\n"
Expand All @@ -140,13 +133,13 @@ TEST test_run_session_hello_3(void)

TEST test_run_session_alloc(void)
{
struct lucet_state end_state;
struct session session = { 0 };
enum lucet_error err;
struct session session = { 0 };
session_create(&session, (const unsigned char *) request_header[0]);

CHECK_CALL(run(ALLOC_MOD_PATH, &session, &end_state));
CHECK_CALL(run(ALLOC_MOD_PATH, &session, &err));

ASSERT_ENUM_EQ(lucet_state_ready, end_state.tag, lucet_state_name);
ASSERT_ENUM_EQ(lucet_error_ok, err, lucet_error_name);

ASSERT_STR_EQm("session output",
"hello from sandbox_alloc.c!\n"
Expand All @@ -159,13 +152,13 @@ TEST test_run_session_alloc(void)

TEST test_run_session_stdio(void)
{
struct lucet_state end_state;
struct session session = { 0 };
enum lucet_error err;
struct session session = { 0 };
session_create(&session, (const unsigned char *) request_header[0]);

CHECK_CALL(run(STDIO_MOD_PATH, &session, &end_state));
CHECK_CALL(run(STDIO_MOD_PATH, &session, &err));

ASSERT_ENUM_EQ(lucet_state_terminated, end_state.tag, lucet_state_name);
ASSERT_ENUM_EQ(lucet_error_runtime_terminated, err, lucet_error_name);
ASSERT_ENUM_EQ(lucet_libc_term_exit, session.libc.term_reason, lucet_libc_term_reason_str);
ASSERT_EQ(0, lucet_libc_exit_code(&session.libc));

Expand Down
Loading

0 comments on commit be0ef55

Please sign in to comment.