From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from hqnvemgate26.nvidia.com (hqnvemgate26.nvidia.com [216.228.121.65]) by sourceware.org (Postfix) with ESMTPS id 0CFA53942026 for ; Fri, 13 Mar 2020 00:59:15 +0000 (GMT) Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 12 Mar 2020 17:59:01 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Thu, 12 Mar 2020 17:59:14 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Thu, 12 Mar 2020 17:59:14 -0700 Received: from nvbus.nvidia.com (10.124.1.5) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 13 Mar 2020 00:59:14 +0000 From: Victor Collod To: CC: Victor Collod Subject: [PATCH] Add support for intel IBT Date: Thu, 12 Mar 2020 17:58:52 -0700 Message-ID: <20200313005852.14788-1-vcollod@nvidia.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL101.nvidia.com (172.20.187.10) To HQMAIL107.nvidia.com (172.20.187.13) X-Spam-Status: No, score=-27.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Mar 2020 00:59:17 -0000 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 * 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] =3D { 0x48, 0x89, 0xe5 }; static const gdb_byte mov_rsp_rbp_2[3] =3D { 0x48, 0x8b, 0xec }; + static const gdb_byte endbr64[4] =3D { 0xf3, 0x0f, 0x1e, 0xfa }; + /* Ditto for movl %esp, %ebp. */ static const gdb_byte mov_esp_ebp_1[2] =3D { 0x89, 0xe5 }; static const gdb_byte mov_esp_ebp_2[2] =3D { 0x8b, 0xec }; =20 - gdb_byte buf[3]; - gdb_byte op; + gdb_byte buf[4]; =20 if (current_pc <=3D pc) return current_pc; @@ -2390,43 +2391,54 @@ amd64_analyze_prologue (struct gdbarch *gdbarch, else pc =3D amd64_analyze_stack_align (pc, current_pc, cache); =20 - op =3D read_code_unsigned_integer (pc, 1, byte_order); - - if (op =3D=3D 0x55) /* pushq %rbp */ + /* Check for an IBT ENDBRANCH instruction */ + read_code (pc, buf, sizeof(endbr64)); + if (memcmp (buf, endbr64, sizeof(endbr64)) =3D=3D 0) { - /* Take into account that we've executed the `pushq %rbp' that - starts this instruction sequence. */ - cache->saved_regs[AMD64_RBP_REGNUM] =3D 0; - cache->sp_offset +=3D 8; - + pc +=3D sizeof(endbr64); /* If that's all, return now. */ - if (current_pc <=3D pc + 1) - return current_pc; + if (current_pc <=3D pc) + return current_pc; + } + + /* stop right now if there's no `pushq %rbp' */ + if (read_code_unsigned_integer (pc, 1, byte_order) !=3D 0x55) + return pc; + + /* Take into account that we've executed the `pushq %rbp' that + starts this instruction sequence. */ + cache->saved_regs[AMD64_RBP_REGNUM] =3D 0; + cache->sp_offset +=3D 8; + + pc +=3D 1; + + /* If that's all, return now. */ + if (current_pc <=3D pc) + return current_pc; =20 - read_code (pc + 1, buf, 3); + read_code (pc, buf, 3); =20 - /* Check for `movq %rsp, %rbp'. */ - if (memcmp (buf, mov_rsp_rbp_1, 3) =3D=3D 0 - || memcmp (buf, mov_rsp_rbp_2, 3) =3D=3D 0) + /* Check for `movq %rsp, %rbp'. */ + if (memcmp (buf, mov_rsp_rbp_1, 3) =3D=3D 0 + || memcmp (buf, mov_rsp_rbp_2, 3) =3D=3D 0) + { + pc +=3D 3; + /* OK, we actually have a frame. */ + cache->frameless_p =3D 0; + return pc; + } + + /* For X32, also check for `movq %esp, %ebp'. */ + if (gdbarch_ptr_bit (gdbarch) =3D=3D 32) + { + if (memcmp (buf, mov_esp_ebp_1, 2) =3D=3D 0 + || memcmp (buf, mov_esp_ebp_2, 2) =3D=3D 0) { + pc +=3D 2; /* OK, we actually have a frame. */ cache->frameless_p =3D 0; - return pc + 4; + return pc; } - - /* For X32, also check for `movq %esp, %ebp'. */ - if (gdbarch_ptr_bit (gdbarch) =3D=3D 32) - { - if (memcmp (buf, mov_esp_ebp_1, 2) =3D=3D 0 - || memcmp (buf, mov_esp_ebp_2, 2) =3D=3D 0) - { - /* OK, we actually have a frame. */ - cache->frameless_p =3D 0; - return pc + 3; - } - } - - return pc + 1; } =20 return pc; diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 19876c3553..0d1cee26fe 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -1537,6 +1537,24 @@ struct i386_insn i386_frame_setup_skip_insns[] =3D { 0 } }; =20 +/* Check whether PC points to an endbr32 instruction. */ +static CORE_ADDR +i386_skip_endbr(CORE_ADDR pc) +{ + static const gdb_byte endbr32[] =3D { 0xf3, 0x0f, 0x1e, 0xfb }; + + gdb_byte buf[sizeof(endbr32)]; + + /* Stop there if we can't read the code */ + if (target_read_code (pc, buf, sizeof(endbr32))) + return pc; + + /* If the instruction isn't an endbr32, stop */ + if (memcmp (buf, endbr32, sizeof(endbr32)) !=3D 0) + return pc; + + return pc + sizeof(endbr32); +} =20 /* Check whether PC points to a no-op instruction. */ static CORE_ADDR @@ -1814,6 +1832,7 @@ i386_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR current_pc, struct i386_frame_cache *cache) { + pc =3D i386_skip_endbr (pc); pc =3D i386_skip_noop (pc); pc =3D i386_follow_jump (gdbarch, pc); pc =3D i386_analyze_struct_return (pc, current_pc, cache); --=20 2.20.1