/* Copyright Yann Weber This file is part of asmsh. asmsh is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. asmsh is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with asmsh. If not, see . */ #ifndef ASMSH_COMPILE_H #define ASMSH_COMPILE_H #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "logger.h" /** Define the default assembler (GNU as) */ #define ASMSH_COMPILE_AS "as" #define ASMSH_COMPILE_ARGS {"", "-O2", "-f", "-ad", "-o", NULL, "-c", "-", NULL} #define ASMSH_COMPILE_OBJ "/tmp/asmsh_jit_XXXXXX" typedef struct asmsh_asmc_ctx_s asmsh_asmc_ctx_t; typedef struct asmsh_asmc_child_s asmsh_asmc_child_t; typedef struct asmsh_bytecode_s asmsh_bytecode_t; struct asmsh_asmc_child_s { /** Compiler subprocess PID (waiting code on piped STDIN) */ pid_t pid; /** Write endpoint of subprocess's piped STDIN */ int pipe_stdin; /** Read endpoint of subprocess's piped STDOUT & STDERR */ int pipe_stdout[2]; }; struct asmsh_asmc_ctx_s { /** NULL terminated list of args for child subprocess, * arg[0] is progname */ char **args; /** Points on args[0] */ char *progname; /** Points on the result path argument (value of -o) */ char *respath; /** Compilation timeout */ struct timeval ctimeout; /** A child, that can be spawn in advance */ asmsh_asmc_child_t child; /** If true pre spawn childs */ char pre_spawn; }; /** Compilation result, 1 instruction bytecode */ struct asmsh_bytecode_s { /** Instruction bytes */ unsigned char bytes[15]; /** Instruction size */ char size; }; /** * Check if : * - contains no ';' nor '#' nor '\n' * - only contains char in range [0x20 .. 0x7E] * - do not begins by '.' * * @param char* The instruction to pre-check * @param char** If not null contains a reason on failure (and must be freed) * @return 0 if instr has a valid syntax else -1 */ int asmsh_asmc_syntax(const char* instr, char **reason); /** Return a default compilation context */ asmsh_asmc_ctx_t* asmsh_asmc_ctx_default(); /** Return a new compilation context * @param char* The assembler name/path * @param char* The result path for the compiled obj as mkstemp(3) template * @param char*[] The assembler list of arguments, without the argv[0] progname and with NULL as a placeholder for the result path * @param int If 0 no child are pre-spawned, else a child is spawned in returned context * @param struct timeval* Compilation timeout */ asmsh_asmc_ctx_t* asmsh_asmc_ctx(const char *progname, \ const char *result_path, char* const args[], int pre_spawn, struct timeval *ctimeout); /** Free all compile context resources */ void asmsh_asmc_ctx_free(asmsh_asmc_ctx_t *ctx); /** Compile an instruction * @param asmsh_asmc_ctx_t* The context * @param const char* The instruction to compile * @param asmsh_bytecode_t* Pointer on the result struct * @return 0 if ok else -1 on failure with errno set */ int asmsh_asmc_compile(asmsh_asmc_ctx_t *ctx, const char *instr, asmsh_bytecode_t *res); /** Compile an instruction * @param asmsh_asmc_ctx_t* The context * @param const char* The instruction to compile * @param asmsh_bytecode_t* Pointer on the result struct * @return 0 if ok else -1 on failure with errno set */ int asmsh_asmc_compile_unsafe(asmsh_asmc_ctx_t *ctx, const char *_instr, asmsh_bytecode_t *res); /** Spawn an assembler process child process * @return 0 if no error else -1 */ int asmsh_asmc_spawn(asmsh_asmc_ctx_t *ctx); /**Child process main function * @param int[2][2] The pipes for stdin and stderr in this order * @param *char The path/name of the assembler executable * @param *char[] The NULL terminated list of arguments for the assembler * @return NEVER */ void asmsh_asmc_child(const int std_pipes[3][2], const char *progname, char* const args[]); /** Given an object file, extract the "bytecode" * * Copy the .text segment of an ELF file * @param const char* the object file path * @param asmsh_bytecode_t* The result bytecode * * @return 0 if no error else -1 */ int asmh_asmc_bytecode_from_obj(const char *objfile, asmsh_bytecode_t *bytecode); /** Forge compiler arguments. * * The constructed arguments list will be allocated in args_o. * Put progname as first argument, result_tpl will replace the first NULL encountered * in the args_in array. args_in is an array of argument, that will be copied in * args_o. * @param const char* The compiler name/path * @param const char* An mkstemp() file template * @param char *const[] The NULL terminated list of arguments, the first will * be replaced by the progname value. And the first encountered NULL will * be affected to the temporary result file (from result_tpl) * @param char** The resulting args * @return 0 if no error else -1 */ int asmsh_asmc_buildarg(const char* progname, const char *result_tpl, \ char *const args_in[], char ***args_o, char **progname_o, char **respath_o); #endif