Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
/* 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);
    }
}
Exemple #4
0
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;
}