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

Function queueFlush

src/e9patch/e9api.cpp:57–109  ·  view source on GitHub ↗

* Flush the patching queue up to the new cursor. */

Source from the content-addressed store, hash-verified

55 * Flush the patching queue up to the new cursor.
56 */
57static void queueFlush(Binary *B, intptr_t cursor)
58{
59 if (B->cursor <= cursor)
60 error("failed to patch instruction at address 0x%lx; \"patch\" "
61 "messages were not send in reverse order", cursor);
62 B->cursor = cursor;
63
64 cursor += std::max(
65 T0_LIMIT * /*max instruction size=*/15,
66 /*max short jmp=*/ INT8_MAX + 2 + /*max instruction size=*/15) +
67 /*a bit extra=*/32;
68 while (!B->Q.empty() &&
69 (B->Q.back().options || B->Q.back().I->addr > cursor))
70 {
71 const auto &entry = B->Q.back();
72 if (!entry.options)
73 {
74 // Patch entry
75 Instr *I = entry.I;
76 const Trampoline *T = entry.T;
77 switch (I->STATE[0])
78 {
79 case STATE_QUEUED:
80 for (unsigned i = 0; i < I->size; i++)
81 {
82 assert(I->STATE[i] == STATE_QUEUED);
83 I->STATE[i] = STATE_INSTRUCTION;
84 }
85 I->debug = (option_trap_all ||
86 option_trap.find(I->addr) != option_trap.end());
87 if (patch(*B, I, T))
88 stat_num_patched++;
89 else
90 stat_num_failed++;
91 break;
92 default:
93 // For other states we assume T0 was applies:
94 stat_num_patched++;
95 stat_num_T0++;
96 log(COLOR_GREEN, '.');
97 break;
98 }
99 }
100 else
101 {
102 // Options entry
103 char * const *argv = entry.argv;
104 parseOptions(B, argv);
105 delete[] argv;
106 }
107 B->Q.pop_back();
108 }
109}
110
111/*
112 * Queue an instruction for patching.

Callers 2

queuePatchFunction · 0.85
parseEmitFunction · 0.85

Calls 7

errorFunction · 0.85
patchFunction · 0.85
logFunction · 0.85
backMethod · 0.80
parseOptionsFunction · 0.70
findMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected