[PATCH] Add support for intel IBT

H.J. Lu hjl.tools@gmail.com
Fri Mar 13 01:29:18 GMT 2020


On Thu, Mar 12, 2020 at 5:59 PM Victor Collod via Gdb-patches
<gdb-patches@sourceware.org> wrote:
>
> Intel IBT adds a new instruction that is used to mark valid indirect
> jump targets. Some recent compilers add such instructions at the
> beginning of all functions.
>
> Without this patch, gdb does not properly skip the prologue of these
> functions, which makes it fail to print function arguments right after
> hitting a function breakpoint.
>
> 2020-03-12  Victor Collod  <vcollod@nvidia.com>
>
>         * i386-tdep.c (i386_skip_endbr): add a helper function to skip endbr
>         instructions.
>         (i386_analyze_prologue): call i386_skip_endbr.
>         * amd64-tdep.c (i386_analyze_prologue): skip endbr instructions.
> ---
>  gdb/amd64-tdep.c | 74 ++++++++++++++++++++++++++++--------------------
>  gdb/i386-tdep.c  | 19 +++++++++++++
>  2 files changed, 62 insertions(+), 31 deletions(-)
>
> diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
> index 5c56a970d8..bce6dcda47 100644
> --- a/gdb/amd64-tdep.c
> +++ b/gdb/amd64-tdep.c
> @@ -2375,12 +2375,13 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
>    /* There are two variations of movq %rsp, %rbp.  */
>    static const gdb_byte mov_rsp_rbp_1[3] = { 0x48, 0x89, 0xe5 };
>    static const gdb_byte mov_rsp_rbp_2[3] = { 0x48, 0x8b, 0xec };
> +  static const gdb_byte endbr64[4] = { 0xf3, 0x0f, 0x1e, 0xfa };
> +
>    /* Ditto for movl %esp, %ebp.  */
>    static const gdb_byte mov_esp_ebp_1[2] = { 0x89, 0xe5 };
>    static const gdb_byte mov_esp_ebp_2[2] = { 0x8b, 0xec };
>
> -  gdb_byte buf[3];
> -  gdb_byte op;
> +  gdb_byte buf[4];
>
>    if (current_pc <= pc)
>      return current_pc;
> @@ -2390,43 +2391,54 @@ amd64_analyze_prologue (struct gdbarch *gdbarch,
>    else
>      pc = amd64_analyze_stack_align (pc, current_pc, cache);
>
> -  op = read_code_unsigned_integer (pc, 1, byte_order);
> -
> -  if (op == 0x55)              /* pushq %rbp */
> +  /* Check for an IBT ENDBRANCH instruction */
> +  read_code (pc, buf, sizeof(endbr64));
> +  if (memcmp (buf, endbr64, sizeof(endbr64)) == 0)
>      {
> -      /* Take into account that we've executed the `pushq %rbp' that
> -         starts this instruction sequence.  */
> -      cache->saved_regs[AMD64_RBP_REGNUM] = 0;
> -      cache->sp_offset += 8;
> -
> +      pc += sizeof(endbr64);
>        /* If that's all, return now.  */
> -      if (current_pc <= pc + 1)
> -        return current_pc;
> +      if (current_pc <= pc)
> +       return current_pc;
> +    }
> +
> +  /* stop right now if there's no `pushq %rbp' */
> +  if (read_code_unsigned_integer (pc, 1, byte_order) != 0x55)
> +    return pc;
> +
> +  /* Take into account that we've executed the `pushq %rbp' that
> +     starts this instruction sequence.  */
> +  cache->saved_regs[AMD64_RBP_REGNUM] = 0;
> +  cache->sp_offset += 8;
> +
> +  pc += 1;
> +
> +  /* If that's all, return now.  */
> +  if (current_pc <= pc)
> +    return current_pc;
>
> -      read_code (pc + 1, buf, 3);
> +  read_code (pc, buf, 3);
>
> -      /* Check for `movq %rsp, %rbp'.  */
> -      if (memcmp (buf, mov_rsp_rbp_1, 3) == 0
> -         || memcmp (buf, mov_rsp_rbp_2, 3) == 0)
> +  /* Check for `movq %rsp, %rbp'.  */
> +  if (memcmp (buf, mov_rsp_rbp_1, 3) == 0
> +      || memcmp (buf, mov_rsp_rbp_2, 3) == 0)
> +    {
> +      pc += 3;
> +      /* OK, we actually have a frame.  */
> +      cache->frameless_p = 0;
> +      return pc;
> +    }
> +
> +  /* For X32, also check for `movq %esp, %ebp'.  */

It should be "movl %esp, %ebp", not movq.

> +  if (gdbarch_ptr_bit (gdbarch) == 32)
> +    {
> +      if (memcmp (buf, mov_esp_ebp_1, 2) == 0
> +         || memcmp (buf, mov_esp_ebp_2, 2) == 0)
>         {
> +         pc += 2;
>           /* OK, we actually have a frame.  */
>           cache->frameless_p = 0;
> -         return pc + 4;
> +         return pc;
>         }
> -
> -      /* For X32, also check for `movq %esp, %ebp'.  */
> -      if (gdbarch_ptr_bit (gdbarch) == 32)
> -       {
> -         if (memcmp (buf, mov_esp_ebp_1, 2) == 0
> -             || memcmp (buf, mov_esp_ebp_2, 2) == 0)
> -           {
> -             /* OK, we actually have a frame.  */
> -             cache->frameless_p = 0;
> -             return pc + 3;
> -           }
> -       }
> -
> -      return pc + 1;
>      }
>
>    return pc;



-- 
H.J.


More information about the Gdb-patches mailing list