Example #1
0
static void destroy_dyninst()
{
  int i;

  for(i = 0; i < dyninst_index; i++)
    replace_opcode(dyninst[i].arch, dyninst[i].oldinst, dyninst[i].opcode1, dyninst[i].opcode2);
}
Example #2
0
void inline_sget(DexMethod* method, DexOpcodeField* opfield) {
  if (!validate_sget(method, opfield)) return;
  auto opcode = OPCODE_CONST;
  auto dest = opfield->dest();
  auto field = resolve_field(opfield->field(), FieldSearch::Static);
  always_assert_log(field->is_concrete(), "Must be a concrete field");
  auto value = field->get_static_value();
  /* FIXME for sget_wide case */
  uint32_t v = value != nullptr ? (uint32_t)value->value() : 0;

  auto newopcode = (new DexInstruction(opcode))->set_dest(dest)->set_literal(v);
  replace_opcode(method, opfield, newopcode);
}
Example #3
0
void inline_cheap_sget(DexMethod* method, DexOpcodeField* opfield) {
  if (!validate_sget(method, opfield)) return;
  auto dest = opfield->dest();
  auto field = resolve_field(opfield->field(), FieldSearch::Static);
  always_assert_log(field->is_concrete(), "Must be a concrete field");
  auto value = field->get_static_value();
  /* FIXME for sget_wide case */
  uint32_t v = value != nullptr ? (uint32_t)value->value() : 0;
  auto opcode = [&] {
    if ((v & 0xffff) == v) {
      return OPCODE_CONST_16;
    } else if ((v & 0xffff0000) == v) {
      return OPCODE_CONST_HIGH16;
    }
    always_assert_log(false,
                      "Bad inline_cheap_sget queued up, can't fit to"
                      " CONST_16 or CONST_HIGH16, bailing\n");
  }();

  auto newopcode = (new DexInstruction(opcode, 0))->set_dest(dest)->set_literal(v);
  replace_opcode(method, opfield, newopcode);
}
Example #4
0
static void update_dyninst()
{
  int arch;
  char name[64];
  zz_func newinst;
  zz_func oldinst;
  int opcode1;
  int opcode2;

  for(arch = 0; arch < GEN_ARCHCOUNT; arch++)
  {
    for(opcode1 = 0; opcode1 < 0x100 && dyninst_index < MAXDYNINST; opcode1++)
    {
      snprintf(name, sizeof(name), "%s%02X", prefix[arch], opcode1);
      newinst = HDL_FINDSYM(name);
      if(newinst)
      {
        oldinst = replace_opcode(arch, newinst, opcode1, -1);
        if(oldinst)
        {
          dyninst[dyninst_index].opcode1 = opcode1;
          dyninst[dyninst_index].opcode2 = -1;
          dyninst[dyninst_index].arch = arch;
          dyninst[dyninst_index].newinst = newinst;
          dyninst[dyninst_index].oldinst = oldinst;
          dyninst_index++;
        }
      }

      switch(opcode1) {
        case 0x01:
        case 0xa4:
        case 0xa6:
        case 0xb2:
        case 0xb3:
        case 0xb9:
        case 0xe4:
        case 0xe5:
        case 0xe6:
        case 0xa5:
        case 0xa7:
        case 0xc0:
        case 0xc2:
        case 0xc4:
        case 0xc6:
        case 0xc8:
        case 0xcc:
        case 0xe3:
        case 0xeb:
        case 0xec:
        case 0xed:
          for(opcode2 = 0; opcode2 < 0x100 && dyninst_index < MAXDYNINST; opcode2++)
          {
            snprintf(name, sizeof(name), "%s%02X%02X", prefix[arch], opcode1, opcode2);
            newinst = HDL_FINDSYM(name);
            if(newinst)
            {
              oldinst = replace_opcode(arch, newinst, opcode1, opcode2);
              if(oldinst)
              {
                dyninst[dyninst_index].opcode1 = opcode1;
                dyninst[dyninst_index].opcode2 = opcode2;
                dyninst[dyninst_index].arch = arch;
                dyninst[dyninst_index].newinst = newinst;
                dyninst[dyninst_index].oldinst = oldinst;
                dyninst_index++;
              }
            }
          }
       }
    }
  }
}
Example #5
0
void IRList::replace_opcode(IRInstruction* from, IRInstruction* to) {
  always_assert_log(!is_branch(to->opcode()),
                    "You may want replace_branch instead");
  replace_opcode(from, std::vector<IRInstruction*>{to});
}