MCPcopy Create free account
hub / github.com/GJDuck/e9patch / patchJump

Function patchJump

src/e9patch/e9tactics.cpp:326–364  ·  view source on GitHub ↗

* Patch in a jmpq instruction. */

Source from the content-addressed store, hash-verified

324 * Patch in a jmpq instruction.
325 */
326static void patchJump(Patch *P, unsigned offset)
327{
328 assert(offset <= PATCH_MAX - JMP_SIZE);
329 assert(offset < P->I->size);
330 assert(P->A != nullptr);
331
332 intptr_t diff = (P->A->lb + P->A->entry) -
333 (P->I->addr + offset + JMP_SIZE);
334 assert(diff >= INT32_MIN && diff <= INT32_MAX);
335 int32_t rel32 = (int32_t)diff;
336
337 uint8_t *bytes = P->I->PATCH + offset,
338 *state = P->I->STATE + offset;
339 assert(*state == STATE_INSTRUCTION || *state == STATE_FREE);
340 *bytes++ = /*jmpq opcode=*/0xE9;
341 *state++ = STATE_PATCHED;
342 offset++;
343
344 const uint8_t *rel32p8 = (uint8_t *)&rel32;
345 unsigned i = 0;
346 for (; i < sizeof(rel32) && offset + i < P->I->size; i++)
347 {
348 assert(state[i] == STATE_INSTRUCTION || state[i] == STATE_FREE ||
349 (state[i] == STATE_PATCHED && bytes[i] == rel32p8[i]));
350 bytes[i] = rel32p8[i];
351 state[i] = STATE_PATCHED;
352 }
353 for (; i < sizeof(rel32); i++)
354 {
355 assert(state[i] != STATE_QUEUED);
356 if (state[i] == STATE_FREE)
357 {
358 bytes[i] = rel32p8[i];
359 state[i] = STATE_PATCHED;
360 }
361 else
362 state[i] |= STATE_LOCKED;
363 }
364}
365
366/*
367 * Patch in a short jmp instruction.

Callers 5

tactic_B1Function · 0.85
tactic_B2Function · 0.85
tactic_T1Function · 0.85
tactic_T3bFunction · 0.85
tactic_T3Function · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected