On Mon, Nov 26, 2018 at 07:54:59AM -0600, Josh Poimboeuf wrote:

> +void static_call_bp_handler(void);
> +void *bp_handler_dest;
> +
> +asm(".pushsection .text, \"ax\"                                              
> \n"
> +    ".globl static_call_bp_handler                                   \n"
> +    ".type static_call_bp_handler, @function                         \n"
> +    "static_call_bp_handler:                                         \n"
> +    "ANNOTATE_RETPOLINE_SAFE                                         \n"
> +    "jmp *bp_handler_dest                                            \n"
> +    ".popsection                                                     \n");
> +
> +void arch_static_call_transform(void *site, void *tramp, void *func)
> +{
> +     s32 dest_relative;
> +     unsigned long insn;
> +     unsigned char insn_opcode;
> +     unsigned char opcodes[CALL_INSN_SIZE];
> +
> +     insn = (unsigned long)tramp;
> +
> +     mutex_lock(&text_mutex);
> +
> +     insn_opcode = *(unsigned char *)insn;
> +     if (insn_opcode != 0xe8 && insn_opcode != 0xe9) {
> +             WARN_ONCE(1, "unexpected static call insn opcode 0x%x at %pS",
> +                       insn_opcode, (void *)insn);
> +             goto done;
> +     }
> +
> +     dest_relative = (long)(func) - (long)(insn + CALL_INSN_SIZE);
> +
> +     opcodes[0] = insn_opcode;
> +     memcpy(&opcodes[1], &dest_relative, CALL_INSN_SIZE - 1);
> +
> +     /* Set up the variable for the breakpoint handler: */
> +     bp_handler_dest = func;
> +
> +     /* Patch the call site: */
> +     text_poke_bp((void *)insn, opcodes, CALL_INSN_SIZE,
> +                  static_call_bp_handler);

I'm confused by the whole static_call_bp_handler thing; why not jump
straight to @func ?

Also, what guarantees this other thread will have gotten from
static_call_bp_handler and executed the actual indirect JMP instruction
by the time we re-write @bp_handler_dest again?

> +done:
> +     mutex_unlock(&text_mutex);
> +}

Reply via email to