Exemple #1
0
ArgUnion getImm(PC const origPC, int idx, const Unit* unit) {
  auto pc = origPC;
  auto const UNUSED op = decode_op(pc);
  assert(idx >= 0 && idx < numImmediates(op));
  ArgUnion retval;
  retval.u_NA = 0;
  int cursor = 0;
  for (cursor = 0; cursor < idx; cursor++) {
    // Advance over this immediate.
    pc += immSize(origPC, cursor);
  }
  always_assert(cursor == idx);
  auto const type = immType(op, idx);
  if (type == IVA || type == LA || type == IA) {
    retval.u_IVA = decodeVariableSizeImm(&pc);
  } else if (type == KA) {
    assert(unit != nullptr);
    retval.u_KA = decode_member_key(pc, unit);
  } else if (!immIsVector(op, cursor)) {
    always_assert(type != RATA);  // Decode RATAs with a different function.
    memcpy(&retval.bytes, pc, immSize(origPC, idx));
  }
  always_assert(numImmediates(op) > idx);
  return retval;
}
Exemple #2
0
ArgUnion getImm(const PC origPC, int idx, const Unit* unit) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  assertx(idx >= 0 && idx < numImmediates(op));
  ArgUnion retval;
  retval.u_NA = 0;
  int cursor = 0;
  for (cursor = 0; cursor < idx; cursor++) {
    // Advance over this immediate.
    pc += immSize(immType(op, cursor), pc);
  }
  always_assert(cursor == idx);
  auto const type = immType(op, idx);
  if (type == IVA || type == LA || type == IA ||
      type == CAR || type == CAW) {
    retval.u_IVA = decode_iva(pc);
  } else if (type == KA) {
    assertx(unit != nullptr);
    retval.u_KA = decode_member_key(pc, unit);
  } else if (type == LAR) {
    retval.u_LAR = decodeLocalRange(pc);
  } else if (type == FCA) {
    retval.u_FCA = decodeFCallArgs(pc);
  } else if (type == RATA) {
    assertx(unit != nullptr);
    retval.u_RATA = decodeRAT(unit, pc);
  } else if (!argTypeIsVector(type)) {
    memcpy(&retval.bytes, pc, immSize(type, pc));
  }
  always_assert(numImmediates(op) > idx);
  return retval;
}
Exemple #3
0
offs_t lc8670_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
	int pos = 0;
	char arg1[16], arg2[16];

	UINT8 op = oprom[pos++];

	int op_idx = decode_op(op);
	const dasm_entry *inst = &s_dasm_table[op_idx];

	buffer += sprintf(buffer,"%-8s", inst->str);

	dasm_arg(op, inst->inv ? arg2 : arg1, pc+0, inst->arg1, oprom, pos);
	dasm_arg(op, inst->inv ? arg1 : arg2, pc+1, inst->arg2, oprom, pos);

	strcat(buffer, arg1);

	if (inst->arg2 != OP_NULL)
	{
		strcat(buffer, ",");
		strcat(buffer, arg2);
	}

	return pos;
}
Exemple #4
0
int instrLen(PC const origPC) {
  auto pc = origPC;
  auto op = decode_op(pc);
  int nImm = numImmediates(op);
  for (int i = 0; i < nImm; i++) {
    pc += immSize(origPC, i);
  }
  return pc - origPC;
}
Exemple #5
0
void decode_and_print_code( RW_Robo_Op *code, size_t length ) {
    size_t i;
    int opcode, reg1, reg2, reg3, imme;
    printf("Generated code:\n");
    for( i = 0; i < length; i++ ) {
        printf("%d: ", (int)i);
        decode_op(code[i], opcode, reg1, reg2, reg3, imme);
        switch( opcode ) {
            case op_nop:
            case op_ne:
            case op_eq:
            case op_lt:
            case op_gt:
            case op_add:
            case op_sub:
            case op_mul:
            case op_div:
            case op_mod:
            case op_and:
            case op_or:
            case op_xor:
            case op_max:
            case op_min:
            case op_dist:
            case op_sin:
            case op_cos:
            case op_tan:
            case op_arcsin:
            case op_arccos:
            case op_arctan:
                print_code_3reg(opcode, reg1, reg2, reg3);
                break;
            case op_two_reg:
                print_code_2reg(reg3, reg1, reg2);
                break;
            case op_one_reg:
                print_code_1reg(reg3, reg1);
                break;
            case op_zero_reg:
                print_code_0reg(reg3);
                break;
            case op_call:
            case op_jump:
            case op_mova:
            case op_movb:
            case op_push:
                print_code_immed(opcode, imme);
                break;
            default:
                printf("BAD OPERATOR\n");
                break;
        }
    }
}
Exemple #6
0
ArgUnion* getImmPtr(PC const origPC, int idx) {
  auto pc = origPC;
  auto const UNUSED op = decode_op(pc);
  assert(immType(op, idx) != IVA);
  assert(immType(op, idx) != LA);
  assert(immType(op, idx) != IA);
  assert(immType(op, idx) != RATA);
  for (int i = 0; i < idx; i++) {
    pc += immSize(origPC, i);
  }
  return (ArgUnion*)pc;
}
Exemple #7
0
// Await / Yield opcodes mark a suspend points of async functions and
// generators. Execution will resume at this function later after the
// opcode.
void CmdNext::setupStepSuspend(ActRec* fp, PC pc) {
  // Yield is followed by the label where execution will continue.
  auto const op = decode_op(pc);
  assertx(op == OpAwait || op == OpYield || op == OpYieldK);
  if (op == OpAwait) {
    decode_iva(pc);
  }
  Offset nextInst = fp->func()->unit()->offsetOf(pc);
  assertx(nextInst != InvalidAbsoluteOffset);
  m_stepResumableId = fp;
  TRACE(2, "CmdNext: patch for resumable step at '%s' offset %d\n",
        fp->m_func->fullName()->data(), nextInst);
  m_stepResumable = StepDestination(fp->m_func->unit(), nextInst);
}
Exemple #8
0
ArgUnion* getImmPtr(const PC origPC, int idx) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  assertx(immType(op, idx) != IVA);
  assertx(immType(op, idx) != LA);
  assertx(immType(op, idx) != IA);
  assertx(immType(op, idx) != CAR);
  assertx(immType(op, idx) != CAW);
  assertx(immType(op, idx) != RATA);
  for (int i = 0; i < idx; i++) {
    pc += immSize(immType(op, i), pc);
  }
  return (ArgUnion*)pc;
}
Exemple #9
0
/**
 * Return the number of successor-edges including fall-through paths but not
 * implicit exception paths.
 */
