/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ /* Copyright (C) 2014 Stony Brook University This file is part of Graphene Library OS. Graphene Library OS is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Graphene Library OS 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* * shim_utils.h */ #ifndef _SHIM_UTILS_H_ #define _SHIM_UTILS_H_ #include #include #include #include struct shim_handle; void sysparser_printf (const char * fmt, ...); /* string object */ struct shim_str * get_str_obj (void); int free_str_obj (struct shim_str * str); int init_str_mgr (void); /* qstring object */ #define QSTR_INIT { .len = 0, .oflow = NULL } static inline const char * qstrgetstr (const struct shim_qstr * qstr) { return qstr->oflow ? qstr->oflow->str : qstr->name; } static inline void qstrfree (struct shim_qstr * qstr) { if (qstr->oflow) { free_str_obj(qstr->oflow); qstr->oflow = NULL; } qstr->name[0] = 0; qstr->len = 0; } static inline char * qstrsetstr (struct shim_qstr * qstr, const char * str, size_t size) { if (!str) { qstrfree(qstr); return NULL; } if (size >= STR_SIZE) return NULL; char * buf = qstr->name; if (size >= QSTR_SIZE) { if (!qstr->oflow) { qstr->oflow = get_str_obj(); if (!qstr->oflow) return NULL; } buf = qstr->oflow->str; } else { if (qstr->oflow) { free_str_obj(qstr->oflow); qstr->oflow = NULL; } } memcpy(buf, str, size); buf[size] = 0; qstr->len = size; return buf; } static inline char * qstrsetstrs (struct shim_qstr * qstr, int nstrs, const char ** strs, size_t * sizes) { size_t total_size = 0; for (int i = 0 ; i < nstrs ; i++) total_size += sizes[i]; if (total_size >= STR_SIZE) return NULL; char * buf = qstr->name; if (total_size >= QSTR_SIZE) { if (!qstr->oflow) { // TODO: alloc proper size. qstr->oflow = get_str_obj(); if (!qstr->oflow) return NULL; } buf = qstr->oflow->str; } char * ptr = buf; qstr->len = 0; for (int i = 0 ; i < nstrs ; i++) { int size = sizes[i]; memcpy(ptr, strs[i], size); ptr[size] = 0; qstr->len += size; ptr += size; } return buf; } static inline int qstrempty (const struct shim_qstr * qstr) { return qstr->len == 0; } static inline void qstrcopy (struct shim_qstr * to, const struct shim_qstr * from) { qstrsetstr(to, qstrgetstr(from), from->len); to->hash = from->hash; } static inline int qstrcmpstr (const struct shim_qstr * qstr, const char * str, size_t size) { if (qstr->len != size) return 1; return memcmp(qstrgetstr(qstr), str, size); } //#define SLAB_DEBUG_PRINT //#define SLAB_DEBUG_TRACE /* heap allocation functions */ int init_slab (void); #if defined(SLAB_DEBUG_PRINT) || defined(SLAB_DEBUG_TRACE) void * __malloc_debug (size_t size, const char * file, int line); #define malloc(size) __malloc_debug((size), __FILE__, __LINE__) void __free_debug (void * mem, const char * file, int line); #define free(mem) __free_debug((mem), __FILE__, __LINE__) void * __malloc_copy_debug (const void * mem, size_t size, const char * file, int line); #define malloc_copy(mem, size) __malloc_copy_debug((mem), (size), __FILE__, __LINE__) #else void * malloc (size_t size); void free (void * mem); void * malloc_copy (const void * mem, size_t size); #endif static_always_inline char * qstrtostr (struct shim_qstr * qstr, bool on_stack) { int len = qstr->len; char * buf = on_stack ? __alloca(len + 1) : malloc(len + 1); if (!buf) return NULL; memcpy(buf, qstrgetstr(qstr), len); buf[len] = 0; return buf; } /* typedef a 32 bit type */ # ifndef UINT4 # define UINT4 uint32_t # endif /* Data structure for MD5 (Message Digest) computation */ struct shim_md5_ctx { UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ UINT4 buf[4]; /* scratch buffer */ unsigned char in[64]; /* input buffer */ unsigned char digest[16]; /* actual digest after MD5Final call */ }; void md5_init (struct shim_md5_ctx * mdContext); void md5_update (struct shim_md5_ctx * mdContext, const void * buf, size_t len); void md5_final (struct shim_md5_ctx * mdContext); /* prompt user for confirmation */ int message_confirm (const char * message, const char * options); /* ELF binary loading */ int check_elf_object (struct shim_handle * file); int load_elf_object (struct shim_handle * file, void * addr, size_t mapped); int load_elf_interp (struct shim_handle * exec); int free_elf_interp (void); void execute_elf_object (struct shim_handle * exec, int * argcp, const char ** argp, int nauxv, elf_auxv_t * auxp); int remove_loaded_libraries (void); /* gdb debugging support */ void remove_r_debug (void * addr); void append_r_debug (const char * uri, void * addr, void * dyn_addr); void clean_link_map_list (void); /* create unique files/pipes */ #define PIPE_URI_SIZE 40 int create_pipe (IDTYPE * pipeid, char * uri, size_t size, PAL_HANDLE * hdl, struct shim_qstr * qstr); int create_dir (const char * prefix, char * path, size_t size, struct shim_handle ** hdl); int create_file (const char * prefix, char * path, size_t size, struct shim_handle ** hdl); int create_handle (const char * prefix, char * path, size_t size, PAL_HANDLE * hdl, unsigned int * id); /* Asynchronous event support */ int init_async (void); int64_t install_async_event (PAL_HANDLE object, unsigned long time, void (*callback) (IDTYPE caller, void * arg), void * arg); int create_async_helper (void); struct shim_thread * terminate_async_helper (void); extern struct config_store * root_config; #endif /* _SHIM_UTILS_H */