From patchwork Mon Jun 12 08:41:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 20920 Received: (qmail 70112 invoked by alias); 12 Jun 2017 08:42:08 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 70050 invoked by uid 89); 12 Jun 2017 08:42:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY autolearn=ham version=3.3.2 spammy=H*r:sk:static. X-HELO: mail-io0-f171.google.com Received: from mail-io0-f171.google.com (HELO mail-io0-f171.google.com) (209.85.223.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 12 Jun 2017 08:42:04 +0000 Received: by mail-io0-f171.google.com with SMTP id t87so32534759ioe.0 for ; Mon, 12 Jun 2017 01:42:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=wMoX5fpYCRHpmVT1d6HQE/TWBfJ3jfMFZcS80aEja44=; b=FcU91IcblY2JiahrlOUDkVFjgWMm+ZeAA1zcQ4xLR72Rq2jt7xQ3p+YpA3RVclRdHb tlLvN0W00E7maZqkWmG7aulmlCnl971ECnWLVHdvtAuvVS++HKYOQOIgh4qYzgi7wQrh huTPQszPygEmD8ar2Rgq7yzJjVDqsuDnWM1w0Da98mCQIO84RXkkf7Xq5QJCSrXoBbag n0i8UxYh+/giLhkWAVkXt/V9yv454ErDW4XcwkveAEE1dDWUF/+8U7FFvZVdO1Jk1VdE YwesQKJcihSRB63Ui623hTbjTpR0qdqabcJ4PlxXDvre9o+Zuj9N2HB+6XdRjSNXxxr8 qHVw== X-Gm-Message-State: AODbwcAIOtcHudtIcy9OYrveWnsk/ujN1EdkDqVF0QfgGmLUsd1XssSd /ea9ZVgWZEKdLvvI X-Received: by 10.107.14.76 with SMTP id 73mr18900968ioo.145.1497256927360; Mon, 12 Jun 2017 01:42:07 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (static.42.136.251.148.clients.your-server.de. [148.251.136.42]) by smtp.gmail.com with ESMTPSA id u4sm5280289itu.1.2017.06.12.01.42.06 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 12 Jun 2017 01:42:06 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 07/25] Lazily and dynamically create i386-linux target descriptions Date: Mon, 12 Jun 2017 09:41:38 +0100 Message-Id: <1497256916-4958-8-git-send-email-yao.qi@linaro.org> In-Reply-To: <1497256916-4958-1-git-send-email-yao.qi@linaro.org> References: <1497256916-4958-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes Instead of using pre-generated target descriptions, this patch changes GDB to lazily and dynamically create target descriptions according to the target hardware capability (xcr0 in i386). This support any combination of target features. This patch also adds a unit test to make sure dynamically generated tdesc are identical to these generated from xml files. gdb: 2017-04-27 Yao Qi * i386-linux-tdep.c (i386_linux_read_description): Generate target description if it doesn't exist. [GDB_SELF_TEST] (i386_linux_read_description_test): New unit test. (_initialize_i386_linux_tdep) [GDB_SELF_TEST]: Register unit test. --- gdb/features/i386/32bit-linux.c | 1 + gdb/features/i386/32bit-sse.c | 1 + gdb/i386-linux-tdep.c | 83 ++++++++++++++++++++++++----------------- gdb/target-descriptions.c | 11 ++++++ 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/gdb/features/i386/32bit-linux.c b/gdb/features/i386/32bit-linux.c index 3f7bfe7..ff90d40 100644 --- a/gdb/features/i386/32bit-linux.c +++ b/gdb/features/i386/32bit-linux.c @@ -11,6 +11,7 @@ create_feature_i386_32bit_linux (struct target_desc *result, long regnum) struct tdesc_feature *feature; feature = tdesc_create_feature (result, "org.gnu.gdb.i386.linux"); + regnum = 41; tdesc_create_reg (feature, "orig_eax", regnum++, 1, NULL, 32, "int"); return regnum; } diff --git a/gdb/features/i386/32bit-sse.c b/gdb/features/i386/32bit-sse.c index 9aa7d3e..08c3948 100644 --- a/gdb/features/i386/32bit-sse.c +++ b/gdb/features/i386/32bit-sse.c @@ -63,6 +63,7 @@ create_feature_i386_32bit_sse (struct target_desc *result, long regnum) tdesc_add_flag (type, 12, "PM"); tdesc_add_flag (type, 15, "FZ"); + regnum = 32; tdesc_create_reg (feature, "xmm0", regnum++, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "xmm1", regnum++, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "xmm2", regnum++, 1, NULL, 128, "vec128"); diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 1bc1a6f..5ca58a1 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -45,13 +45,14 @@ #include "record-full.h" #include "linux-record.h" -#include "features/i386/i386-linux.c" -#include "features/i386/i386-mmx-linux.c" -#include "features/i386/i386-mpx-linux.c" -#include "features/i386/i386-avx-mpx-linux.c" -#include "features/i386/i386-avx-linux.c" -#include "features/i386/i386-avx-avx512-linux.c" -#include "features/i386/i386-avx-mpx-avx512-pku-linux.c" + +#include "features/i386/32bit-core.c" +#include "features/i386/32bit-sse.c" +#include "features/i386/32bit-linux.c" +#include "features/i386/32bit-avx.c" +#include "features/i386/32bit-mpx.c" +#include "features/i386/32bit-avx512.c" +#include "features/i386/32bit-pkeys.c" /* Return non-zero, when the register is in the corresponding register group. Put the LINUX_ORIG_EAX register in the system group. */ @@ -681,27 +682,50 @@ i386_linux_core_read_xcr0 (bfd *abfd) const struct target_desc * i386_linux_read_description (uint64_t xcr0) { - switch ((xcr0 & X86_XSTATE_ALL_MASK)) + if (xcr0 == 0) + return NULL; + + static struct target_desc *i386_linux_tdescs \ + [2/*X87*/][2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; + struct target_desc **tdesc; + + tdesc = &i386_linux_tdescs[(xcr0 & X86_XSTATE_X87) ? 1 : 0] + [(xcr0 & X86_XSTATE_SSE) ? 1 : 0] + [(xcr0 & X86_XSTATE_AVX) ? 1 : 0] + [(xcr0 & X86_XSTATE_MPX) ? 1 : 0] + [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0] + [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; + + if (*tdesc == NULL) { - case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: - return tdesc_i386_avx_mpx_avx512_pku_linux; - case X86_XSTATE_AVX_AVX512_MASK: - return tdesc_i386_avx_avx512_linux; - case X86_XSTATE_MPX_MASK: - return tdesc_i386_mpx_linux; - case X86_XSTATE_AVX_MPX_MASK: - return tdesc_i386_avx_mpx_linux; - case X86_XSTATE_AVX_MASK: - return tdesc_i386_avx_linux; - case X86_XSTATE_SSE_MASK: - return tdesc_i386_linux; - case X86_XSTATE_X87_MASK: - return tdesc_i386_mmx_linux; - default: - break; + *tdesc = allocate_target_description (); + set_tdesc_architecture (*tdesc, bfd_scan_arch ("i386")); + set_tdesc_osabi (*tdesc, osabi_from_tdesc_string ("GNU/Linux")); + + long regnum = 0; + + if (xcr0 & X86_XSTATE_X87) + regnum = create_feature_i386_32bit_core (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_SSE) + regnum = create_feature_i386_32bit_sse (*tdesc, regnum); + + regnum = create_feature_i386_32bit_linux (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_AVX) + regnum = create_feature_i386_32bit_avx (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_MPX) + regnum = create_feature_i386_32bit_mpx (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_AVX512) + regnum = create_feature_i386_32bit_avx512 (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_PKRU) + regnum = create_feature_i386_32bit_pkeys (*tdesc, regnum); } - return NULL; + return *tdesc; } /* Get Linux/x86 target description from core dump. */ @@ -1092,13 +1116,4 @@ _initialize_i386_linux_tdep (void) { gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX, i386_linux_init_abi); - - /* Initialize the Linux target description. */ - initialize_tdesc_i386_linux (); - initialize_tdesc_i386_mmx_linux (); - initialize_tdesc_i386_avx_linux (); - initialize_tdesc_i386_mpx_linux (); - initialize_tdesc_i386_avx_mpx_linux (); - initialize_tdesc_i386_avx_avx512_linux (); - initialize_tdesc_i386_avx_mpx_avx512_pku_linux (); } diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index fceab5f..c0b716a 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -2100,6 +2100,12 @@ public: void visit (const tdesc_reg *reg) override { + if (reg->target_regnum > next_regnum) + { + printf_unfiltered (" regnum = %ld;\n", reg->target_regnum); + next_regnum = reg->target_regnum; + } + printf_unfiltered (" tdesc_create_reg (feature, \"%s\", regnum++, %d, ", reg->name, reg->save_restore); if (reg->group) @@ -2107,8 +2113,13 @@ public: else printf_unfiltered ("NULL, "); printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type); + + next_regnum++; } +private: + /* The register number to use for the next register we see. */ + int next_regnum = 0; }; static void