|
| 1 | +/*******************************************************************\ |
| 2 | +
|
| 3 | +Module: Goto Programs |
| 4 | +
|
| 5 | +Author: Thomas Kiley |
| 6 | +
|
| 7 | +\*******************************************************************/ |
| 8 | + |
| 9 | +#include "system_library_symbols.h" |
| 10 | +#include <util/cprover_prefix.h> |
| 11 | +#include <util/prefix.h> |
| 12 | +#include <util/symbol.h> |
| 13 | + |
| 14 | +system_library_symbolst::system_library_symbolst() |
| 15 | +{ |
| 16 | + init_system_library_map(); |
| 17 | +} |
| 18 | + |
| 19 | +/*******************************************************************\ |
| 20 | +
|
| 21 | +Function: system_library_symbolst::init_system_library_map |
| 22 | +
|
| 23 | +Inputs: |
| 24 | +
|
| 25 | +Outputs: |
| 26 | +
|
| 27 | +Purpose: To generate a map of header file names -> list of symbols |
| 28 | + The symbol names are reserved as the header and source files |
| 29 | + will be compiled in to the goto program. |
| 30 | +
|
| 31 | +\*******************************************************************/ |
| 32 | + |
| 33 | +void system_library_symbolst::init_system_library_map() |
| 34 | +{ |
| 35 | + // ctype.h |
| 36 | + std::list<irep_idt> ctype_syms= |
| 37 | + { |
| 38 | + "isalnum", "isalpha", "isblank", "iscntrl", "isdigit", "isgraph", |
| 39 | + "islower", "isprint", "ispunct", "isspace", "isupper", "isxdigit", |
| 40 | + "tolower", "toupper" |
| 41 | + }; |
| 42 | + add_to_system_library("ctype.h", ctype_syms); |
| 43 | + |
| 44 | + // fcntl.h |
| 45 | + std::list<irep_idt> fcntl_syms= |
| 46 | + { |
| 47 | + "creat", "fcntl", "open" |
| 48 | + }; |
| 49 | + add_to_system_library("fcntl.h", fcntl_syms); |
| 50 | + |
| 51 | + // locale.h |
| 52 | + std::list<irep_idt> locale_syms= |
| 53 | + { |
| 54 | + "setlocale" |
| 55 | + }; |
| 56 | + add_to_system_library("locale.h", locale_syms); |
| 57 | + |
| 58 | + // math.h |
| 59 | + std::list<irep_idt> math_syms= |
| 60 | + { |
| 61 | + "acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", |
| 62 | + "cbrt", "ceil", "copysign", "cos", "cosh", "erf", "erfc", "exp", |
| 63 | + "exp2", "expm1", "fabs", "fdim", "floor", "fma", "fmax", "fmin", |
| 64 | + "fmod", "fpclassify", "frexp", "hypot", "ilogb", "isfinite", |
| 65 | + "isinf", "isnan", "isnormal", "j0", "j1", "jn", "ldexp", "lgamma", |
| 66 | + "llrint", "llround", "log", "log10", "log1p", "log2", "logb", |
| 67 | + "lrint", "lround", "modf", "nan", "nearbyint", "nextafter", "pow", |
| 68 | + "remainder", "remquo", "rint", "round", "scalbln", "scalbn", |
| 69 | + "signbit", "sin", "sinh", "sqrt", "tan", "tanh", "tgamma", |
| 70 | + "trunc", "y0", "y1", "yn" |
| 71 | + }; |
| 72 | + add_to_system_library("math.h", math_syms); |
| 73 | + |
| 74 | + // pthread.h |
| 75 | + std::list<irep_idt> pthread_syms= |
| 76 | + { |
| 77 | + "pthread_cleanup_pop", "pthread_cleanup_push", |
| 78 | + "pthread_cond_broadcast", "pthread_cond_destroy", |
| 79 | + "pthread_cond_init", "pthread_cond_signal", |
| 80 | + "pthread_cond_timedwait", "pthread_cond_wait", "pthread_create", |
| 81 | + "pthread_detach", "pthread_equal", "pthread_exit", |
| 82 | + "pthread_getspecific", "pthread_join", "pthread_key_delete", |
| 83 | + "pthread_mutex_destroy", "pthread_mutex_init", |
| 84 | + "pthread_mutex_lock", "pthread_mutex_trylock", |
| 85 | + "pthread_mutex_unlock", "pthread_once", "pthread_rwlock_destroy", |
| 86 | + "pthread_rwlock_init", "pthread_rwlock_rdlock", |
| 87 | + "pthread_rwlock_unlock", "pthread_rwlock_wrlock", |
| 88 | + "pthread_rwlockattr_destroy", "pthread_rwlockattr_getpshared", |
| 89 | + "pthread_rwlockattr_init", "pthread_rwlockattr_setpshared", |
| 90 | + "pthread_self", "pthread_setspecific" |
| 91 | + }; |
| 92 | + add_to_system_library("pthread.h", pthread_syms); |
| 93 | + |
| 94 | + // setjmp.h |
| 95 | + std::list<irep_idt> setjmp_syms= |
| 96 | + { |
| 97 | + "_longjmp", "_setjmp", "longjmp", "longjmperror", "setjmp", |
| 98 | + "siglongjmp", "sigsetjmp" |
| 99 | + }; |
| 100 | + add_to_system_library("setjmp.h", setjmp_syms); |
| 101 | + |
| 102 | + // stdio.h |
| 103 | + std::list<irep_idt> stdio_syms= |
| 104 | + { |
| 105 | + "asprintf", "clearerr", "fclose", "fdopen", "feof", "ferror", |
| 106 | + "fflush", "fgetc", "fgetln", "fgetpos", "fgets", "fgetwc", |
| 107 | + "fgetws", "fileno", "fopen", "fprintf", "fpurge", "fputc", |
| 108 | + "fputs", "fputwc", "fputws", "fread", "freopen", "fropen", |
| 109 | + "fscanf", "fseek", "fsetpos", "ftell", "funopen", "fwide", |
| 110 | + "fwopen", "fwprintf", "fwrite", "getc", "getchar", "getdelim", |
| 111 | + "getline", "gets", "getw", "getwc", "getwchar", "mkdtemp", |
| 112 | + "mkstemp", "mktemp", "perror", "printf", "putc", "putchar", |
| 113 | + "puts", "putw", "putwc", "putwchar", "remove", "rewind", "scanf", |
| 114 | + "setbuf", "setbuffer", "setlinebuf", "setvbuf", "snprintf", |
| 115 | + "sprintf", "sscanf", "strerror", "swprintf", "sys_errlist", |
| 116 | + "sys_nerr", "tempnam", "tmpfile", "tmpnam", "ungetc", "ungetwc", |
| 117 | + "vasprintf", "vfprintf", "vfscanf", "vfwprintf", "vprintf", |
| 118 | + "vscanf", "vsnprintf", "vsprintf", "vsscanf", "vswprintf", |
| 119 | + "vwprintf", "wprintf", |
| 120 | + /* non-public struct types */ |
| 121 | + "tag-__sFILE", "tag-__sbuf", // OS X |
| 122 | + "tag-_IO_FILE", "tag-_IO_marker", // Linux |
| 123 | + }; |
| 124 | + add_to_system_library("stdio.h", stdio_syms); |
| 125 | + |
| 126 | + // stdlib.h |
| 127 | + std::list<irep_idt> stdlib_syms= |
| 128 | + { |
| 129 | + "abort", "abs", "atexit", "atof", "atoi", "atol", "atoll", |
| 130 | + "bsearch", "calloc", "div", "exit", "free", "getenv", "labs", |
| 131 | + "ldiv", "llabs", "lldiv", "malloc", "mblen", "mbstowcs", "mbtowc", |
| 132 | + "qsort", "rand", "realloc", "srand", "strtod", "strtof", "strtol", |
| 133 | + "strtold", "strtoll", "strtoul", "strtoull", "system", "wcstombs", |
| 134 | + "wctomb" |
| 135 | + }; |
| 136 | + add_to_system_library("stdlib.h", stdlib_syms); |
| 137 | + |
| 138 | + // string.h |
| 139 | + std::list<irep_idt> string_syms= |
| 140 | + { |
| 141 | + "strcat", "strncat", "strchr", "strrchr", "strcmp", "strncmp", |
| 142 | + "strcpy", "strncpy", "strerror", "strlen", "strpbrk", "strspn", |
| 143 | + "strcspn", "strstr", "strtok" |
| 144 | + }; |
| 145 | + add_to_system_library("string.h", string_syms); |
| 146 | + |
| 147 | + // time.h |
| 148 | + std::list<irep_idt> time_syms= |
| 149 | + { |
| 150 | + "asctime", "asctime_r", "ctime", "ctime_r", "difftime", "gmtime", |
| 151 | + "gmtime_r", "localtime", "localtime_r", "mktime", |
| 152 | + /* non-public struct types */ |
| 153 | + "tag-timespec", "tag-timeval" |
| 154 | + }; |
| 155 | + add_to_system_library("time.h", time_syms); |
| 156 | + |
| 157 | + // unistd.h |
| 158 | + std::list<irep_idt> unistd_syms= |
| 159 | + { |
| 160 | + "_exit", "access", "alarm", "chdir", "chown", "close", "dup", |
| 161 | + "dup2", "execl", "execle", "execlp", "execv", "execve", "execvp", |
| 162 | + "fork", "fpathconf", "getcwd", "getegid", "geteuid", "getgid", |
| 163 | + "getgroups", "getlogin", "getpgrp", "getpid", "getppid", "getuid", |
| 164 | + "isatty", "link", "lseek", "pathconf", "pause", "pipe", "read", |
| 165 | + "rmdir", "setgid", "setpgid", "setsid", "setuid", "sleep", |
| 166 | + "sysconf", "tcgetpgrp", "tcsetpgrp", "ttyname", "ttyname_r", |
| 167 | + "unlink", "write" |
| 168 | + }; |
| 169 | + add_to_system_library("unistd.h", unistd_syms); |
| 170 | + |
| 171 | + // sys/select.h |
| 172 | + std::list<irep_idt> sys_select_syms= |
| 173 | + { |
| 174 | + "select" |
| 175 | + }; |
| 176 | + add_to_system_library("sys/select.h", sys_select_syms); |
| 177 | + |
| 178 | + // sys/socket.h |
| 179 | + std::list<irep_idt> sys_socket_syms= |
| 180 | + { |
| 181 | + "accept", "bind", "connect" |
| 182 | + }; |
| 183 | + add_to_system_library("sys/socket.h", sys_socket_syms); |
| 184 | + |
| 185 | + // sys/stat.h |
| 186 | + std::list<irep_idt> sys_stat_syms= |
| 187 | + { |
| 188 | + "fstat", "lstat", "stat" |
| 189 | + }; |
| 190 | + add_to_system_library("sys/stat.h", sys_stat_syms); |
| 191 | + |
| 192 | +#if 0 |
| 193 | + // sys/types.h |
| 194 | + std::list<irep_idt> sys_types_syms= |
| 195 | + { |
| 196 | + }; |
| 197 | + add_to_system_library("sys/types.h", sys_types_syms); |
| 198 | +#endif |
| 199 | + |
| 200 | + // sys/wait.h |
| 201 | + std::list<irep_idt> sys_wait_syms= |
| 202 | + { |
| 203 | + "wait", "waitpid" |
| 204 | + }; |
| 205 | + add_to_system_library("sys/wait.h", sys_wait_syms); |
| 206 | +} |
| 207 | + |
| 208 | +/*******************************************************************\ |
| 209 | +
|
| 210 | +Function: system_library_symbolst::add_to_system_library |
| 211 | +
|
| 212 | +Inputs: |
| 213 | + header_file - the name of the header file the symbol came from |
| 214 | + symbols - a list of the names of the symbols in the header file |
| 215 | +
|
| 216 | +Outputs: |
| 217 | +
|
| 218 | +Purpose: To add the symbols from a specific header file to the |
| 219 | + system library map. The symbol is used as the key so that |
| 220 | + we can easily look up symbols. |
| 221 | +
|
| 222 | +\*******************************************************************/ |
| 223 | + |
| 224 | +void system_library_symbolst::add_to_system_library( |
| 225 | + irep_idt header_file, |
| 226 | + std::list<irep_idt> symbols) |
| 227 | +{ |
| 228 | + for(const irep_idt &symbol : symbols) |
| 229 | + { |
| 230 | + system_library_map[symbol]=header_file; |
| 231 | + } |
| 232 | +} |
| 233 | + |
| 234 | + |
| 235 | +/*******************************************************************\ |
| 236 | +
|
| 237 | +Function: system_library_symbolst::is_symbol_internal_symbol |
| 238 | +
|
| 239 | +Inputs: |
| 240 | + symbol - the symbol to check |
| 241 | +
|
| 242 | +Outputs: True if the symbol is an internal symbol. If specific system |
| 243 | + headers need to be included, the out_system_headers will contain |
| 244 | + the headers. |
| 245 | +
|
| 246 | +Purpose: To find out if a symbol is an internal symbol. |
| 247 | +
|
| 248 | +\*******************************************************************/ |
| 249 | + |
| 250 | +bool system_library_symbolst::is_symbol_internal_symbol( |
| 251 | + const symbolt &symbol, |
| 252 | + std::set<irep_idt> &out_system_headers) const |
| 253 | +{ |
| 254 | + const std::string &name_str=id2string(symbol.name); |
| 255 | + |
| 256 | + if(has_prefix(name_str, CPROVER_PREFIX) || |
| 257 | + name_str=="__func__" || |
| 258 | + name_str=="__FUNCTION__" || |
| 259 | + name_str=="__PRETTY_FUNCTION__" || |
| 260 | + name_str=="argc'" || |
| 261 | + name_str=="argv'" || |
| 262 | + name_str=="envp'" || |
| 263 | + name_str=="envp_size'") |
| 264 | + return true; |
| 265 | + |
| 266 | + const std::string &file_str=id2string(symbol.location.get_file()); |
| 267 | + |
| 268 | + // don't dump internal GCC builtins |
| 269 | + if((file_str=="gcc_builtin_headers_alpha.h" || |
| 270 | + file_str=="gcc_builtin_headers_arm.h" || |
| 271 | + file_str=="gcc_builtin_headers_ia32.h" || |
| 272 | + file_str=="gcc_builtin_headers_mips.h" || |
| 273 | + file_str=="gcc_builtin_headers_power.h" || |
| 274 | + file_str=="gcc_builtin_headers_generic.h") && |
| 275 | + has_prefix(name_str, "__builtin_")) |
| 276 | + return true; |
| 277 | + |
| 278 | + if(name_str=="__builtin_va_start" || |
| 279 | + name_str=="__builtin_va_end" || |
| 280 | + symbol.name==ID_gcc_builtin_va_arg) |
| 281 | + { |
| 282 | + out_system_headers.insert("stdarg.h"); |
| 283 | + return true; |
| 284 | + } |
| 285 | + |
| 286 | + if(name_str.find("$link")!=std::string::npos) |
| 287 | + return false; |
| 288 | + |
| 289 | + const auto &it=system_library_map.find(symbol.name); |
| 290 | + |
| 291 | + if(it!=system_library_map.end()) |
| 292 | + { |
| 293 | + out_system_headers.insert(it->second); |
| 294 | + return true; |
| 295 | + } |
| 296 | + |
| 297 | + return false; |
| 298 | +} |
0 commit comments