Esempio n. 1
0
bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name)
{
	u32 jitAddr = blocks.GetAddressFromBlockPtr(ptr);

	// Returns 0 when it's valid, but unknown.
	if (jitAddr == 0)
		name = "UnknownOrDeletedBlock";
	else if (jitAddr != (u32)-1)
	{
		char temp[1024];
		const std::string label = symbolMap.GetDescription(jitAddr);
		if (!label.empty())
			snprintf(temp, sizeof(temp), "%08x_%s", jitAddr, label.c_str());
		else
			snprintf(temp, sizeof(temp), "%08x", jitAddr);
		name = temp;
	}
	else if (asm_.IsInSpace(ptr))
		name = "RunLoopUntil";
	else if (thunks.IsInSpace(ptr))
		name = "Thunk";
	else if (safeMemFuncs.IsInSpace(ptr))
		name = "JitSafeMem";
	else if (IsInSpace(ptr))
		name = "Unknown";
	// Not anywhere in jit, then.
	else
		return false;

	// If we got here, one of the above cases matched.
	return true;
}
Esempio n. 2
0
bool Jitx86Base::BackPatch(u32 emAddress, SContext* ctx)
{
  u8* codePtr = reinterpret_cast<u8*>(ctx->CTX_PC);

  if (!IsInSpace(codePtr))
    return false;  // this will become a regular crash real soon after this

  auto it = m_back_patch_info.find(codePtr);
  if (it == m_back_patch_info.end())
  {
    PanicAlert("BackPatch: no register use entry for address %p", codePtr);
    return false;
  }

  TrampolineInfo& info = it->second;

  u8* exceptionHandler = nullptr;
  if (jo.memcheck)
  {
    auto it2 = m_exception_handler_at_loc.find(codePtr);
    if (it2 != m_exception_handler_at_loc.end())
      exceptionHandler = it2->second;
  }

  // In the trampoline code, we jump back into the block at the beginning
  // of the next instruction. The next instruction comes immediately
  // after the backpatched operation, or BACKPATCH_SIZE bytes after the start
  // of the backpatched operation, whichever comes last. (The JIT inserts NOPs
  // into the original code if necessary to ensure there is enough space
  // to insert the backpatch jump.)

  js.generatingTrampoline = true;
  js.trampolineExceptionHandler = exceptionHandler;

  // Generate the trampoline.
  const u8* trampoline = trampolines.GenerateTrampoline(info);
  js.generatingTrampoline = false;
  js.trampolineExceptionHandler = nullptr;

  u8* start = info.start;

  // Patch the original memory operation.
  XEmitter emitter(start);
  emitter.JMP(trampoline, true);
  // NOPs become dead code
  const u8* end = info.start + info.len;
  for (const u8* i = emitter.GetCodePtr(); i < end; ++i)
    emitter.INT3();

  // Rewind time to just before the start of the write block. If we swapped memory
  // before faulting (eg: the store+swap was not an atomic op like MOVBE), let's
  // swap it back so that the swap can happen again (this double swap isn't ideal but
  // only happens the first time we fault).
  if (info.nonAtomicSwapStoreSrc != Gen::INVALID_REG)
  {
    u64* ptr = ContextRN(ctx, info.nonAtomicSwapStoreSrc);
    switch (info.accessSize << 3)
    {
    case 8:
      // No need to swap a byte
      break;
    case 16:
      *ptr = Common::swap16(static_cast<u16>(*ptr));
      break;
    case 32:
      *ptr = Common::swap32(static_cast<u32>(*ptr));
      break;
    case 64:
      *ptr = Common::swap64(static_cast<u64>(*ptr));
      break;
    default:
      _dbg_assert_(DYNA_REC, 0);
      break;
    }
  }

  // This is special code to undo the LEA in SafeLoadToReg if it clobbered the address
  // register in the case where reg_value shared the same location as opAddress.
  if (info.offsetAddedToAddress)
  {
    u64* ptr = ContextRN(ctx, info.op_arg.GetSimpleReg());
    *ptr -= static_cast<u32>(info.offset);
  }

  ctx->CTX_PC = reinterpret_cast<u64>(trampoline);

  return true;
}
Esempio n. 3
0
void Client::Killed(Damage &fatal_blow) {
    DynamicSystemEntity::Killed(fatal_blow);


    if(GetShip()->typeID() == itemTypeCapsule) {
        //we have been pod killed... off we go.

        //TODO: destroy all implants

        //TODO: send them back to their clone.
        m_system->RemoveClient(this);
    } else {
        //our ship has been destroyed. Off to our capsule.
        //We are currently not keeping our real capsule around in the DB, so we need to make a new one.

        //m_system->bubbles.Remove(this, true);

        std::string capsule_name = GetName();
        capsule_name += "'s Capsule";
        ItemData idata(
            itemTypeCapsule,
            GetCharacterID(),
            GetLocationID(),
            flagAutoFit,
            capsule_name.c_str()
        );

        ShipRef capsule = m_services.item_factory.SpawnShip(idata);
        if( !capsule ) {
            codelog(CLIENT__ERROR, "Failed to create capsule for character '%s'", GetName());
            //what to do?
            return;
        }

        ShipRef dead_ship = GetShip();    //grab a ship ref to ensure that nobody else nukes it first.

        //ok, nothing can fail now, we need have our capsule, make the transition.

        //put the capsule where the ship was
        capsule->Relocate(dead_ship->position());

        //move it out of the way
        dead_ship->Move(this->GetLocationID(), (EVEItemFlags)flagNone, true );



        //this updates m_self and manages destiny updates as needed.
        BoardShip((ShipRef)capsule);

        m_shipId = capsule->itemID();
        if (IsInSpace())
            mSession.SetInt("shipid", capsule->itemID() );

        //This sends the RemoveBall for the old ship.




        //kill off the old ship.
        //TODO: figure out anybody else which may be referencing this ship...
        dead_ship->Delete();    //remove from the DB.


    }
}