int numSuccs(PC const origPC) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  if ((instrFlags(op) & TF) != 0) {
    if (isSwitch(op)) {
      return decode_raw<int32_t>(pc);
    }
    if (isUnconditionalJmp(op) || op == OpIterBreak) return 1;
    return 0;
  }
  if (!instrIsControlFlow(op)) return 1;
  if (instrJumpOffset(origPC)) return 2;
  return 1;
}
Exemple #10
0
/**
 * Return the number of successor-edges including fall-through paths but not
 * implicit exception paths.
 */
int numSuccs(PC const origPC) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  if ((instrFlags(op) & TF) != 0) {
    if (isSwitch(op)) {
      if (op == Op::Switch) {
        decode_raw<SwitchKind>(pc); // skip bounded flag
        decode_raw<int64_t>(pc); // skip base
      }
      return decode_raw<int32_t>(pc); // vector length
    }
    if (isUnconditionalJmp(op) || op == OpIterBreak) return 1;
    return 0;
  }
  if (!instrIsControlFlow(op)) return 1;
  if (instrJumpOffset(origPC)) return 2;
  return 1;
}
Exemple #11
0
void test_instr_encoding() {
    RW_Robo_Op op;
    int opcode, reg1, reg2, reg3, imme;
    encode_op_regs(op, op_add, 1, 2, 3);
    decode_op(op, opcode, reg1, reg2, reg3, imme);
    if( opcode != op_add ) {
        printf("opcode encoding/decoding error\n");
    }
    if( reg1 != 1 ) {
        printf("reg1 encoding/decoding error\n");
    }
    if( reg2 != 2 ) {
        printf("reg2 encoding/decoding error\n");
    }
    if( reg3 != 3 ) {
        printf("reg3 encoding/decoding error\n");
    }
}
Exemple #12
0
int
main(int argc, char ** argv)
{
	char * operation = argv[1]; 
	unsigned int size;
	unsigned short i, byte, key, op;
	if (argc != 4)
		usage(), exit(1);
	if (!strcmp(operation, "add")) {
		op = ADD;
	} else if (!strcmp(operation, "sub")) {
		op = SUB;
	} else if (!strcmp(operation, "xor")) {
		op = XOR;
	} else
		usage(), exit(1);
	key = atoi(argv[2]);
	size = strlen(argv[3]);
	printf("shellcode %s 0x%.2x encoded:\n", argv[1], key);
	printf("\"");
	printf(
				//_start:
"\\xeb\\x0d"			//    jmp    encoded
				//decoder:
"\\x5e"				//    pop    %esi
"\\x6a\\x%.2x"			//    push   $size
"\\x5f"				//    pop    %edx
				//decoder_loop:
"\\x83\\x%.2x\\x3e\\x%.2x"	//    inst   $key,(%esi,%edx,1)
"\\x4f"				//    dec    %edx
"\\x75\\xf9"			//    jne    decoder_loop
"\\xeb\\x05"			//    jmp    shellcode
				//encoded:
"\\xe8\\xee\\xff\\xff\\xff",	//    call   decoder
				//shellcode:
size, decode_op(op), key);

	for(i = 0; i < size; i++) {
		byte = (argv[3][i] & 0xff);
		printf("\\x%.2x", calc(op, byte, key));
	}
	puts("\"");
	return 0;
}
Exemple #13
0
void lc8670_cpu_device::execute_run()
{
	if (m_clock_changed)
	{
		change_clock_source();
		return;
	}

	do
	{
		check_irqs();

		debugger_instruction_hook(this, m_pc);

		int cycles = 0;
		m_ppc = m_pc;

		if (REG_PCON & HALT_MODE)
		{
			// in HALT state the timers are still updated
			cycles = 1;
		}
		else
		{
			// instruction fetch
			m_op = fetch();
			int op_idx = decode_op(m_op);

			// execute the instruction
			cycles = (this->*s_opcode_table[op_idx])();
		}

		// update the instruction counter
		m_icount -= cycles;
	}
	while (m_icount > 0 && !m_clock_changed);
}
Exemple #14
0
Offset* instrJumpOffset(const PC origPC) {
  static const int8_t jumpMask[] = {
#define IMM_NA 0
#define IMM_IVA 0
#define IMM_I64A 0
#define IMM_DA 0
#define IMM_SA 0
#define IMM_AA 0
#define IMM_RATA 0
#define IMM_BA 1
#define IMM_BLA 0  // these are jump offsets, but must be handled specially
#define IMM_ILA 0
#define IMM_I32LA 0
#define IMM_BLLA 0
#define IMM_SLA 0
#define IMM_LA 0
#define IMM_IA 0
#define IMM_CAR 0
#define IMM_CAW 0
#define IMM_OA(x) 0
#define IMM_VSA 0
#define IMM_KA 0
#define IMM_LAR 0
#define IMM_FCA 0
#define ONE(a) IMM_##a
#define TWO(a, b) (IMM_##a + 2 * IMM_##b)
#define THREE(a, b, c) (IMM_##a + 2 * IMM_##b + 4 * IMM_##c)
#define FOUR(a, b, c, d) (IMM_##a + 2 * IMM_##b + 4 * IMM_##c + 8 * IMM_##d)
#define FIVE(a, b, c, d, e) (IMM_##a + 2 * IMM_##b + 4 * IMM_##c + 8 * IMM_##d + 16 * IMM_##e)
#define O(name, imm, pop, push, flags) imm,
    OPCODES
#undef IMM_NA
#undef IMM_IVA
#undef IMM_I64A
#undef IMM_DA
#undef IMM_SA
#undef IMM_AA
#undef IMM_RATA
#undef IMM_LA
#undef IMM_IA
#undef IMM_CAR
#undef IMM_CAW
#undef IMM_BA
#undef IMM_BLA
#undef IMM_ILA
#undef IMM_I32LA
#undef IMM_BLLA
#undef IMM_SLA
#undef IMM_OA
#undef IMM_VSA
#undef IMM_KA
#undef IMM_LAR
#undef IMM_FCA
#undef ONE
#undef TWO
#undef THREE
#undef FOUR
#undef FIVE
#undef O
  };

  auto pc = origPC;
  auto const op = decode_op(pc);
  assertx(!isSwitch(op));  // BLA doesn't work here

  if (op == OpIterBreak) {
    // offset is imm number 0
    return const_cast<Offset*>(reinterpret_cast<const Offset*>(pc));
  }

  int mask = jumpMask[size_t(op)];
  if (mask == 0) {
    return nullptr;
  }
  int immNum;
  switch (mask) {
  case 0: return nullptr;
  case 1: immNum = 0; break;
  case 2: immNum = 1; break;
  case 4: immNum = 2; break;
  case 8: immNum = 3; break;
  case 16: immNum = 4; break;
  default: assertx(false); return nullptr;
  }

  return &getImmPtr(origPC, immNum)->u_BA;
}
Exemple #15
0
std::string instrToString(PC it, Either<const Unit*, const UnitEmitter*> u) {
  std::stringstream out;
  PC iStart = it;
  Op op = decode_op(it);

  auto readRATA = [&] {
    if (auto unit = u.left()) {
      auto const rat = decodeRAT(unit, it);
      out << ' ' << show(rat);
      return;
    }

    auto const pc = it;
    it += encodedRATSize(pc);
    out << " <RepoAuthType>";
  };

  auto offsetOf = [u](PC pc) {
    return u.match(
      [pc](const Unit* u) { return u->offsetOf(pc); },
      [pc](const UnitEmitter* ue) { return ue->offsetOf(pc); }
    );
  };

  auto lookupLitstrId = [u](Id id) {
    return u.match(
      [id](const Unit* u) { return u->lookupLitstrId(id); },
      [id](const UnitEmitter* ue) { return ue->lookupLitstr(id); }
    );
  };

  auto lookupArrayId = [u](Id id) {
    return u.match(
      [id](const Unit* u) { return u->lookupArrayId(id); },
      [id](const UnitEmitter* ue) { return ue->lookupArray(id); }
    );
  };

  switch (op) {

#define READ(t) out << " " << *((t*)&*it); it += sizeof(t)

#define READOFF() do {                                              \
  Offset _value = *(Offset*)it;                                     \
  out << " " << _value;                                             \
  if (u != nullptr) {                                               \
    out << " (" << offsetOf(iStart + _value) << ")";                \
  }                                                                 \
  it += sizeof(Offset);                                             \
} while (false)

#define READV() out << " " << decodeVariableSizeImm(&it);

#define READLA() out << " L:" << decodeVariableSizeImm(&it);

#define READIVA() do {                      \
  out << " ";                               \
  auto imm = decodeVariableSizeImm((const uint8_t**)&it);    \
  if (op == OpIncStat && immIdx == 0) {     \
    out << Stats::g_counterNames[imm];      \
  } else {                                  \
    out << imm;                             \
  }                                         \
  immIdx++;                                 \
} while (false)

