static void event_post_syscall(void *drcontext, int sysnum) { drsys_syscall_t *syscall; bool success = false; uint errno; drmf_status_t res; buf_info_t buf; buf.sofar = 0; if (drsys_cur_syscall(drcontext, &syscall) != DRMF_SUCCESS) ASSERT(false, "drsys_cur_syscall failed"); if (drsys_cur_syscall_result(drcontext, &success, NULL, &errno) != DRMF_SUCCESS) ASSERT(false, "drsys_cur_syscall_result failed"); if (success) OUTPUT(&buf, " succeeded =>\n"); else OUTPUT(&buf, " failed (error="IF_WINDOWS_ELSE(PIFX, "%d")") =>\n", errno); res = drsys_iterate_args(drcontext, drsys_iter_arg_cb, &buf); if (res != DRMF_SUCCESS && res != DRMF_ERROR_DETAILS_UNKNOWN) ASSERT(false, "drsys_iterate_args failed post-syscall"); FLUSH_BUFFER(outf, buf.buf, buf.sofar); }
static bool event_pre_syscall(void *drcontext, int sysnum) { drsys_syscall_t *syscall; bool known; drsys_param_type_t ret_type; const char *name; drmf_status_t res; buf_info_t buf; buf.sofar = 0; if (drsys_cur_syscall(drcontext, &syscall) != DRMF_SUCCESS) ASSERT(false, "drsys_cur_syscall failed"); if (drsys_syscall_name(syscall, &name) != DRMF_SUCCESS) ASSERT(false, "drsys_syscall_name failed"); if (drsys_syscall_is_known(syscall, &known) != DRMF_SUCCESS) ASSERT(false, "failed to find whether known"); OUTPUT(&buf, "%s%s\n", name, known ? "" : " (details not all known)"); res = drsys_iterate_args(drcontext, drsys_iter_arg_cb, &buf); if (res != DRMF_SUCCESS && res != DRMF_ERROR_DETAILS_UNKNOWN) ASSERT(false, "drsys_iterate_args failed pre-syscall"); /* Flush prior to potentially waiting in the kernel */ FLUSH_BUFFER(outf, buf.buf, buf.sofar); return true; }
/* caller must hold symcache_lock */ static void symcache_write_symfile(const char *modname, mod_cache_t *modcache) { uint i; file_t f; hashtable_t *symtable = &modcache->table; char buf[SYMCACHE_BUFFER_SIZE]; size_t sofar = 0; ssize_t len; size_t bsz = BUFFER_SIZE_ELEMENTS(buf); size_t filesz_loc; char symfile[MAXIMUM_PATH]; char symfile_tmp[MAXIMUM_PATH]; int64 file_size; ASSERT(dr_mutex_self_owns(symcache_lock), "missing symcache lock"); /* if from file, we assume it's a waste of time to re-write file: * the version matched after all, unless we appended to it. */ if (modcache->from_file && !modcache->appended) return; if (symtable->entries == 0) return; /* nothing to write */ /* Open the temp symcache that we will rename. */ symcache_get_filename(modname, symfile, BUFFER_SIZE_ELEMENTS(symfile)); f = INVALID_FILE; i = 0; while (f == INVALID_FILE && i < SYMCACHE_MAX_TMP_TRIES) { dr_snprintf(symfile_tmp, BUFFER_SIZE_ELEMENTS(symfile_tmp), "%s.%04d.tmp", symfile, i); NULL_TERMINATE_BUFFER(symfile_tmp); f = dr_open_file(symfile_tmp, DR_FILE_WRITE_REQUIRE_NEW); i++; } if (f == INVALID_FILE) { NOTIFY("WARNING: Unable to create symcache temp file %s"NL, symfile_tmp); return; } BUFFERED_WRITE(f, buf, bsz, sofar, len, "%s %d\n", SYMCACHE_FILE_HEADER, SYMCACHE_VERSION); /* Leave room for file size for self-consistency check */ filesz_loc = sofar; /* XXX: Assumes that the buffer hasn't been flushed. */ BUFFERED_WRITE(f, buf, bsz, sofar, len, "%"STRINGIFY(SYMCACHE_SIZE_DIGITS)"u,", 0); #ifdef WINDOWS BUFFERED_WRITE(f, buf, bsz, sofar, len, UINT64_FORMAT_STRING","UINT64_FORMAT_STRING"," UINT64_FORMAT_STRING",%u,%u,%lu\n", modcache->module_file_size, modcache->file_version.version, modcache->product_version.version, modcache->checksum, modcache->timestamp, modcache->module_internal_size); #else BUFFERED_WRITE(f, buf, bsz, sofar, len, UINT64_FORMAT_STRING",%u", modcache->module_file_size, modcache->timestamp); # ifdef MACOS BUFFERED_WRITE(f, buf, bsz, sofar, len, ",%u,%u,", modcache->current_version, modcache->compatibility_version); /* For easy sscanf we print as 4 ints */ for (i = 0; i < 4; i++) BUFFERED_WRITE(f, buf, bsz, sofar, len, "%08x,", *(int*)(&modcache->uuid[i*4])); # endif BUFFERED_WRITE(f, buf, bsz, sofar, len, "\n"); #endif BUFFERED_WRITE(f, buf, bsz, sofar, len, "%u\n", modcache->has_debug_info); for (i = 0; i < HASHTABLE_SIZE(symtable->table_bits); i++) { hash_entry_t *he; for (he = symtable->table[i]; he != NULL; he = he->next) { offset_list_t *olist = (offset_list_t *) he->payload; offset_entry_t *e; if (olist == NULL) continue; /* skip symbol in dup entries to save space */ BUFFERED_WRITE(f, buf, bsz, sofar, len, "%s", he->key); e = olist->list; while (e != NULL) { BUFFERED_WRITE(f, buf, bsz, sofar, len, ",0x%x\n", e->offs); e = e->next; } } } /* now update size */ FLUSH_BUFFER(f, buf, sofar); if ((file_size = dr_file_tell(f)) < 0 || dr_snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%"STRINGIFY(SYMCACHE_SIZE_DIGITS)"u", (uint)file_size) < 0 || !dr_file_seek(f, filesz_loc, DR_SEEK_SET) || dr_write_file(f, buf, SYMCACHE_SIZE_DIGITS) != SYMCACHE_SIZE_DIGITS) { /* If any steps fail, warn and give up. */ NOTIFY("WARNING: Unable to write symcache file size."NL); dr_close_file(f); dr_delete_file(symfile_tmp); return; } else { LOG(3, "Wrote symcache %s file size %u to pos "SZFMT"\n", modname, (uint)file_size, filesz_loc); ASSERT(strlen(buf) <= SYMCACHE_SIZE_DIGITS, "not enough space for file size"); } dr_close_file(f); if (!dr_rename_file(symfile_tmp, symfile, /*replace*/true)) { NOTIFY_ERROR("WARNING: Failed to rename the symcache file."NL); dr_delete_file(symfile_tmp); } }
static int serial_driver_output_colors(output_driver_t *this_gen, rgb_color_t *colors, rgb_color_t *last_colors) { serial_output_driver_t *this = (serial_output_driver_t *) this_gen; uint8_t msg[512]; uint8_t *m = msg; int data = 0, area = 0, area_num = 0, color = 0; const char *p = this->protocol; dev_size_t len, written; enum { TOP_AREA, BOTTOM_AREA, LEFT_AREA, RIGHT_AREA, CENTER_AREA, TOP_LEFT_AREA, TOP_RIGHT_AREA, BOTTOM_LEFT_AREA, BOTTOM_RIGHT_AREA }; enum { COLOR_RED, COLOR_GREEN, COLOR_BLUE }; enum { START_STATE, DEC_CONST_STATE, HEX_CONST_STATE, AREA_STATE, AREA_NUM_STATE, CRC_STATE }; enum { NO_ERR, SYNTAX_ERR, DATA_ERR, LENGTH_ERR, CRC_MODE_ERR }; enum { ERR_CRC_MODE, XOR_CRC_MODE }; int state = START_STATE; int err = NO_ERR; int crc_mode = ERR_CRC_MODE; uint8_t *crc_pos = NULL; if (this->devfd == INVALID_DEV_HANDLE) return -1; /* parse protocol descriptor and build data packet */ while (err == NO_ERR) { int c = *p++; switch (state) { case START_STATE: switch (c) { case 0: break; case 'x': case 'X': data = 0; state = HEX_CONST_STATE; break; case 'r': case 'R': color = COLOR_RED; state = AREA_STATE; break; case 'g': case 'G': color = COLOR_GREEN; state = AREA_STATE; break; case 'b': case 'B': color = COLOR_BLUE; state = AREA_STATE; break; case 'c': case 'C': state = CRC_STATE; break; default: if (c >= '0' && c <= '9') { data = c - '0'; state = DEC_CONST_STATE; } else err = SYNTAX_ERR; } break; case CRC_STATE: switch (c) { case 'x': case 'X': crc_mode = XOR_CRC_MODE; break; case '|': case 0: if (crc_mode == ERR_CRC_MODE) err = CRC_MODE_ERR; else { crc_pos = m++; state = START_STATE; } break; default: err = SYNTAX_ERR; } break; case DEC_CONST_STATE: if (c >= '0' && c <= '9') { data = data * 10 + c - '0'; if (data > 255) err = DATA_ERR; } else if (c == '|' || !c) { *m++ = data; state = START_STATE; } else err = SYNTAX_ERR; break; case HEX_CONST_STATE: if (c >= '0' && c <= '9') { data = data * 16 + c - '0'; if (data > 255) err = DATA_ERR; } else if (c >= 'a' && c <= 'f') { data = data * 16 + c - 'a' + 10; if (data > 255) err = DATA_ERR; } else if (c >= 'A' && c <= 'F') { data = data * 16 + c - 'A' + 10; if (data > 255) err = DATA_ERR; } else if (c == '|' || !c) { *m++ = data; state = START_STATE; } else err = SYNTAX_ERR; break; case AREA_STATE: area_num = 0; state = AREA_NUM_STATE; switch (c) { case 't': case 'T': area = TOP_AREA; break; case 'b': case 'B': area = BOTTOM_AREA; break; case 'l': case 'L': area = LEFT_AREA; break; case 'r': case 'R': area = RIGHT_AREA; break; case 'c': case 'C': area = CENTER_AREA; break; default: err = SYNTAX_ERR; } break; case AREA_NUM_STATE: switch (c) { case 'l': case 'L': switch (area) { case TOP_AREA: area = TOP_LEFT_AREA; break; case BOTTOM_AREA: area = BOTTOM_LEFT_AREA; break; default: err = SYNTAX_ERR; } break; case 'r': case 'R': switch (area) { case TOP_AREA: area = TOP_RIGHT_AREA; break; case BOTTOM_AREA: area = BOTTOM_RIGHT_AREA; break; default: err = SYNTAX_ERR; } break; default: if (c >= '0' && c <= '9') area_num = area_num * 10 + c - '0'; else if (c == '|' || !c) { int n, i; uint8_t v; switch (area) { case TOP_AREA: i = 0; n = this->param.top; break; case BOTTOM_AREA: i = this->param.top; n = this->param.bottom; break; case LEFT_AREA: i = this->param.top + this->param.bottom; n = this->param.left; break; case RIGHT_AREA: i = this->param.top + this->param.bottom + this->param.left; n = this->param.right; break; case CENTER_AREA: i = this->param.top + this->param.bottom + this->param.left + this->param.right; n = this->param.center; break; case TOP_LEFT_AREA: i = this->param.top + this->param.bottom + this->param.left + this->param.right + this->param.center; n = this->param.top_left; break; case TOP_RIGHT_AREA: i = this->param.top + this->param.bottom + this->param.left + this->param.right + this->param.center + this->param.top_left; n = this->param.top_right; break; case BOTTOM_LEFT_AREA: i = this->param.top + this->param.bottom + this->param.left + this->param.right + this->param.center + this->param.top_left + this->param.top_right; n = this->param.bottom_left; break; default: i = this->param.top + this->param.bottom + this->param.left + this->param.right + this->param.center + this->param.top_left + this->param.top_right + this->param.bottom_left; n = this->param.bottom_right; } if (area_num) --area_num; if (area_num < n) { i += area_num; switch (color) { case COLOR_RED: v = colors[i].r; break; case COLOR_GREEN: v = colors[i].g; break; default: v = colors[i].b; } } else v = 0; if (this->escapes) { int n = this->escapes[1]; const uint8_t *p = &this->escapes[2]; while (n) { if (v == *p) { *m++ = this->escapes[0]; break; } ++p; --n; } } *m++ = v; state = START_STATE; } else err = SYNTAX_ERR; } } if (!c) { if (state != START_STATE) err = SYNTAX_ERR; break; } if ((m - msg) >= sizeof(msg)) err = LENGTH_ERR; } if (err != NO_ERR) { switch (err) { case SYNTAX_ERR: snprintf(this->output_driver.errmsg, sizeof(this->output_driver.errmsg), "protocol syntax error at position: %d", (int)(p - this->protocol)); break; case DATA_ERR: snprintf(this->output_driver.errmsg, sizeof(this->output_driver.errmsg), "bad data byte value: %d", data); break; case LENGTH_ERR: snprintf(this->output_driver.errmsg, sizeof(this->output_driver.errmsg), "message to long"); break; case CRC_MODE_ERR: snprintf(this->output_driver.errmsg, sizeof(this->output_driver.errmsg), "missing crc mode"); } return -1; } if (crc_pos != NULL) { uint8_t *v = msg; uint8_t crc = 0; while (v < m) { if (v != crc_pos) crc ^= *v; ++v; } *crc_pos = crc; } len = (dev_size_t)(m - msg); if (!WRITE_DATA(this->devfd, msg, len, written) || !FLUSH_BUFFER(this->devfd)) { char buf[128]; GET_SYS_ERR_MSG(buf); snprintf(this->output_driver.errmsg, sizeof(this->output_driver.errmsg), "writing data to serial port failed: %s", buf); return -1; } return 0; }