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

Function buildPrologue

src/e9patch/e9trampoline.cpp:296–340  ·  view source on GitHub ↗

* Build a trampoline prologue, which may include instructions before the * patched instruction. The trampoline prologue allows other instructions * to jump to the trampoline "early", without having to go back to the main * program. The code is similar to buildBreak(). */

Source from the content-addressed store, hash-verified

294 * program. The code is similar to buildBreak().
295 */
296static int buildPrologue(const Binary *B, const Instr *I,
297 intptr_t addr, BuildMode mode = BUILD_SIZE, Buffer *buf = nullptr)
298{
299 if (!option_Opeephole)
300 return 0;
301 const Instr *J = getTrampolinePrologueStart(B->Es, I);
302 if (J == nullptr || J == I)
303 return 0;
304
305 int r = 0;
306 unsigned start = (mode == BUILD_BYTES? buf->size(): 0);
307 std::vector<std::pair<const Instr *, intptr_t>> entries;
308 for (; J != I; J = J->next())
309 {
310 int len = 0;
311 switch (mode)
312 {
313 case BUILD_SIZE:
314 len = relocateInstr(J, INTPTR_MIN);
315 break;
316 case BUILD_BYTES:
317 {
318 uint8_t *bytes = buf->bytes();
319 intptr_t entry = addr;
320 len = relocateInstr(J, addr, buf);
321 if (len < 0)
322 {
323 buf->reset(start);
324 break;
325 }
326 saveJump(B, entry, bytes, len);
327 entries.push_back({J, entry});
328 }
329 }
330 if (len < 0)
331 return 0;
332 addr += len;
333 r += len;
334 }
335
336 for (const auto &entry: entries)
337 setTrampolineEntry(B->Es, entry.first, entry.second);
338
339 return r;
340}
341
342/*
343 * Calculate trampoline size.

Callers 2

flattenTrampolineFunction · 0.85

Calls 8

saveJumpFunction · 0.85
setTrampolineEntryFunction · 0.85
nextMethod · 0.80
bytesMethod · 0.80
resetMethod · 0.80
relocateInstrFunction · 0.70
sizeMethod · 0.45

Tested by

no test coverage detected