Skip to content

Commit

Permalink
Turn interpositions into macro, implement for read, write
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-u committed Nov 15, 2022
1 parent d6d5c93 commit 42f26a6
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 107 deletions.
107 changes: 3 additions & 104 deletions bin/shortcut/sc_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,107 +271,6 @@ void egress_work(struct fn_ctrl *ctrl) {
}

// This macro allocates a "real_" fn ptr, a "ksys_" fn ptr, and a fn_ctrl struct
MAKE_STRUCTS(write, ssize_t (*write_t)(int fd, const void *buf, size_t count))
MAKE_STRUCTS(read, ssize_t (*read_t)(int fd, void *buf, size_t count))

MAKE_INTERPOSE_FN(write, ssize_t, (int fd, const void *buf, size_t count))



// This is awkward, but it is an effort to minimize the scope of differences
// btw fns.

// Pointer to the ctrl struct.
// struct fn_ctrl *ctrl = &write_ctrl;

// Shortcut fn has same signature as write
// typedef write_t shortcut_fn_t;

// typedef int (*shortcut_fn_t)(unsigned int fd, const char *buf, size_t
// count);
typedef write_t real_fn_t;

// Pointer to real_write, generic version
real_fn_t *real_fn = &real_write;

// Pointer to shortcut_write, generic version
// shortcut_fn_t *shortcut_fn = &ksys_write;

// String name of shortcut target
char *shortcut_target = "ksys_write";

// If real_write is null, get it from dlsym
if (! real_write) {
// Place to do one time work
// Configs ctrl struct with envt variables, gets ptrs to real and shortcut
// fns
get_fn_config_and_targets(&write_ctrl, (void **)real_fn, (void **) &ksys_write,
shortcut_target, __func__);
}

// Pre fn work e.g. elevation
ingress_work(&write_ctrl);

int ret;
// Call real write
if (write_ctrl.do_shortcut) {
// Awkward, but we have to deref the ptr to the fn ptr
ret = ksys_write(fd, buf, count);
} else {
ret = (*real_fn)(fd, buf, count);
}

egress_work(&write_ctrl);

return ret;
}

ssize_t read(int fd, void *buf, size_t len) {

// This is awkward, but it is an effort to minimize the scope of differences
// btw fns.

// Pointer to the ctrl struct.
struct fn_ctrl *ctrl = &read_ctrl;

// Shortcut fn has same signature as write
typedef read_t shortcut_fn_t;

// typedef int (*shortcut_fn_t)(unsigned int fd, const char *buf, size_t
// count);
typedef read_t real_fn_t;

// Pointer to real_write, generic version
real_fn_t *real_fn = &real_read;

// Pointer to shortcut_write, generic version
shortcut_fn_t *shortcut_fn = &ksys_read;

// String name of shortcut target
char *shortcut_target = "ksys_read";

// If real_write is null, get it from dlsym
if (!(*real_fn)) {
// Place to do one time work
// Configs ctrl struct with envt variables, gets ptrs to real and shortcut
// fns
get_fn_config_and_targets(ctrl, (void **)real_fn, (void **)shortcut_fn,
shortcut_target, __func__);
}

// Pre fn work e.g. elevation
ingress_work(ctrl);

int ret;
// Call real write
if (ctrl->do_shortcut) {
// Awkward, but we have to deref the ptr to the fn ptr
ret = (*shortcut_fn)(fd, buf, len);
} else {
ret = (*real_fn)(fd, buf, len);
}

egress_work(ctrl);

return ret;
}
// Then it implements the relevant interposer fn.
MAKE_STRUCTS_AND_FN(write, ssize_t, int, fd, const void *, buf, size_t, count)
MAKE_STRUCTS_AND_FN(read, ssize_t, int, fd, void *, buf, size_t, count)
31 changes: 28 additions & 3 deletions bin/shortcut/sc_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#include <stdbool.h>

// Struct that contains all flags for function interposition

// HACK: huge hack to toggle shortcut
int master_toggle_shortcut = 0;

struct fn_ctrl {
// Do we need to run a pre/post condition around fn call?
bool sandwich_fn;
Expand All @@ -26,10 +30,31 @@ struct fn_ctrl {
struct fn_ctrl fn_name##_ctrl = {0, 0, 0, 0}; \
fn_name##_t ksys_##fn_name = NULL;

#define MAKE_INTERPOSE_FN(fn_name, ret_t, args) \
ret_t fn_name args {
// If real_write is null, get it from dlsym
// Place to do one time work
// Configs ctrl struct with envt variables, gets ptrs to real and shortcut

#define MAKE_INTERPOSE_FN(fn_name, ret_t, t_1, arg_1, t_2, arg_2, t_3, arg_3 ) \
ret_t fn_name ( t_1 arg_1, t_2 arg_2, t_3 arg_3 ) { \
if (! real_##fn_name ) { \
get_fn_config_and_targets(& fn_name##_ctrl, (void **)&real_##fn_name, (void **) &ksys_##fn_name, \
"ksys_"#fn_name, __func__); \
} \
ingress_work(&fn_name##_ctrl); \
int ret; \
if (fn_name##_ctrl.do_shortcut ^ master_toggle_shortcut) { \
ret = ksys_##fn_name( arg_1, arg_2, arg_3 ); \
} else { \
ret = real_##fn_name( arg_1, arg_2, arg_3 ); \
} \
egress_work(&fn_name##_ctrl); \
return ret;\
}

void fn(){};
// Combine both structs, variables and fn
#define MAKE_STRUCTS_AND_FN(fn_name, ret_t, t_1, arg_1, t_2, arg_2, t_3, arg_3 ) \
MAKE_STRUCTS(fn_name, ret_t (*fn_name##_t) ( t_1 arg_1, t_2 arg_2, t_3 arg_3) ) \
MAKE_INTERPOSE_FN(fn_name, ret_t, t_1, arg_1, t_2, arg_2, t_3, arg_3)


#endif

0 comments on commit 42f26a6

Please sign in to comment.