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

Function emitRefactoredPatch

src/e9patch/e9elf.cpp:272–327  ·  view source on GitHub ↗

* Refactor out the patched pages & restore the original pages. * For some programs/libraries, it is difficult to ensure the loader is * run before the code segment is executed. This is especially difficult * with some advanced uses of the dynamic linker. This refactoring provides * a simple solution: have the loader also patch the code. */

Source from the content-addressed store, hash-verified

270 * a simple solution: have the loader also patch the code.
271 */
272static size_t emitRefactoredPatch(const uint8_t *original, uint8_t *data,
273 size_t size, size_t mapping_size, const InstrSet &Is,
274 RefactorSet &refactors)
275{
276 if (option_loader_static)
277 return 0;
278
279 assert(size % PAGE_SIZE == 0);
280
281 // Step #1: Find refactorings:
282 intptr_t curr_addr = INTPTR_MIN;
283 off_t curr_offset = -1;
284 size_t curr_size = 0;
285 for (off_t offset = 0; offset < (off_t)size; offset += PAGE_SIZE)
286 {
287 if (memcmp(original + offset, data + offset, PAGE_SIZE) == 0)
288 continue;
289 const Instr *I = Is.lower_bound(offset);
290 assert(I != nullptr);
291 intptr_t page_addr = I->addr - (I->addr % PAGE_SIZE);
292 off_t page_offset = I->offset - (I->offset % PAGE_SIZE);
293 assert(page_offset == offset);
294
295 if (curr_addr < 0 || page_addr < curr_addr ||
296 (intptr_t)(curr_addr + curr_size + mapping_size) < page_addr)
297 {
298 if (curr_addr >= 0)
299 {
300 Refactor r(curr_addr, curr_offset, curr_size);
301 refactors.push_back(r);
302 }
303 curr_addr = page_addr;
304 curr_offset = page_offset;
305 curr_size = PAGE_SIZE;
306 }
307 else
308 curr_size += (page_addr + PAGE_SIZE) - (curr_addr + curr_size);
309 }
310 if (curr_addr >= 0)
311 {
312 Refactor r(curr_addr, curr_offset, curr_size);
313 refactors.push_back(r);
314 }
315
316 // Step #2: Write out a copy of the patched pages & restore original pages:
317 size_t size_0 = size;
318 for (auto &r: refactors)
319 {
320 r.patched.offset = (off_t)size;
321 memcpy(data + size, data + r.original.offset, r.size);
322 memcpy(data + r.original.offset, original + r.original.offset, r.size);
323 size += r.size;
324 }
325
326 return size - size_0;
327}
328
329/*

Callers 1

emitElfFunction · 0.85

Calls 3

memcmpFunction · 0.85
memcpyFunction · 0.85
lower_boundMethod · 0.80

Tested by

no test coverage detected