#define READOA(type) do {                       \
  auto const immVal = static_cast<type>(        \
    *reinterpret_cast<const uint8_t*>(it)       \
  );                                            \
  it += sizeof(unsigned char);                  \
  out << " " << subopToName(immVal);            \
} while (false)

#define READLITSTR(sep) do {                                      \
  Id id = decode_raw<Id>(it);                                     \
  if (id < 0) {                                                   \
    assert(op == OpSSwitch);                                      \
    out << sep << "-";                                            \
  } else {                                                        \
    auto const sd = lookupLitstrId(id);                           \
    out << sep << "\"" <<                                         \
      escapeStringForCPP(sd->data(), sd->size()) << "\"";         \
  }                                                               \
} while (false)

#define READSVEC() do {                         \
  int sz = decode_raw<int>(it);                 \
  out << " <";                                  \
  const char* sep = "";                         \
  for (int i = 0; i < sz; ++i) {                \
    out << sep;                                 \
    if (op == OpSSwitch) {                      \
      READLITSTR("");                           \
      out << ":";                               \
    }                                           \
    Offset o = decode_raw<Offset>(it);          \
    out << offsetOf(iStart + o);                \
    sep = " ";                                  \
  }                                             \
  out << ">";                                   \
} while (false)

#define READIVEC() do {                           \
  int sz = decode_raw<int>(it);                     \
  out << " <";                                    \
  const char* sep = "";                           \
  for (int i = 0; i < sz; ++i) {                  \
    out << sep;                                   \
    IterKind k = (IterKind)decode_raw<Id>(it);      \
    switch(k) {                                   \
      case KindOfIter:  out << "(Iter) ";  break; \
      case KindOfMIter: out << "(MIter) "; break; \
      case KindOfCIter: out << "(CIter) "; break; \
    }                                             \
    out << decode_raw<Id>(it);                      \
    sep = ", ";                                   \
  }                                               \
  out << ">";                                     \
} while (false)

