@@ -427,14 +427,39 @@ analyze_object(struct dl_phdr_info *info, size_t size, void *data)
427427 patches -> base_addr = (unsigned char * )info -> dlpi_addr ;
428428 patches -> path = path ;
429429 find_syscalls (patches );
430- allocate_trampoline_table (patches );
431- create_patch_wrappers (patches );
432430
433431 return 0 ;
434432}
435433
436434const char * cmdline ;
437435
436+ static unsigned char asm_wrapper_space [0x100000 ];
437+ static unsigned char * next_asm_wrapper_space = asm_wrapper_space + PAGE_SIZE ;
438+
439+ static bool
440+ is_asm_wrapper_space_full (void )
441+ {
442+ return next_asm_wrapper_space + asm_wrapper_tmpl_size + 256 >
443+ asm_wrapper_space + sizeof (asm_wrapper_space );
444+ }
445+
446+ /*
447+ * mprotect_asm_wrappers
448+ * The code generated into the data segment at the asm_wrapper_space
449+ * array is not executable by default. This routine sets that memory region
450+ * to be executable, must called before attempting to execute any patched
451+ * syscall.
452+ */
453+ void
454+ mprotect_asm_wrappers (void )
455+ {
456+ mprotect_no_intercept (
457+ round_down_address (asm_wrapper_space + PAGE_SIZE ),
458+ sizeof (asm_wrapper_space ) - PAGE_SIZE ,
459+ PROT_READ | PROT_EXEC ,
460+ "mprotect_asm_wrappers PROT_READ | PROT_EXEC" );
461+ }
462+
438463/*
439464 * intercept - This is where the highest level logic of hotpatching
440465 * is described. Upon startup, this routine looks for libc, and libpthread.
@@ -467,6 +492,12 @@ intercept(int argc, char **argv)
467492 if (!libc_found )
468493 xabort ("libc not found" );
469494
495+ for (unsigned i = 0 ; i < objs_count ; ++ i ) {
496+ if (objs [i ].count > 0 && is_asm_wrapper_space_full ())
497+ xabort ("not enough space in asm_wrapper_space" );
498+ allocate_trampoline_table (objs + i );
499+ create_patch_wrappers (objs + i , & next_asm_wrapper_space );
500+ }
470501 mprotect_asm_wrappers ();
471502 for (unsigned i = 0 ; i < objs_count ; ++ i )
472503 activate_patches (objs + i );
0 commit comments