Пример #1
0
/* Given an instruction corresponding to a call, validate that the generated
 * return address is safe.
 * Parameters:
 *   vstate - The state of the validator.
 */
static void NaClValidateCallAlignment(NaClValidatorState* vstate) {
  /* The return is safe only if it begins at an aligned address (since
   * return instructions are not explicit jumps).
   */
  NaClPcAddress next_addr = vstate->cur_inst_state->inst_addr
      + NaClInstStateLength(vstate->cur_inst_state);
  if (next_addr & vstate->bundle_mask) {
    NaClPcAddress printable_next_addr =
        NaClInstStatePrintableAddress(vstate->cur_inst_state) +
        NaClInstStateLength(vstate->cur_inst_state);
    /* NOTE: Previously the validator recorded an error for call instructions
     * that were not aligned against the end of a bundle, as these, while
     * safe, are not correct with the current code generation idioms.
     * This #if defined(ERROR_ON_CALL_BUNDLE_ALIGNMENT) was added to allow
     * experimentation with different call/return idioms.
     */
    if (!NACL_FLAGS_unsafe_single_inst_mode) {
      NaClValidatorInstMessage(
#if defined(ERROR_ON_CALL_BUNDLE_ALIGNMENT)
          LOG_ERROR,
#else
          LOG_WARNING,
#endif
          vstate, vstate->cur_inst_state,
          "Bad call alignment, return pc = %"NACL_PRIxNaClPcAddress"\n",
          printable_next_addr);
    }
  }
}
Пример #2
0
void NaClInstStateInstPrint(struct Gio* file, NaClInstState* state) {
  int i;
  const NaClInst* inst;

  /* Print out the address and the inst bytes. */
  int length = NaClInstStateLength(state);

  DEBUG_OR_ERASE(
      NaClInstPrint(file, state->decoder_tables, NaClInstStateInst(state)));
  DEBUG(NaClExpVectorPrint(file, state));
  gprintf(file, "%"NACL_PRIxNaClPcAddressAll": ",
          NaClInstStatePrintableAddress(state));
  for (i = 0; i < length; ++i) {
    gprintf(file, "%02"NACL_PRIx8" ", NaClInstStateByte(state, i));
  }
  for (i = length; i < NACL_MAX_BYTES_PER_X86_INSTRUCTION; ++i) {
    gprintf(file, "   ");
  }

  /* Print out the assembly instruction it disassembles to. */
  inst = NaClInstStateInst(state);
  NaClPrintDisassembled(file, state, inst);
  gprintf(file, "\n");
}
Пример #3
0
/* Print out the given constant expression node to the given file. */
static void NaClPrintDisassembledConst(
    struct Gio* file, NaClInstState* state, NaClExp* node) {
  assert(node->kind == ExprConstant);
  if (node->flags & NACL_EFLAG(ExprJumpTarget)) {
    NaClPcAddress target = NaClInstStatePrintableAddress(state)
        + state->bytes.length + (NaClPcNumber) NaClGetExprSignedValue(node);
    gprintf(file, "0x%"NACL_PRIxNaClPcAddress, target);
  }else if (node->flags & NACL_EFLAG(ExprUnsignedHex)) {
    gprintf(file, "0x%"NACL_PRIx64, NaClGetExprUnsignedValue(node));
  } else if (node->flags & NACL_EFLAG(ExprSignedHex)) {
    int64_t val = NaClGetExprSignedValue(node);
    if (val < 0) {
      val = -val;
      gprintf(file, "-0x%"NACL_PRIx64, val);
    } else {
      gprintf(file, "0x%"NACL_PRIx64, val);
    }
  } else if (node->flags & NACL_EFLAG(ExprUnsignedInt)) {
    gprintf(file, "%"NACL_PRIu64, NaClGetExprUnsignedValue(node));
  } else {
    /* Assume ExprSignedInt. */
    gprintf(file, "%"NACL_PRId64, NaClGetExprSignedValue(node));
  }
}