#define ONE(a) H_##a
#define TWO(a, b) H_##a; H_##b
#define THREE(a, b, c) H_##a; H_##b; H_##c;
#define FOUR(a, b, c, d) H_##a; H_##b; H_##c; H_##d;
#define NA
#define H_BLA READSVEC()
#define H_SLA READSVEC()
#define H_ILA READIVEC()
#define H_IVA READIVA()
#define H_I64A READ(int64_t)
#define H_LA READLA()
#define H_IA READV()
#define H_DA READ(double)
#define H_BA READOFF()
#define H_OA(type) READOA(type)
#define H_SA READLITSTR(" ")
#define H_RATA readRATA()
#define H_AA do {                                                \
  out << ' ';                                                    \
  staticArrayStreamer(lookupArrayId(decode_raw<Id>(it)), out);   \
} while (false)
#define H_VSA do {                                      \
  int sz = decode_raw<int32_t>(it);                     \
  out << " <";                                          \
  for (int i = 0; i < sz; ++i) {                        \
    H_SA;                                               \
  }                                                     \
  out << " >";                                          \
} while (false)
#define H_KA out << ' ' << show(decode_member_key(it, u))

#define O(name, imm, push, pop, flags)    \
  case Op##name: {                        \
    out << #name;                         \
    UNUSED unsigned immIdx = 0;           \
    imm;                                  \
    break;                                \
  }
