예제 #1
0
파일: srcdb.cpp 프로젝트: Dream-Seeker/hhvm
void SrcRec::chainFrom(IncomingBranch br) {
  assert(br.type() == IncomingBranch::Tag::ADDR ||
         mcg->code.isValidCodeAddress(br.toSmash()));
  TCA destAddr = getTopTranslation();
  m_incomingBranches.push_back(br);
  TRACE(1, "SrcRec(%p)::chainFrom %p -> %p (type %d); %zd incoming branches\n",
        this,
        br.toSmash(), destAddr, br.type(), m_incomingBranches.size());
  br.patch(destAddr);
}
예제 #2
0
void SrcRec::chainFrom(IncomingBranch br) {
  assertx(br.type() == IncomingBranch::Tag::ADDR ||
          tc::isValidCodeAddress(br.toSmash()));
  TCA destAddr = getTopTranslation();
  m_incomingBranches.push_back(br);
  TRACE(1, "SrcRec(%p)::chainFrom %p -> %p (type %d); %zd incoming branches\n",
        this,
        br.toSmash(), destAddr, static_cast<int>(br.type()),
        m_incomingBranches.size());
  br.patch(destAddr);

  if (RuntimeOption::EvalEnableReusableTC) {
    tc::recordJump(br.toSmash(), this);
  }
}
예제 #3
0
파일: tc-bind.cpp 프로젝트: MatmaRex/hhvm
TCA bindAddr(TCA toSmash, SrcKey destSk, TransFlags trflags, bool& smashed) {
  auto const sr = srcDB().find(destSk);
  always_assert(sr);
  auto const tDest = sr->getTopTranslation();
  if (tDest == nullptr) return nullptr;

  auto codeLock = lockCode();

  auto addr = reinterpret_cast<TCA*>(toSmash);
  if (*addr == tDest) {
    // Already smashed
    return tDest;
  }
  sr->chainFrom(IncomingBranch::addr(addr));
  smashed = true;
  return tDest;
}
예제 #4
0
파일: tc-bind.cpp 프로젝트: MatmaRex/hhvm
TCA bindJmp(TCA toSmash, SrcKey destSk, TransFlags trflags, bool& smashed) {
  auto const sr = srcDB().find(destSk);
  always_assert(sr);
  auto const tDest = sr->getTopTranslation();
  if (tDest == nullptr) return nullptr;

  auto codeLock = lockCode();

  auto const isJcc = [&] {
    switch (arch()) {
      case Arch::X64: {
        x64::DecodedInstruction di(toSmash);
        return (di.isBranch() && !di.isJmp());
      }

      case Arch::ARM: {
        auto instr = reinterpret_cast<vixl::Instruction*>(toSmash);
        return instr->IsCondBranchImm();
      }

      case Arch::PPC64:
        ppc64_asm::DecodedInstruction di(toSmash);
        return (di.isBranch() && !di.isJmp());
    }
    not_reached();
  }();

  if (isJcc) {
    auto const target = smashableJccTarget(toSmash);
    assertx(target);

    // Return if already smashed.
    if (target == tDest) return tDest;
    sr->chainFrom(IncomingBranch::jccFrom(toSmash));
  } else {
    auto const target = smashableJmpTarget(toSmash);
    assertx(target);

    // Return if already smashed.
    if (!target || target == tDest) return tDest;
    sr->chainFrom(IncomingBranch::jmpFrom(toSmash));
  }

  smashed = true;
  return tDest;
}