shim_utils.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* Copyright (C) 2014 Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /*
  14. * shim_utils.h
  15. */
  16. #ifndef _SHIM_UTILS_H_
  17. #define _SHIM_UTILS_H_
  18. #include <api.h>
  19. #include <list.h>
  20. #include <pal.h>
  21. #include <shim_handle.h>
  22. #include <shim_internal.h>
  23. struct shim_handle;
  24. void sysparser_printf(const char* fmt, ...);
  25. /* string object */
  26. struct shim_str* get_str_obj(void);
  27. int free_str_obj(struct shim_str* str);
  28. int init_str_mgr(void);
  29. /* qstring object */
  30. #define QSTR_INIT \
  31. { .len = 0, .oflow = NULL }
  32. static inline const char* qstrgetstr(const struct shim_qstr* qstr) {
  33. return qstr->oflow ? qstr->oflow->str : qstr->name;
  34. }
  35. static inline void qstrfree(struct shim_qstr* qstr) {
  36. if (qstr->oflow) {
  37. free_str_obj(qstr->oflow);
  38. qstr->oflow = NULL;
  39. }
  40. qstr->name[0] = 0;
  41. qstr->len = 0;
  42. }
  43. static inline char* qstrsetstr(struct shim_qstr* qstr, const char* str, size_t size) {
  44. if (!str) {
  45. qstrfree(qstr);
  46. return NULL;
  47. }
  48. if (size >= STR_SIZE)
  49. return NULL;
  50. char* buf = qstr->name;
  51. if (size >= QSTR_SIZE) {
  52. if (!qstr->oflow) {
  53. qstr->oflow = get_str_obj();
  54. if (!qstr->oflow)
  55. return NULL;
  56. }
  57. buf = qstr->oflow->str;
  58. } else {
  59. if (qstr->oflow) {
  60. free_str_obj(qstr->oflow);
  61. qstr->oflow = NULL;
  62. }
  63. }
  64. memcpy(buf, str, size);
  65. buf[size] = 0;
  66. qstr->len = size;
  67. return buf;
  68. }
  69. static inline char* qstrsetstrs(struct shim_qstr* qstr, int nstrs, const char** strs,
  70. size_t* sizes) {
  71. size_t total_size = 0;
  72. for (int i = 0; i < nstrs; i++) {
  73. total_size += sizes[i];
  74. }
  75. if (total_size >= STR_SIZE)
  76. return NULL;
  77. char* buf = qstr->name;
  78. if (total_size >= QSTR_SIZE) {
  79. if (!qstr->oflow) {
  80. // TODO: alloc proper size.
  81. qstr->oflow = get_str_obj();
  82. if (!qstr->oflow)
  83. return NULL;
  84. }
  85. buf = qstr->oflow->str;
  86. }
  87. char* ptr = buf;
  88. qstr->len = 0;
  89. for (int i = 0; i < nstrs; i++) {
  90. int size = sizes[i];
  91. memcpy(ptr, strs[i], size);
  92. ptr[size] = 0;
  93. qstr->len += size;
  94. ptr += size;
  95. }
  96. return buf;
  97. }
  98. static inline int qstrempty(const struct shim_qstr* qstr) {
  99. return qstr->len == 0;
  100. }
  101. static inline void qstrcopy(struct shim_qstr* to, const struct shim_qstr* from) {
  102. qstrsetstr(to, qstrgetstr(from), from->len);
  103. to->hash = from->hash;
  104. }
  105. static inline int qstrcmpstr(const struct shim_qstr* qstr, const char* str, size_t size) {
  106. if (qstr->len != size)
  107. return 1;
  108. return memcmp(qstrgetstr(qstr), str, size);
  109. }
  110. //#define SLAB_DEBUG_PRINT
  111. //#define SLAB_DEBUG_TRACE
  112. /* heap allocation functions */
  113. int init_slab(void);
  114. #if defined(SLAB_DEBUG_PRINT) || defined(SLAB_DEBUG_TRACE)
  115. void* __malloc_debug(size_t size, const char* file, int line);
  116. #define malloc(size) __malloc_debug(size, __FILE__, __LINE__)
  117. void __free_debug(void* mem, const char* file, int line);
  118. #define free(mem) __free_debug(mem, __FILE__, __LINE__)
  119. void* __malloc_copy_debug(const void* mem, size_t size, const char* file, int line);
  120. #define malloc_copy(mem, size) __malloc_copy_debug(mem, size, __FILE__, __LINE__)
  121. #else
  122. void* malloc(size_t size);
  123. void free(void* mem);
  124. void* malloc_copy(const void* mem, size_t size);
  125. #endif
  126. static_always_inline char* qstrtostr(struct shim_qstr* qstr, bool on_stack) {
  127. int len = qstr->len;
  128. char* buf = on_stack ? __alloca(len + 1) : malloc(len + 1);
  129. if (!buf)
  130. return NULL;
  131. memcpy(buf, qstrgetstr(qstr), len);
  132. buf[len] = 0;
  133. return buf;
  134. }
  135. /* typedef a 32 bit type */
  136. #ifndef UINT4
  137. #define UINT4 uint32_t
  138. #endif
  139. /* Data structure for MD5 (Message Digest) computation */
  140. struct shim_md5_ctx {
  141. UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
  142. UINT4 buf[4]; /* scratch buffer */
  143. unsigned char in[64]; /* input buffer */
  144. unsigned char digest[16]; /* actual digest after MD5Final call */
  145. };
  146. void md5_init(struct shim_md5_ctx* mdContext);
  147. void md5_update(struct shim_md5_ctx* mdContext, const void* buf, size_t len);
  148. void md5_final(struct shim_md5_ctx* mdContext);
  149. /* prompt user for confirmation */
  150. int message_confirm(const char* message, const char* options);
  151. /* ELF binary loading */
  152. int check_elf_object(struct shim_handle* file);
  153. int load_elf_object(struct shim_handle* file, void* addr, size_t mapped);
  154. int load_elf_interp(struct shim_handle* exec);
  155. int free_elf_interp(void);
  156. noreturn void execute_elf_object(struct shim_handle* exec, int* argcp, const char** argp,
  157. elf_auxv_t* auxp);
  158. int remove_loaded_libraries(void);
  159. /* gdb debugging support */
  160. void remove_r_debug(void* addr);
  161. void append_r_debug(const char* uri, void* addr, void* dyn_addr);
  162. void clean_link_map_list(void);
  163. /* create unique files/pipes */
  164. #define PIPE_URI_SIZE 40
  165. int create_pipe(IDTYPE* pipeid, char* uri, size_t size, PAL_HANDLE* hdl, struct shim_qstr* qstr,
  166. bool use_vmid_for_name);
  167. int create_dir(const char* prefix, char* path, size_t size, struct shim_handle** hdl);
  168. int create_file(const char* prefix, char* path, size_t size, struct shim_handle** hdl);
  169. int create_handle(const char* prefix, char* path, size_t size, PAL_HANDLE* hdl, unsigned int* id);
  170. /* Asynchronous event support */
  171. int init_async(void);
  172. int64_t install_async_event(PAL_HANDLE object, unsigned long time,
  173. void (*callback)(IDTYPE caller, void* arg), void* arg);
  174. struct shim_thread* terminate_async_helper(void);
  175. extern struct config_store* root_config;
  176. #endif /* _SHIM_UTILS_H */