OPCODES
#undef O
#undef READ
#undef READV
#undef READLA
#undef ONE
#undef TWO
#undef THREE
#undef FOUR
#undef NA
#undef H_BLA
#undef H_SLA
#undef H_ILA
#undef H_IVA
#undef H_I64A
#undef H_LA
#undef H_IA
#undef H_DA
#undef H_BA
#undef H_OA
#undef H_SA
#undef H_AA
#undef H_VSA
#undef H_KA
    default: assert(false);
  };
  return out.str();
}
Exemple #16
0
Offset* instrJumpOffset(PC const origPC) {
  static const int8_t jumpMask[] = {
#define IMM_NA 0
#define IMM_IVA 0
#define IMM_I64A 0
#define IMM_DA 0
#define IMM_SA 0
#define IMM_AA 0
#define IMM_RATA 0
#define IMM_BA 1
#define IMM_BLA 0  // these are jump offsets, but must be handled specially
#define IMM_ILA 0
#define IMM_SLA 0
#define IMM_LA 0
#define IMM_IA 0
#define IMM_OA(x) 0
#define IMM_VSA 0
#define IMM_KA 0
#define ONE(a) IMM_##a
#define TWO(a, b) (IMM_##a + 2 * IMM_##b)
#define THREE(a, b, c) (IMM_##a + 2 * IMM_##b + 4 * IMM_##c)
#define FOUR(a, b, c, d) (IMM_##a + 2 * IMM_##b + 4 * IMM_##c + 8 * IMM_##d)
#define O(name, imm, pop, push, flags) imm,
    OPCODES
#undef IMM_NA
#undef IMM_IVA
#undef IMM_I64A
#undef IMM_DA
#undef IMM_SA
#undef IMM_AA
#undef IMM_RATA
#undef IMM_LA
#undef IMM_IA
#undef IMM_BA
#undef IMM_BLA
#undef IMM_ILA
#undef IMM_SLA
#undef IMM_OA
#undef IMM_VSA
#undef IMM_KA
#undef ONE
#undef TWO
#undef THREE
#undef FOUR
#undef O
  };

  auto pc = origPC;
  auto const op = decode_op(pc);
  assert(!isSwitch(op));  // BLA doesn't work here

  if (op == OpIterBreak) {
    auto const veclen = decode_raw<uint32_t>(pc);
    assert(veclen > 0);
    auto const target = const_cast<Offset*>(
      reinterpret_cast<const Offset*>(
        reinterpret_cast<const uint32_t*>(pc) + 2 * veclen
      )
    );
    return target;
  }

  int mask = jumpMask[size_t(op)];
  if (mask == 0) {
    return nullptr;
  }
  int immNum;
  switch (mask) {
  case 0: return nullptr;
  case 1: immNum = 0; break;
  case 2: immNum = 1; break;
  case 4: immNum = 2; break;
  case 8: immNum = 3; break;
  default: assert(false); return nullptr;
  }

  return &getImmPtr(origPC, immNum)->u_BA;
}
Exemple #17
0
std::string instrToString(PC it, Either<const Unit*, const UnitEmitter*> u) {
  std::string out;
  PC iStart = it;
  Op op = decode_op(it);

  auto readRATA = [&] {
    if (auto unit = u.left()) {
      auto const rat = decodeRAT(unit, it);
      folly::format(&out, " {}", show(rat));
      return;
    }

    auto const pc = it;
    it += encodedRATSize(pc);
    out += " <RepoAuthType>";
  };

  auto offsetOf = [u](PC pc) {
    return u.match(
      [pc](const Unit* u) { return u->offsetOf(pc); },
      [pc](const UnitEmitter* ue) { return ue->offsetOf(pc); }
    );
  };

  auto lookupLitstrId = [u](Id id) {
    return u.match(
      [id](const Unit* u) { return u->lookupLitstrId(id); },
      [id](const UnitEmitter* ue) { return ue->lookupLitstr(id); }
    );
  };

  auto lookupArrayId = [u](Id id) {
    return u.match(
      [id](const Unit* u) { return u->lookupArrayId(id); },
      [id](const UnitEmitter* ue) { return ue->lookupArray(id); }
    );
  };

  switch (op) {

#define READ(t) folly::format(&out, " {}", *((t*)&*it)); it += sizeof(t)

#define READOFF() do {                                          \
  Offset _value = *(Offset*)it;                                 \
  folly::format(&out, " {}", _value);                           \
  if (u != nullptr) {                                           \
    folly::format(&out, " ({})", offsetOf(iStart + _value));    \
  }                                                             \
  it += sizeof(Offset);                                         \
} while (false)

#define READV() folly::format(&out, " {}", decode_iva(it));

#define READLA() folly::format(&out, " L:{}", decode_iva(it));

#define READIVA() do {                                          \
  auto imm = decode_iva(it);                                    \
  folly::format(&out, " {}", imm);                              \
  immIdx++;                                                     \
} while (false)

#define READOA(type) do {                               \
  auto const immVal = static_cast<type>(                \
    *reinterpret_cast<const uint8_t*>(it)               \
  );                                                    \
  it += sizeof(unsigned char);                          \
  folly::format(&out, " {}", subopToName(immVal));      \
} while (false)

#define READLITSTR(sep) do {                                    \
  Id id = decode_raw<Id>(it);                                   \
  if (id < 0) {                                                 \
    assertx(op == OpSSwitch);                                    \
    folly::format(&out, "{}-", sep);                            \
  } else {                                                      \
    auto const sd = lookupLitstrId(id);                         \
    folly::format(&out, "{}\"{}\"", sep,                        \
                  escapeStringForCPP(sd->data(), sd->size()));  \
  }                                                             \
} while (false)

#define READSVEC() do {                                 \
  int sz = decode_iva(it);                              \
  out += " <";                                          \
  const char* sep = "";                                 \
  for (int i = 0; i < sz; ++i) {                        \
    out += sep;                                         \
    if (op == OpSSwitch) {                              \
      READLITSTR("");                                   \
      out += ":";                                       \
    }                                                   \
    Offset o = decode_raw<Offset>(it);                  \
    folly::format(&out, "{}", offsetOf(iStart + o));    \
    sep = " ";                                          \
  }                                                     \
  out += ">";                                           \
} while (false)

#define READI32VEC() do {                                      \
  int sz = decode_iva(it);                                     \
  out += " <";                                                 \
  const char* sep = "";                                        \
  for (int i = 0; i < sz; ++i) {                               \
    folly::format(&out, "{}{}", sep, decode_raw<uint32_t>(it));\
    sep = ", ";                                                \
  }                                                            \
  out += ">";                                                  \
} while (false)

