From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 21F8B384841E for ; Fri, 4 Jun 2021 15:28:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 21F8B384841E Received: from pps.filterd (m0187473.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 154F35iu004658 for ; Fri, 4 Jun 2021 11:28:20 -0400 Received: from ppma01dal.us.ibm.com (83.d6.3fa9.ip4.static.sl-reverse.com [169.63.214.131]) by mx0a-001b2d01.pphosted.com with ESMTP id 38yng3jsqe-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 04 Jun 2021 11:28:20 -0400 Received: from pps.filterd (ppma01dal.us.ibm.com [127.0.0.1]) by ppma01dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 154FCpQK024521 for ; Fri, 4 Jun 2021 15:28:19 GMT Received: from b01cxnp23032.gho.pok.ibm.com (b01cxnp23032.gho.pok.ibm.com [9.57.198.27]) by ppma01dal.us.ibm.com with ESMTP id 38ud8ada3c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 04 Jun 2021 15:28:19 +0000 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 154FSHCi11010488 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 4 Jun 2021 15:28:17 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2BA64B2065; Fri, 4 Jun 2021 15:28:17 +0000 (GMT) Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8425BB2064; Fri, 4 Jun 2021 15:28:16 +0000 (GMT) Received: from li-e362e14c-2378-11b2-a85c-87d605f3c641.ibm.com (unknown [9.163.15.250]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP; Fri, 4 Jun 2021 15:28:16 +0000 (GMT) Message-ID: <1984418036f52962c1436bafdcc720c8fa2ce699.camel@us.ibm.com> Subject: [PATCH] Add Power 10 PLT instruction patterns From: Carl Love To: gdb-patches@sourceware.org, Ulrich.Weigand@de.ibm.com Cc: cel@us.ibm.com, Pedro Franco de Carvalho , Rogerio Alves Date: Fri, 04 Jun 2021 08:28:15 -0700 Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.28.5 (3.28.5-14.el8) Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: y8u-2BR9u-JgEUzcKuqwHQicWNmIiG_j X-Proofpoint-GUID: y8u-2BR9u-JgEUzcKuqwHQicWNmIiG_j X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-06-04_08:2021-06-04, 2021-06-04 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 mlxlogscore=999 mlxscore=0 adultscore=0 impostorscore=0 spamscore=0 lowpriorityscore=0 malwarescore=0 suspectscore=0 bulkscore=0 priorityscore=1501 clxscore=1011 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2104190000 definitions=main-2106040112 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP 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, 04 Jun 2021 15:28:23 -0000 GDB maintainers: The following patch add the PLT patterns for Power 10. The patch has been tested on Power 10. The regression tests all pass. Additional manual testing has been done to verify the instruction sequences are correctly matched. Please take a look at the patch and let me know if it is acceptable to commit. Thanks. Carl Love --------------------------------------------------------- gdb/ChangeLog: 2021-06-06 Carl Love * ppc-tdep.h: New extern ppc_insn_prefix_dform. * ppc64-tdep.c: New defines prefix, insn_md, insn_x, insn_xo. New functions ppc64_plt_pcrel_entry_point, ppc64_pcrel_linkage1_target, ppc64_pcrel_linkage2_target. New ppc instruction patterns ppc64_standard_linkage9, ppc64_standard_linkage10, ppc64_standard_linkage11, ppc64_standard_linkage12. Add ppc64_standard_linkage9, ppc64_standard_linkage10, ppc64_standard_linkage11, ppc64_standard_linkage12 to define MAX expression. (ppc64_skip_trampoline_code_1): Add if statement checks for ppc64_standard_linkage9, ppc64_standard_linkage10, ppc64_standard_linkage11, ppc64_standard_linkage12. * New function ppc_insn_prefix_dform. --- gdb/ppc-tdep.h | 2 + gdb/ppc64-tdep.c | 194 +++++++++++++++++++++++++++++++++++++++++++++- gdb/rs6000-tdep.c | 8 ++ 3 files changed, 201 insertions(+), 3 deletions(-) diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index 77b6ab154f4..1e0754f7692 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -426,6 +426,8 @@ extern int ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc, extern CORE_ADDR ppc_insn_d_field (unsigned int insn); extern CORE_ADDR ppc_insn_ds_field (unsigned int insn); +extern CORE_ADDR ppc_insn_prefix_dform (unsigned int insn1, + unsigned int insn2); extern int ppc_process_record (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR addr); diff --git a/gdb/ppc64-tdep.c b/gdb/ppc64-tdep.c index 74873a6999e..1dd94f20ab6 100644 --- a/gdb/ppc64-tdep.c +++ b/gdb/ppc64-tdep.c @@ -49,6 +49,38 @@ | (((unsigned (spr)) & 0x3e0) << 6) \ | (((unsigned (xo)) & 0x3ff) << 1)) +#define prefix(a, b, R, do) \ + (((0x1) << 26) \ + | (((unsigned (a)) & 0x3) << 24) \ + | (((unsigned (b)) & 0x1) << 23) \ + | (((unsigned (R)) & 0x1) << 20) \ + | ((unsigned (do)) & 0x3ffff)) + +#define insn_md(opcd, ra, rs, sh, me, rc) \ + ((((unsigned (opcd)) & 0x3f) << 26) \ + | (((unsigned (rs)) & 0x1f) << 21) \ + | (((unsigned (ra)) & 0x1f) << 16) \ + | (((unsigned (sh)) & 0x3e) << 11) \ + | (((unsigned (me)) & 0x3f) << 25) \ + | (((unsigned (sh)) & 0x1) << 1) \ + | ((unsigned (rc)) & 0x1)) + +#define insn_x(opcd, rt, ra, rb, opc2) \ + ((((unsigned (opcd)) & 0x3f) << 26) \ + | (((unsigned (rt)) & 0x1f) << 21) \ + | (((unsigned (ra)) & 0x1f) << 16) \ + | (((unsigned (rb)) & 0x3e) << 11) \ + | (((unsigned (opc2)) & 0x3FF) << 1)) + +#define insn_xo(opcd, rt, ra, rb, oe, rc, opc2) \ + ((((unsigned (opcd)) & 0x3f) << 26) \ + | (((unsigned (rt)) & 0x1f) << 21) \ + | (((unsigned (ra)) & 0x1f) << 16) \ + | (((unsigned (rb)) & 0x3e) << 11) \ + | (((unsigned (oe)) & 0x1) << 10) \ + | (((unsigned (opc2)) & 0x1FF) << 1) \ + | (((unsigned (rc))))) + /* PLT_OFF is the TOC-relative offset of a 64-bit PowerPC PLT entry. Return the function's entry point. */ @@ -75,6 +107,18 @@ ppc64_plt_entry_point (struct frame_info *frame, CORE_ADDR plt_off) return read_memory_unsigned_integer (tocp + plt_off, 8, byte_order); } +static CORE_ADDR +ppc64_plt_pcrel_entry_point (struct frame_info *frame, CORE_ADDR plt_off, + CORE_ADDR pc) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + + /* Execution direction doesn't matter, entry is pc + plt_off either way. + The first word of the PLT entry is the function entry point. */ + return read_memory_unsigned_integer (pc + plt_off, 8, byte_order); +} + /* Patterns for the standard linkage functions. These are built by build_plt_stub in bfd/elf64-ppc.c. */ @@ -342,6 +386,110 @@ static const struct ppc_insn_pattern ppc64_standard_linkage8[] = { 0, 0, 0 } }; +/* Power 10 ELFv2 PLT call stubs */ +static const struct ppc_insn_pattern ppc64_standard_linkage9[] = + { + /* std %r2,0+40(%r1) */ + { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, + + /* pld r12, */ + { prefix (-1, -1, 1, 0), prefix (0, 0, 1, 0), 0 }, + { insn_d (-1, -1, -1, 0), insn_d (57, 12, 0, 0), 0 }, + + /* mtctr r12 */ + { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, + + /* bctr */ + { (unsigned) -1, 0x4e800420, 0 }, + + { 0, 0, 0 } + }; + +static const struct ppc_insn_pattern ppc64_standard_linkage10[] = + { + /* std %r2,0+40(%r1) */ + { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, + + /* paddi r12, */ + { prefix (-1, -1, 1, 0), prefix (2, 0, 1, 0), 0 }, + { insn_d (-1, -1, -1, 0), insn_d (14, 12, 0, 0), 0 }, + + /* mtctr r12 */ + { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, + + /* bctr */ + { (unsigned) -1, 0x4e800420, 0 }, + + { 0, 0, 0 } + }; + +static const struct ppc_insn_pattern ppc64_standard_linkage11[] = + { + /* std %r2,0+40(%r1) */ + { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, + + /* li %r11,0 */ + { insn_d (-1, -1, -1, 0), insn_d (14, 11, 0, 0), 1 }, + + /* sldi %r11,%r11,34 */ + { insn_md (-1, -1, -1, 0, 0, 1), insn_md (30, 11, 11, 34, 63-34, 0), 1 }, + + /* paddi r12, */ + { prefix (-1, -1, 1, 0), prefix (2, 0, 1, 0), 0 }, + { insn_d (-1, -1, -1, 0), insn_d (14, 12, 0, 0), 0 }, + + /* ldx %r12,%r11,%r12 */ + { (unsigned) -1, insn_x (31, 12, 11, 12, 21), 1 }, + + /* add %r12,%r11,%r12 */ + { (unsigned) -1, insn_xo (31, 12, 11, 12, 0, 0, 40), 1 }, + + /* mtctr r12 */ + { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, + + /* bctr */ // 13, 14, 15, 16 + { (unsigned) -1, 0x4e800420, 0 }, + + { 0, 0, 0 } + }; + +static const struct ppc_insn_pattern ppc64_standard_linkage12[] = + { + /* std %r2,0+40(%r1) */ + { insn_ds (-1, -1, -1, 0, 1), insn_ds (62, 2, 1, 40, 0), 1 }, + + /* lis %r11,xxx@ha */ + /* addis r12, r2, */ + { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 }, + + /* ori %r11,%r11,xxx@l */ + { insn_d (-1, -1, -1, 0), insn_d (24, 11, 11, 0), 0 }, + + /* sldi %r11,%r11,34 */ + { (unsigned) -1, insn_md (30, 11, 11, 34, 63-34, 0), 1 }, + + /*paddi r12, */ + { prefix (-1, -1, 1, 0), prefix (2, 0, 1, 0), 0 }, + { insn_d (-1, -1, -1, 0), insn_d (14, 12, 0, 0), 0 }, + + /* sldi %r11,%r11,34 */ + { (unsigned) -1, insn_md (30, 11, 11, 34, 63-34, 0), 1 }, + + /* ldx %r12,%r11,%r12 */ + { (unsigned) -1, insn_x (31, 12, 11, 12, 21), 1 }, + + /* add %r12,%r11,%r12 */ + { (unsigned) -1, insn_xo (31, 12, 11, 12, 0, 0, 40), 1 }, + + /* mtctr r12 */ + { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 }, + + /* bctr */ // 17, 18, 19, 20 + { (unsigned) -1, 0x4e800420, 0 }, + + { 0, 0, 0 } + }; + /* When the dynamic linker is doing lazy symbol resolution, the first call to a function in another object will go like this: @@ -432,6 +580,29 @@ ppc64_standard_linkage4_target (struct frame_info *frame, unsigned int *insn) return ppc64_plt_entry_point (frame, plt_off); } +static CORE_ADDR +ppc64_pcrel_linkage1_target (struct frame_info *frame, unsigned int *insn, + CORE_ADDR pc) +{ + /* insn[0] is for the std instruction. */ + CORE_ADDR plt_off = ppc_insn_prefix_dform (insn[1], insn[2]); + + return ppc64_plt_pcrel_entry_point (frame, plt_off, pc); +} + +static CORE_ADDR +ppc64_pcrel_linkage2_target (struct frame_info *frame, unsigned int *insn, + CORE_ADDR pc) +{ + CORE_ADDR plt_off; + + /* insn[0] is for the std instruction. + insn[1] is for the li r11 instruction */ + plt_off = ppc_insn_prefix_dform (insn[2], insn[3]); + + return ppc64_plt_pcrel_entry_point (frame, plt_off, pc); +} + /* Given that we've begun executing a call trampoline at PC, return the entry point of the function the trampoline will go to. @@ -447,10 +618,15 @@ ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc) ARRAY_SIZE (ppc64_standard_linkage2)), MAX (ARRAY_SIZE (ppc64_standard_linkage3), ARRAY_SIZE (ppc64_standard_linkage4))), - MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5), + MAX(MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5), ARRAY_SIZE (ppc64_standard_linkage6)), MAX (ARRAY_SIZE (ppc64_standard_linkage7), - ARRAY_SIZE (ppc64_standard_linkage8)))) + ARRAY_SIZE (ppc64_standard_linkage8))), + MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage9), + ARRAY_SIZE (ppc64_standard_linkage10)), + MAX (ARRAY_SIZE (ppc64_standard_linkage11), + ARRAY_SIZE (ppc64_standard_linkage12))))) + - 1]; CORE_ADDR target; int scan_limit, i; @@ -463,7 +639,19 @@ ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc) for (i = 0; i < scan_limit; i++) { - if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1 + if (i < ARRAY_SIZE (ppc64_standard_linkage12) - 1 + && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage12, insns)) + pc = ppc64_pcrel_linkage1_target (frame, insns, pc); + else if (i < ARRAY_SIZE (ppc64_standard_linkage11) - 1 + && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage11, insns)) + pc = ppc64_pcrel_linkage2_target (frame, insns, pc); + else if (i < ARRAY_SIZE (ppc64_standard_linkage10) - 1 + && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage10, insns)) + pc = ppc64_pcrel_linkage1_target (frame, insns, pc); + else if (i < ARRAY_SIZE (ppc64_standard_linkage9) - 1 + && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage9, insns)) + pc = ppc64_pcrel_linkage1_target (frame, insns, pc); + else if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns)) pc = ppc64_standard_linkage4_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1 diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 347014d6c2f..f05252a81b7 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -7368,6 +7368,14 @@ ppc_insn_ds_field (unsigned int insn) return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000); } +CORE_ADDR +ppc_insn_prefix_dform (unsigned int insn1, unsigned int insn2) +{ + /* result is 34-bits */ + return (CORE_ADDR) ((((insn1 & 0x3ffff) ^ 0x20000) - 0x20000) << 16) + | (CORE_ADDR)(insn2 & 0xffff); +} + /* Initialization code. */ void _initialize_rs6000_tdep (); -- 2.27.0