diff --git a/Makefile.am b/Makefile.am index 0bebed8..a19a29d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,8 @@ -SUBDIRS = . src docs +SUBDIRS = . src + +if HAVE_DOXYGEN +SUBDIRS += docs +endif EXTRA_DIST = regen.sh diff --git a/configure.ac b/configure.ac index 6b5d1a6..6702c13 100644 --- a/configure.ac +++ b/configure.ac @@ -5,25 +5,37 @@ AC_PREREQ([2.69]) AC_INIT([asmsh], [0.0-dev], [asmsh@yannweb.net]) AM_INIT_AUTOMAKE([-Wall]) -AC_ARG_ENABLE([check],[ --disable-check disable unit test support], -[case "${enableval}" in - yes) check=true ;; - no) check=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-check]) ;; -esac],[check=true]) -AM_CONDITIONAL([CHECK], [test x$check = xtrue]) +AC_ARG_WITH([readline], + [AS_HELP_STRING([--without-readline], + [disable support for readline])], + [], + [with_readline=yes]) +AC_ARG_WITH([doxygen], + [AS_HELP_STRING([--without-doxygen], + [disable code documentation])], + [], + [with_doxygen=yes]) + +AC_ARG_WITH([check], + [AS_HELP_STRING([--without-check], + [disable unit-tests])], + [], + [with_check=yes]) + +AM_CONDITIONAL([CHECK], [test x$with_check = xyes]) # Checks for libraries. -if test "x$check" = "xtrue" -then +AS_IF([test "x$with_check" = "xyes"], + [ + PKG_PROG_PKG_CONFIG([1.8]) PKG_CHECK_MODULES([CHECK], [check >= 0.9.4], [], AC_MSG_FAILURE([Unable to locate (check unit test c framework). You can run ./configure --disable-check if you do not need unit tests. ])) AS_IF([test x$debug = xtrue], [CK_FORK=no],[]) -fi - + ] +) AC_CONFIG_SRCDIR([src/asmsh.c]) @@ -32,7 +44,7 @@ AC_CONFIG_HEADERS([src/config.h]) # Checks for programs. -AC_GNU_SOURCE +AC_USE_SYSTEM_EXTENSIONS AC_C_CONST AC_C_INLINE AC_PROG_CC @@ -41,30 +53,27 @@ AC_PROG_RANLIB AM_PROG_AS AM_PROG_AR -if test "x$check" = "xtrue" -then +AS_IF([test "x$with_check" = "xyes"], + [ AC_CHECK_PROGS([GCOV], [gcov]) - if test -z "$GCOV"; - then - AC_MSG_WARN([gcov not found - continuing without coverage monitoring]) - else - AC_CHECK_PROGS([LCOV], [lcov]) - if test -z "$LCOV"; - then - AC_MSG_WARN([lcov not found - continuing without HTML coverage summary]) - fi - fi -fi + AC_CHECK_PROGS([LCOV], [lcov]) + ] +) AC_CHECK_PROGS([CPPCHECK], [cppcheck]) -AC_CHECK_PROGS([DOXYGEN], [doxygen]) -if test -z "$DOXYGEN"; -then - AC_MSG_WARN([Doxygen not found - continuing without Doxygen support]) -fi -AC_CHECK_PROGS([DOT], [dot]) -if test -z "$DOT"; then - AC_MSG_ERROR([Doxygen needs dot, please install dot first]) -fi + +AS_IF([test "x$with_doxygen" = "xyes"], + [ + AC_CHECK_PROGS([DOXYGEN], [doxygen]) + AS_IF([test -n "$DOXYGEN"], + [ + AC_CHECK_PROGS([DOT], [dot]) + AS_IF([test -z "$DOT"], + [AC_MSG_ERROR([Doxygen needs dot from graphviz (--without-doxygen to disable)])] + ) + ] + ) + ] +) AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([docs/Doxyfile])]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([docs/Makefile])]) @@ -74,7 +83,13 @@ AM_CONDITIONAL([HAVE_LCOV], [test -n "$LCOV"]) AM_CONDITIONAL([HAVE_CPPCHECK], [test -n "$CPPCHECK"]) # Checks for libraries. -AC_CHECK_LIB(readline, readline) +LIBREADLINE= +AS_IF([test "x$with_readline" != "xno"], + [AC_CHECK_LIB([readline], [readline], + [], + [AC_MSG_FAILURE( + [libreadline not found (--without-readline to disable)])] + )]) # Checks for header files. AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h]) @@ -91,3 +106,21 @@ AC_CHECK_FUNCS([bzero strtoull, gmtime_r, ptrace]) AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile tests/samples/Makefile]) AC_OUTPUT + +yesno_out(){ if test -n "$1";then echo "yes";else echo "no ";fi; } +echo " +Features +-------- +- libreadline support : $with_readline + +Tests +----- +- check unit tests : $with_check +- gcov coverage : $(yesno_out $GCOV) +- lcov html report : $(yesno_out $LCOV) + +Documentation +------------- +- doxygen : $(yesno_out $DOXYGEN) + +" diff --git a/src/asm_env.c b/src/asm_env.c index d447cae..0f9aa03 100644 --- a/src/asm_env.c +++ b/src/asm_env.c @@ -102,7 +102,7 @@ void asmsh_env_free(asmsh_env_t *asmenv) free(asmenv); } -int asmsh_env_write_mem(asmsh_env_t *env, void **addr, const unsigned char *buf, size_t buf_sz) +int asmsh_env_write_mem(asmsh_env_t *env, uintptr_t *addr, const unsigned char *buf, size_t buf_sz) { int err; u_int64_t data; @@ -175,7 +175,7 @@ int asmsh_env_write_mem(asmsh_env_t *env, void **addr, const unsigned char *buf, int asmsh_env_write_code(asmsh_env_t *env, asmsh_bytecode_t *bcode) { - return asmsh_env_write_mem(env, (void**)&env->code_write_ptr, + return asmsh_env_write_mem(env, (uintptr_t*)&env->code_write_ptr, bcode->bytes, bcode->size); } @@ -300,7 +300,7 @@ int asmsh_env_update_regs(asmsh_env_t *asmenv) return 0; } -int asmsh_env_read_mem(asmsh_env_t *env, void **addr, uint8_t *buf, size_t buf_sz) +int asmsh_env_read_mem(asmsh_env_t *env, uintptr_t *addr, uint8_t *buf, size_t buf_sz) { uint64_t data; size_t readed; diff --git a/src/asm_env.h b/src/asm_env.h index 4cbcf56..a1aa7ac 100644 --- a/src/asm_env.h +++ b/src/asm_env.h @@ -93,7 +93,7 @@ void asmsh_env_free(asmsh_env_t *asmenv); * @param size_t number of bytes to write * @return 0 if no errors else -1 with errno set */ -int asmsh_env_write_mem(asmsh_env_t *env, void **addr, const unsigned char *buf, size_t buf_sz); +int asmsh_env_write_mem(asmsh_env_t *env, uintptr_t *addr, const unsigned char *buf, size_t buf_sz); /** Write bytecode at the next location available in the text map * @param asmsh_env_t* The run environment @@ -134,7 +134,7 @@ int asmsh_env_update_maps(asmsh_env_t *asmenv); * @param size_t Read buffer size * @return 0 if no error else -1 */ -int asmsh_env_read_mem(asmsh_env_t *env, void **addr, uint8_t *buf, size_t buf_sz); +int asmsh_env_read_mem(asmsh_env_t *env, uintptr_t *addr, uint8_t *buf, size_t buf_sz); /** Set a register value * @param asmsh_env_t* diff --git a/src/asmsh.c b/src/asmsh.c index 5b65e00..5cfc989 100644 --- a/src/asmsh.c +++ b/src/asmsh.c @@ -113,8 +113,7 @@ int main(int argc, char *argv[], char *envp[]) #ifdef HAVE_LIBREADLINE rl_special_prefixes=""; rl_basic_word_break_characters=" \t\n"; - rl_attempted_completion_function = asmsh_rl_completion; - //rl_completion_entry_function = asmsh_rl_completion_entry_function; + rl_attempted_completion_function = asmsh_rl_attempted_completion; char * hpath = history_filename_init(NULL); load_history(hpath, add_history); diff --git a/src/completion.c b/src/completion.c index 8e65566..77536d4 100644 --- a/src/completion.c +++ b/src/completion.c @@ -110,7 +110,7 @@ char **asmsh_rl_attempted_completion(const char *text, int start, int end) } free(tmp_cmd); const char *_cmd = _cmd_from_idx(cmd_idx); - if(cmd_sz < strlen(_cmd)) + if(_cmd && cmd_sz < strlen(_cmd)) { /* reformating line buffer : lstrip + command completion */ const size_t needed = snprintf(NULL, 0, "%s%s", diff --git a/src/shell.c b/src/shell.c index bd5078e..cbd6e25 100644 --- a/src/shell.c +++ b/src/shell.c @@ -455,7 +455,7 @@ static int _compile_step(asmsh_t *sh, const char *cmd) case ASMSH_MODE_COMPILE: if(asmsh_env_write_mem( sh->env, - (void**)&sh->env->write_ptr, + (uintptr_t*)&sh->env->write_ptr, bcode.bytes, bcode.size)) { diff --git a/src/shell.h b/src/shell.h index dd53ad7..d1fde62 100644 --- a/src/shell.h +++ b/src/shell.h @@ -183,6 +183,7 @@ const char* asmsh_cmdline_iter(asmsh_cmdline_t *cmdline); * @return 0 on error else return the needed buffer size * @todo move in asm_env.* * @todo Enhance !!! Add support for relative or absolute address replacement + * @todo Bugfix unused preffix argument :/ */ size_t asmsh_parse_labels(asmsh_t *sh, char preffix, const char *cmd, char *buf, size_t buf_sz); diff --git a/src/shell_cmd_breakpoint.c b/src/shell_cmd_breakpoint.c index 5273d7d..5664990 100644 --- a/src/shell_cmd_breakpoint.c +++ b/src/shell_cmd_breakpoint.c @@ -205,10 +205,10 @@ static int brk_del(asmsh_t *sh, asmsh_cmd_args_t *args, int expr_first) int ret = asmsh_brk_del(&sh->env->brks, addr); if(ret < 0) { - int err = errno; + int _err = errno; asmsh_log_error("Unable to remove breakpoint @ %016lX : %s", addr, strerror(errno)); - errno = err; + errno = _err; return -1; } else if(ret > 0) diff --git a/src/shell_cmds.c b/src/shell_cmds.c index 6ece197..4914384 100644 --- a/src/shell_cmds.c +++ b/src/shell_cmds.c @@ -398,7 +398,7 @@ int asmsh_cmd_data(asmsh_t *sh, asmsh_cmd_args_t *args) args->args[0]); goto error; } - if(asmsh_env_write_mem(sh->env, (void**)&addr, (uint8_t*)data, data_sz)) + if(asmsh_env_write_mem(sh->env, &addr, (uint8_t*)data, data_sz)) { asmsh_log_error("Unable to write child memory"); goto error; @@ -621,7 +621,7 @@ int asmsh_cmd_memdump(asmsh_t *sh, asmsh_cmd_args_t *args) return -1; } - if(asmsh_env_read_mem(sh->env, (void**)&addr, buf, len)) + if(asmsh_env_read_mem(sh->env, &addr, buf, len)) { return -1; } diff --git a/src/shell_cmds_lib.c b/src/shell_cmds_lib.c index bb402cf..14b6f78 100644 --- a/src/shell_cmds_lib.c +++ b/src/shell_cmds_lib.c @@ -1,4 +1,5 @@ #include "shell_cmds_lib.h" +extern int errno; /** Utility for @ref asmsh_cmd_parse_addr() parsing an operand * @param const char* the string representation of operand diff --git a/tests/tests_asm_env.c b/tests/tests_asm_env.c index 8898d1c..01257b3 100644 --- a/tests/tests_asm_env.c +++ b/tests/tests_asm_env.c @@ -290,7 +290,7 @@ START_TEST(test_env_write_mem) set_ptrace_record(); wr_addr = (uintptr_t)env->code_write_ptr; ck_assert_int_eq( - asmsh_env_write_mem(env, (void**)&wr_addr, value, value_sz), + asmsh_env_write_mem(env, &wr_addr, value, value_sz), 0); ck_assert_int_eq(wr_addr, (uintptr_t)env->code_write_ptr + value_sz); ck_assert_int_eq(ptrace_calls.calls_sz, 2); @@ -303,7 +303,7 @@ START_TEST(test_env_write_mem) //unalligned write wr_addr = (uintptr_t)env->code_write_ptr + 1; ck_assert_int_eq( - asmsh_env_write_mem(env, (void**)&wr_addr, value, value_sz), + asmsh_env_write_mem(env, &wr_addr, value, value_sz), 0); ck_assert_int_eq(wr_addr, (uintptr_t)env->code_write_ptr + value_sz + 1); ck_assert_int_eq(ptrace_calls.calls_sz, 2 + 1 + 1); @@ -331,12 +331,12 @@ START_TEST(testloop_env_write_mem_ptrace_fails) set_ptrace_fails_in("asmsh_env_write_mem", _i); wr_addr = (uintptr_t)env->code_write_ptr; - ret = asmsh_env_write_mem(env, (void**)&wr_addr, value, value_sz); + ret = asmsh_env_write_mem(env, &wr_addr, value, value_sz); ck_assert_int_eq(ret, reset_ptrace_fails_in() < 0 ? -1 : 0); set_ptrace_fails_in("asmsh_env_write_mem", _i); wr_addr = (uintptr_t)env->code_write_ptr + 1; - ret = asmsh_env_write_mem(env, (void**)&wr_addr, value, value_sz); + ret = asmsh_env_write_mem(env, &wr_addr, value, value_sz); ck_assert_int_eq(ret, reset_ptrace_fails_in() < 0 ? -1 : 0); } END_TEST