#define READBOOLVEC() do {                                     \
  int sz = decode_iva(it);                                     \
  uint8_t tmp = 0;                                             \
  out += " \"";                                                \
  for (int i = 0; i < sz; ++i) {                               \
    if (i % 8 == 0) tmp = decode_raw<uint8_t>(it);             \
    out += ((tmp >> (i % 8)) & 1) ? "1" : "0";                 \
  }                                                            \
  out += "\"";                                                 \
} while (false)

#define READITERTAB() do {                              \
  auto const sz = decode_iva(it);                       \
  out += " <";                                          \
  const char* sep = "";                                 \
  for (int i = 0; i < sz; ++i) {                        \
    out += sep;                                         \
    auto const k = (IterKind)decode_iva(it);            \
    switch (k) {                                        \
      case KindOfIter:  out += "(Iter) ";  break;       \
      case KindOfMIter: out += "(MIter) "; break;       \
      case KindOfCIter: out += "(CIter) "; break;       \
      case KindOfLIter: out += "(LIter) "; break;       \
    }                                                   \
    folly::format(&out, "{}", decode_iva(it));           \
    if (k == KindOfLIter) {                             \
      folly::format(&out, " L:{}", decode_iva(it));     \
    }                                                   \
    sep = ", ";                                         \
  }                                                     \
  out += ">";                                           \
} while (false)

#define ONE(a) H_##a
#define TWO(a, b) H_##a; H_##b
#define THREE(a, b, c) H_##a; H_##b; H_##c;
#define FOUR(a, b, c, d) H_##a; H_##b; H_##c; H_##d;
#define FIVE(a, b, c, d, e) H_##a; H_##b; H_##c; H_##d; H_##e;
#define NA
#define H_BLA READSVEC()
#define H_SLA READSVEC()
#define H_ILA READITERTAB()
#define H_I32LA READI32VEC()
#define H_BLLA READBOOLVEC()
#define H_IVA READIVA()
#define H_I64A READ(int64_t)
#define H_LA READLA()
#define H_IA READV()
#define H_CAR READV()
#define H_CAW READV()
#define H_DA READ(double)
#define H_BA READOFF()
#define H_OA(type) READOA(type)
#define H_SA READLITSTR(" ")
#define H_RATA readRATA()
#define H_AA do {                                                \
  out += ' ';                                                    \
  staticArrayStreamer(lookupArrayId(decode_raw<Id>(it)), out);   \
} while (false)
#define H_VSA do {                                      \
  int sz = decode_iva(it);                              \
  out += " <";                                          \
  for (int i = 0; i < sz; ++i) {                        \
    H_SA;                                               \
  }                                                     \
  out += " >";                                          \
} while (false)
#define H_KA (out += ' ', out += show(decode_member_key(it, u)))
#define H_LAR (out += ' ', out += show(decodeLocalRange(it)))
#define H_FCA (out += ' ', out += show(decodeFCallArgs(it)))

#define O(name, imm, push, pop, flags)    \
  case Op##name: {                        \
    out += #name;                         \
    UNUSED unsigned immIdx = 0;           \
    imm;                                  \
    break;                                \
  }
OPCODES
#undef O
#undef READ
#undef READV
#undef READLA
#undef ONE
#undef TWO
#undef THREE
#undef FOUR
#undef FIVE
#undef NA
#undef H_BLA
#undef H_SLA
#undef H_ILA
#undef H_I32LA
#undef H_BLLA
#undef H_IVA
#undef H_I64A
#undef H_LA
#undef H_IA
#undef H_CAR
#undef H_CAW
#undef H_DA
#undef H_BA
#undef H_OA
#undef H_SA
#undef H_AA
#undef H_VSA
#undef H_KA
#undef H_LAR
#undef H_FCA
    default: assertx(false);
  };
  return out;
}
Exemple #18
0
int immSize(PC origPC, int idx) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  assert(idx >= 0 && idx < numImmediates(op));
  always_assert(idx < 4); // No origPCs have more than four immediates
  static const int8_t argTypeToSizes[] = {
#define ARGTYPE(nm, type) sizeof(type),
#define ARGTYPEVEC(nm, type) 0,
    ARGTYPES
#undef ARGTYPE
#undef ARGTYPEVEC
  };

  if (immType(op, idx) == IVA ||
      immType(op, idx) == LA ||
      immType(op, idx) == IA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    auto const imm = decode_raw<uint8_t>(pc);

    // Low order bit set => 4-byte.
    return (imm & 0x1 ? sizeof(int32_t) : sizeof(unsigned char));
  }

  if (immType(op, idx) == RATA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    return encodedRATSize(pc);
  }

  if (immIsVector(op, idx)) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    int prefixes, vecElemSz;
    auto itype = immType(op, idx);
    if (itype == MA) {
      prefixes = 2;
      vecElemSz = sizeof(uint8_t);
    } else if (itype == BLA) {
      prefixes = 1;
      vecElemSz = sizeof(Offset);
    } else if (itype == ILA) {
      prefixes = 1;
      vecElemSz = 2 * sizeof(uint32_t);
    } else if (itype == VSA) {
      prefixes = 1;
      vecElemSz = sizeof(Id);
    } else {
      assert(itype == SLA);
      prefixes = 1;
      vecElemSz = sizeof(StrVecItem);
    }
    return prefixes * sizeof(int32_t) +
      vecElemSz * decode_raw<int32_t>(pc);
  }

  ArgType type = immType(op, idx);
  return (type >= 0) ? argTypeToSizes[type] : 0;
}
Exemple #19
0
std::string instrToString(PC it, const Unit* u /* = NULL */) {
  std::stringstream out;
  PC iStart = it;
  Op op = decode_op(it);

  auto readRATA = [&] {
    if (!u) {
      auto const pc = it;
      it += encodedRATSize(pc);
      out << " <RepoAuthType>";
      return;
    }
    auto const rat = decodeRAT(u, it);
    out << ' ' << show(rat);
  };

  switch (op) {

#define READ(t) out << " " << *((t*)&*it); it += sizeof(t)

#define READOFF() do {                                              \
  Offset _value = *(Offset*)it;                                     \
  out << " " << _value;                                             \
  if (u != nullptr) {                                               \
    out << " (" << u->offsetOf(iStart + _value) << ")";             \
  }                                                                 \
  it += sizeof(Offset);                                             \
} while (false)

#define READV() out << " " << decodeVariableSizeImm(&it);

#define READLA() out << " L:" << decodeVariableSizeImm(&it);

#define READIVA() do {                      \
  out << " ";                               \
  auto imm = decodeVariableSizeImm((const uint8_t**)&it);    \
  if (op == OpIncStat && immIdx == 0) {     \
    out << Stats::g_counterNames[imm];      \
  } else {                                  \
    out << imm;                             \
  }                                         \
  immIdx++;                                 \
} while (false)

#define READOA(type) do {                       \
  auto const immVal = static_cast<type>(        \
    *reinterpret_cast<const uint8_t*>(it)       \
  );                                            \
  it += sizeof(unsigned char);                  \
  out << " " << subopToName(immVal);            \
} while (false)

#define READVEC() do {                                                  \
  int sz = *((int*)&*it);                                               \
  it += sizeof(int) * 2;                                                \
  const uint8_t* const start = (uint8_t*)it;                             \
  out << " <";                                                          \
  if (sz > 0) {                                                         \
    int immVal = (int)*((unsigned char*)&*it);                          \
    out << ((immVal >= 0 && size_t(immVal) < locationNamesCount) ?      \
            locationCodeString(LocationCode(immVal)) : "?");            \
    it += sizeof(unsigned char);                                        \
    int numLocImms = numLocationCodeImms(LocationCode(immVal));         \
    for (int i = 0; i < numLocImms; ++i) {                              \
      out << ':' << decodeVariableSizeImm((const uint8_t**)&it);        \
    }                                                                   \
    while (reinterpret_cast<const uint8_t*>(it) - start < sz) {         \
      immVal = (int)*((unsigned char*)&*it);                            \
      out << " " << ((immVal >=0 && size_t(immVal) < memberNamesCount) ? \
                     memberCodeString(MemberCode(immVal)) : "?");       \
      it += sizeof(unsigned char);                                      \
      if (memberCodeHasImm(MemberCode(immVal))) {                       \
        int64_t imm = decodeMemberCodeImm((const uint8_t**)&it,         \
                                          MemberCode(immVal));          \
        out << ':';                                                     \
        if (memberCodeImmIsString(MemberCode(immVal)) && u) {           \
          const StringData* str = u->lookupLitstrId(imm);               \
          int len = str->size();                                        \
          String escaped = string_addslashes(str->data(), len);         \
          out << '"' << escaped.data() << '"';                          \
        } else {                                                        \
          out << imm;                                                   \
        }                                                               \
      }                                                                 \
    }                                                                   \
    assert(reinterpret_cast<const uint8_t*>(it) - start == sz);         \
  }                                                                     \
  out << ">";                                                           \
} while (false)

#define READLITSTR(sep) do {                                      \
  Id id = decode_raw<Id>(it);                                       \
  if (id < 0) {                                                   \
    assert(op == OpSSwitch);                                      \
    out << sep << "-";                                            \
  } else if (u) {                                                 \
    const StringData* sd = u->lookupLitstrId(id);                 \
    out << sep << "\"" <<                                         \
      escapeStringForCPP(sd->data(), sd->size()) << "\"";         \
  } else {                                                        \
    out << sep << id;                                             \
  }                                                               \
} while (false)

#define READSVEC() do {                         \
  int sz = decode_raw<int>(it);                   \
  out << " <";                                  \
  const char* sep = "";                         \
  for (int i = 0; i < sz; ++i) {                \
    out << sep;                                 \
    if (op == OpSSwitch) {                      \
      READLITSTR("");                           \
      out << ":";                               \
    }                                           \
    Offset o = decode_raw<Offset>(it);            \
    if (u != nullptr) {                         \
      if (iStart + o == u->entry() - 1) {       \
        out << "Invalid";                       \
      } else {                                  \
        out << u->offsetOf(iStart + o);         \
      }                                         \
    } else {                                    \
      out << o;                                 \
    }                                           \
    sep = " ";                                  \
  }                                             \
  out << ">";                                   \
} while (false)

#define READIVEC() do {                           \
  int sz = decode_raw<int>(it);                     \
  out << " <";                                    \
  const char* sep = "";                           \
  for (int i = 0; i < sz; ++i) {                  \
    out << sep;                                   \
    IterKind k = (IterKind)decode_raw<Id>(it);      \
    switch(k) {                                   \
      case KindOfIter:  out << "(Iter) ";  break; \
      case KindOfMIter: out << "(MIter) "; break; \
      case KindOfCIter: out << "(CIter) "; break; \
    }                                             \
    out << decode_raw<Id>(it);                      \
    sep = ", ";                                   \
  }                                               \
  out << ">";                                     \
} while (false)

#define ONE(a) H_##a
#define TWO(a, b) H_##a; H_##b
#define THREE(a, b, c) H_##a; H_##b; H_##c;
#define FOUR(a, b, c, d) H_##a; H_##b; H_##c; H_##d;
#define NA
#define H_MA READVEC()
#define H_BLA READSVEC()
#define H_SLA READSVEC()
#define H_ILA READIVEC()
#define H_IVA READIVA()
#define H_I64A READ(int64_t)
#define H_LA READLA()
#define H_IA READV()
#define H_DA READ(double)
#define H_BA READOFF()
#define H_OA(type) READOA(type)
#define H_SA READLITSTR(" ")
#define H_RATA readRATA()
#define H_AA                                                  \
  if (u) {                                                    \
    out << " ";                                               \
    staticArrayStreamer(u->lookupArrayId(*((Id*)it)), out);   \
  } else {                                                    \
    out << " " << *((Id*)it);                                 \
  }                                                           \
  it += sizeof(Id)
#define H_VSA do {                                      \
  int sz = decode_raw<int32_t>(it);                       \
  out << " <";                                          \
  for (int i = 0; i < sz; ++i) {                        \
    H_SA;                                               \
  }                                                     \
  out << " >";                                          \
} while (false)

#define O(name, imm, push, pop, flags)    \
  case Op##name: {                        \
    out << #name;                         \
    UNUSED unsigned immIdx = 0;           \
    imm;                                  \
    break;                                \
  }
OPCODES
#undef O
#undef READ
#undef READV
#undef READLA
#undef ONE
#undef TWO
#undef THREE
#undef FOUR
#undef NA
#undef H_MA
#undef H_BLA
#undef H_SLA
#undef H_ILA
#undef H_IVA
#undef H_I64A
#undef H_LA
#undef H_IA
#undef H_DA
#undef H_BA
#undef H_OA
#undef H_SA
#undef H_AA
#undef H_VSA
    default: assert(false);
  };
  return out.str();
}
Exemple #20
0
int immSize(PC origPC, int idx) {
  auto pc = origPC;
  auto const op = decode_op(pc);
  assert(idx >= 0 && idx < numImmediates(op));
  always_assert(idx < 4); // No origPCs have more than four immediates
  static const int8_t argTypeToSizes[] = {
#define ARGTYPE(nm, type) sizeof(type),
#define ARGTYPEVEC(nm, type) 0,
    ARGTYPES
#undef ARGTYPE
#undef ARGTYPEVEC
  };

  if (immType(op, idx) == IVA ||
      immType(op, idx) == LA ||
      immType(op, idx) == IA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    return encoded_iva_size(decode_raw<uint8_t>(pc));
  }

  if (immType(op, idx) == KA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);

    switch (decode_raw<MemberCode>(pc)) {
      case MW:
        return 1;
      case MEL: case MPL: case MEC: case MPC:
        return 1 + encoded_iva_size(decode_raw<uint8_t>(pc));
      case MEI:
        return 1 + sizeof(int64_t);
      case MET: case MPT: case MQT:
        return 1 + sizeof(Id);
    }
    not_reached();
  }

  if (immType(op, idx) == RATA) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    return encodedRATSize(pc);
  }

  if (immIsVector(op, idx)) {
    if (idx >= 1) pc += immSize(origPC, 0);
    if (idx >= 2) pc += immSize(origPC, 1);
    if (idx >= 3) pc += immSize(origPC, 2);
    int vecElemSz;
    auto itype = immType(op, idx);
    if (itype == BLA) {
      vecElemSz = sizeof(Offset);
    } else if (itype == ILA) {
      vecElemSz = 2 * sizeof(uint32_t);
    } else if (itype == VSA) {
      vecElemSz = sizeof(Id);
    } else {
      assert(itype == SLA);
      vecElemSz = sizeof(StrVecItem);
    }
    return sizeof(int32_t) + vecElemSz * decode_raw<int32_t>(pc);
  }

  ArgType type = immType(op, idx);
  return (type >= 0) ? argTypeToSizes[type] : 0;
}