From patchwork Wed Jan 20 17:37:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368205 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CC87C433E0 for ; Wed, 20 Jan 2021 19:21:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3EFE923403 for ; Wed, 20 Jan 2021 19:21:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390691AbhATSqf (ORCPT ); Wed, 20 Jan 2021 13:46:35 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:22477 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733264AbhATRjh (ORCPT ); Wed, 20 Jan 2021 12:39:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164288; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=veDG5mWnaW2Ixi8XXsaq9WVUVN6IJdn0R3qA8goBbxk=; b=B6555LsRqYWm5SinOKfSQlleULzeG6eSsesT8D2nze6+2fByiemUtK9mWKEmm125dHaxoJ x78ZbpZ8gTRHwWwPsKS+AXq9mLBghUnc9KYnvWMdSc7Mhy7e/TJjdncflGxhqoNMR+fMjp cU2v+9oS5UtKVrD539Y1F55jpSCOXBI= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-210-YudkiPCMOjmk3vUurLlSfg-1; Wed, 20 Jan 2021 12:38:06 -0500 X-MC-Unique: YudkiPCMOjmk3vUurLlSfg-1 Received: by mail-wr1-f71.google.com with SMTP id q18so11965932wrc.20 for ; Wed, 20 Jan 2021 09:38:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=veDG5mWnaW2Ixi8XXsaq9WVUVN6IJdn0R3qA8goBbxk=; b=novqXbASCDH0uKo19eSwRoNIzWFpK8w6StylYdvWUz1i7cdlnw9MJ3svJ1GHelRbCN 1YiETlRnreCfK6RyTstvwPYBmyjPLq5kwqkL5MGc6PRt3IJ0duw8pLKK+iq51n0aB76E HBzUx+3QQMFbcOE5bI+aB8bEcDQ72xM3X6lBKBeTKjdi17N8IZCn21E92sQcD8vAojJX fEBnTTlnFjqhOoskwLiZD5H3IpHOwtNP1iG5WDfkI0FiZOw9KFIBo2xp9J0YgeA9Pw2k w9z8mjeRsn5p4xYwhre1k/iyCludRp+cpYH7UW9S2ZPmD5S6lPPndiNOZqvufDmUuOIX o2iQ== X-Gm-Message-State: AOAM530g54HeWTvqGA2uXiADq9KHe3QGwtZhikaOVJ4Urjpi6jbiYAuv WDojJRNUBA4d69Ph2MonpfihFnPbz1nFFfHyc5LvYzqI38jVvUR+fIIffuhtuSUpcusLk74D9kh 7CwwhPeHiN6z1bzUSMqQq X-Received: by 2002:adf:e8c5:: with SMTP id k5mr10771814wrn.242.1611164285589; Wed, 20 Jan 2021 09:38:05 -0800 (PST) X-Google-Smtp-Source: ABdhPJylft7yf7rgmFXUNRqNfNmGJKkqmx1XjdDH0fdpJqZZDyViFfZloLRO9kL6mc2iiU5PzrlGuw== X-Received: by 2002:adf:e8c5:: with SMTP id k5mr10771802wrn.242.1611164285463; Wed, 20 Jan 2021 09:38:05 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:05 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 01/17] tools: Add some generic functions and headers Date: Wed, 20 Jan 2021 18:37:44 +0100 Message-Id: <20210120173800.1660730-2-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org These will be needed to be able to use arm64 instruction decoder in userland tools. Signed-off-by: Julien Thierry --- tools/include/asm-generic/bitops/__ffs.h | 11 +++++++ tools/include/linux/kernel.h | 21 +++++++++++++ tools/include/linux/printk.h | 40 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 tools/include/linux/printk.h diff --git a/tools/include/asm-generic/bitops/__ffs.h b/tools/include/asm-generic/bitops/__ffs.h index 9d1310519497..963f8a22212f 100644 --- a/tools/include/asm-generic/bitops/__ffs.h +++ b/tools/include/asm-generic/bitops/__ffs.h @@ -42,4 +42,15 @@ static __always_inline unsigned long __ffs(unsigned long word) return num; } +static inline unsigned long __ffs64(u64 word) +{ +#if BITS_PER_LONG == 32 + if (((u32)word) == 0UL) + return __ffs((u32)(word >> 32)) + 32; +#elif BITS_PER_LONG != 64 +#error BITS_PER_LONG not 32 or 64 +#endif + return __ffs((unsigned long)word); +} + #endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ */ diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h index a7e54a08fb54..e748982ed5c1 100644 --- a/tools/include/linux/kernel.h +++ b/tools/include/linux/kernel.h @@ -114,6 +114,27 @@ int scnprintf_pad(char * buf, size_t size, const char * fmt, ...); #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) #define round_down(x, y) ((x) & ~__round_mask(x, y)) +/** + * upper_32_bits - return bits 32-63 of a number + * @n: the number we're accessing + * + * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress + * the "right shift count >= width of type" warning when that quantity is + * 32-bits. + */ +#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) + +/** + * lower_32_bits - return bits 0-31 of a number + * @n: the number we're accessing + */ +#define lower_32_bits(n) ((u32)(n)) + +/* Inspired from ALIGN_*_KERNEL */ +#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define __ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1) +#define ALIGN_DOWN(x, a) __ALIGN((x) - ((a) - 1), (a)) + #define current_gfp_context(k) 0 #define synchronize_rcu() diff --git a/tools/include/linux/printk.h b/tools/include/linux/printk.h new file mode 100644 index 000000000000..515ebdc47e6e --- /dev/null +++ b/tools/include/linux/printk.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TOOLS_LINUX_KERNEL_PRINTK_H_ +#define _TOOLS_LINUX_KERNEL_PRINTK_H_ + +#include +#include +#include + +#define printk(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__) +#define pr_info printk +#define pr_notice printk +#define pr_cont printk + +#define pr_warn(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) +#define pr_err pr_warn +#define pr_alert pr_warn +#define pr_emerg pr_warn +#define pr_crit pr_warn + +/* + * Dummy printk for disabled debugging statements to use whilst maintaining + * gcc's format checking. + */ +#define no_printk(fmt, ...) \ +({ \ + if (0) \ + printk(fmt, ##__VA_ARGS__); \ + 0; \ +}) + +/* pr_devel() should produce zero code unless DEBUG is defined */ +#ifdef DEBUG +#define pr_devel(fmt, ...) printk +#else +#define pr_devel(fmt, ...) no_printk +#endif + +#define pr_debug pr_devel + +#endif /* _TOOLS_LINUX_KERNEL_PRINTK_H_ */ From patchwork Wed Jan 20 17:37:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368204 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB9B1C4332D for ; Wed, 20 Jan 2021 19:21:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AAC31233EB for ; Wed, 20 Jan 2021 19:21:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387459AbhATSqq (ORCPT ); Wed, 20 Jan 2021 13:46:46 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:34234 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387456AbhATRjn (ORCPT ); Wed, 20 Jan 2021 12:39:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164293; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WFCoVUxAnYPUNbFxrMojN9lSkyVQsjb562sLib5P5o4=; b=aFy0+cxpSnStnkQNIOtFkIdzeVyP9lKoXLQ/T0H0zLHNTZhdy/i8tGHur/04UqiXe/rA5E dXlOm4McAp4/J1TGfBZlmdFaM8oKLu9X2neem7qyuULIAT9Rpo27zMB/QhlQPTF2oAZ6Gh O+8V65XZI3H5F9VL3i5Kmxeq9vMh8kQ= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-352-hi3HzM8KPR2VqmRHz0S4nQ-1; Wed, 20 Jan 2021 12:38:11 -0500 X-MC-Unique: hi3HzM8KPR2VqmRHz0S4nQ-1 Received: by mail-wr1-f72.google.com with SMTP id u3so11851383wri.19 for ; Wed, 20 Jan 2021 09:38:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WFCoVUxAnYPUNbFxrMojN9lSkyVQsjb562sLib5P5o4=; b=pnlCYqKI5fmC6p526DIL96Evt3STdbZRIfS3nML0LxrUGDJCJp0bT0RdYHpEdnFLQG vz7hYzEW12ZnffDH3wvPDA1iegpSqzOHK/7NcoaurjrY43hnk6YcbyAx3wfBp8YgRR0d yY20ULkrjQgcRSbwSosVWfvfhoUjKT9nWaW0ZImuuR1X4b/D2/oxZNz+rYNkQZC53V62 iJCs+OH+j2Gtedghml9H18SSlWh7L93UbLa2LYFokSAsPDzTp0N8q+c74ZpjU8nGORMd GOru+NduZbwYreqMMSaMmqufQuXsdYmDEJm8FWGvHYf6RkYphTfFSRitZg0+egATY+03 vJ9A== X-Gm-Message-State: AOAM533368ZDxJjji+bGePuL5ntJ6zLOgJ/7pORtVtIBzoA9rcb+1ztA HguKwLtvpDmXbLBUcbrORBwgCnN60LnSXzIWBUtnchi0rdvRbfRJIKhNwZZ4i8XuM2Z1zgxVYRq fRs2wXqJ5WkyAPG5+jrSl X-Received: by 2002:a1c:9dd5:: with SMTP id g204mr5385316wme.37.1611164287757; Wed, 20 Jan 2021 09:38:07 -0800 (PST) X-Google-Smtp-Source: ABdhPJyFcQjLZgQlfx/Gxteu2z+WZsolDHkKC2oh+bNRsmmqRychWL2Ss/Wc1nTRmYHnMx9UmfyrFw== X-Received: by 2002:a1c:9dd5:: with SMTP id g204mr5385278wme.37.1611164287275; Wed, 20 Jan 2021 09:38:07 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:06 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 02/17] tools: arm64: Make aarch64 instruction decoder available to tools Date: Wed, 20 Jan 2021 18:37:45 +0100 Message-Id: <20210120173800.1660730-3-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Add aarch64 encoder/decoder implementation under tools/ as well as the necessary arm64 headers. Signed-off-by: Julien Thierry --- tools/arch/arm64/include/asm/aarch64-insn.h | 551 +++++++ tools/arch/arm64/lib/aarch64-insn.c | 1425 +++++++++++++++++++ 2 files changed, 1976 insertions(+) create mode 100644 tools/arch/arm64/include/asm/aarch64-insn.h create mode 100644 tools/arch/arm64/lib/aarch64-insn.c diff --git a/tools/arch/arm64/include/asm/aarch64-insn.h b/tools/arch/arm64/include/asm/aarch64-insn.h new file mode 100644 index 000000000000..b202d6e2e47e --- /dev/null +++ b/tools/arch/arm64/include/asm/aarch64-insn.h @@ -0,0 +1,551 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ASM_AARCH64_INSN_H +#define __ASM_AARCH64_INSN_H + +#include +#include + + +/* A64 instructions are always 32 bits. */ +#define AARCH64_INSN_SIZE 4 + +/* + * BRK instruction encoding + * The #imm16 value should be placed at bits[20:5] within BRK ins + */ +#define AARCH64_BREAK_MON 0xd4200000 + +/* + * BRK instruction for provoking a fault on purpose + * Unlike kgdb, #imm16 value with unallocated handler is used for faulting. + */ +#define AARCH64_BREAK_FAULT (AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5)) + +#ifndef __ASSEMBLY__ +/* + * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a + * Section C3.1 "A64 instruction index by encoding": + * AArch64 main encoding table + * Bit position + * 28 27 26 25 Encoding Group + * 0 0 - - Unallocated + * 1 0 0 - Data processing, immediate + * 1 0 1 - Branch, exception generation and system instructions + * - 1 - 0 Loads and stores + * - 1 0 1 Data processing - register + * 0 1 1 1 Data processing - SIMD and floating point + * 1 1 1 1 Data processing - SIMD and floating point + * "-" means "don't care" + */ +enum aarch64_insn_encoding_class { + AARCH64_INSN_CLS_UNKNOWN, /* UNALLOCATED */ + AARCH64_INSN_CLS_SVE, /* SVE instructions */ + AARCH64_INSN_CLS_DP_IMM, /* Data processing - immediate */ + AARCH64_INSN_CLS_DP_REG, /* Data processing - register */ + AARCH64_INSN_CLS_DP_FPSIMD, /* Data processing - SIMD and FP */ + AARCH64_INSN_CLS_LDST, /* Loads and stores */ + AARCH64_INSN_CLS_BR_SYS, /* Branch, exception generation and + * system instructions */ +}; + +enum aarch64_insn_hint_cr_op { + AARCH64_INSN_HINT_NOP = 0x0 << 5, + AARCH64_INSN_HINT_YIELD = 0x1 << 5, + AARCH64_INSN_HINT_WFE = 0x2 << 5, + AARCH64_INSN_HINT_WFI = 0x3 << 5, + AARCH64_INSN_HINT_SEV = 0x4 << 5, + AARCH64_INSN_HINT_SEVL = 0x5 << 5, + + AARCH64_INSN_HINT_XPACLRI = 0x07 << 5, + AARCH64_INSN_HINT_PACIA_1716 = 0x08 << 5, + AARCH64_INSN_HINT_PACIB_1716 = 0x0A << 5, + AARCH64_INSN_HINT_AUTIA_1716 = 0x0C << 5, + AARCH64_INSN_HINT_AUTIB_1716 = 0x0E << 5, + AARCH64_INSN_HINT_PACIAZ = 0x18 << 5, + AARCH64_INSN_HINT_PACIASP = 0x19 << 5, + AARCH64_INSN_HINT_PACIBZ = 0x1A << 5, + AARCH64_INSN_HINT_PACIBSP = 0x1B << 5, + AARCH64_INSN_HINT_AUTIAZ = 0x1C << 5, + AARCH64_INSN_HINT_AUTIASP = 0x1D << 5, + AARCH64_INSN_HINT_AUTIBZ = 0x1E << 5, + AARCH64_INSN_HINT_AUTIBSP = 0x1F << 5, + + AARCH64_INSN_HINT_ESB = 0x10 << 5, + AARCH64_INSN_HINT_PSB = 0x11 << 5, + AARCH64_INSN_HINT_TSB = 0x12 << 5, + AARCH64_INSN_HINT_CSDB = 0x14 << 5, + + AARCH64_INSN_HINT_BTI = 0x20 << 5, + AARCH64_INSN_HINT_BTIC = 0x22 << 5, + AARCH64_INSN_HINT_BTIJ = 0x24 << 5, + AARCH64_INSN_HINT_BTIJC = 0x26 << 5, +}; + +enum aarch64_insn_imm_type { + AARCH64_INSN_IMM_ADR, + AARCH64_INSN_IMM_26, + AARCH64_INSN_IMM_19, + AARCH64_INSN_IMM_16, + AARCH64_INSN_IMM_14, + AARCH64_INSN_IMM_12, + AARCH64_INSN_IMM_9, + AARCH64_INSN_IMM_7, + AARCH64_INSN_IMM_6, + AARCH64_INSN_IMM_S, + AARCH64_INSN_IMM_R, + AARCH64_INSN_IMM_N, + AARCH64_INSN_IMM_MAX +}; + +enum aarch64_insn_register_type { + AARCH64_INSN_REGTYPE_RT, + AARCH64_INSN_REGTYPE_RN, + AARCH64_INSN_REGTYPE_RT2, + AARCH64_INSN_REGTYPE_RM, + AARCH64_INSN_REGTYPE_RD, + AARCH64_INSN_REGTYPE_RA, + AARCH64_INSN_REGTYPE_RS, +}; + +enum aarch64_insn_register { + AARCH64_INSN_REG_0 = 0, + AARCH64_INSN_REG_1 = 1, + AARCH64_INSN_REG_2 = 2, + AARCH64_INSN_REG_3 = 3, + AARCH64_INSN_REG_4 = 4, + AARCH64_INSN_REG_5 = 5, + AARCH64_INSN_REG_6 = 6, + AARCH64_INSN_REG_7 = 7, + AARCH64_INSN_REG_8 = 8, + AARCH64_INSN_REG_9 = 9, + AARCH64_INSN_REG_10 = 10, + AARCH64_INSN_REG_11 = 11, + AARCH64_INSN_REG_12 = 12, + AARCH64_INSN_REG_13 = 13, + AARCH64_INSN_REG_14 = 14, + AARCH64_INSN_REG_15 = 15, + AARCH64_INSN_REG_16 = 16, + AARCH64_INSN_REG_17 = 17, + AARCH64_INSN_REG_18 = 18, + AARCH64_INSN_REG_19 = 19, + AARCH64_INSN_REG_20 = 20, + AARCH64_INSN_REG_21 = 21, + AARCH64_INSN_REG_22 = 22, + AARCH64_INSN_REG_23 = 23, + AARCH64_INSN_REG_24 = 24, + AARCH64_INSN_REG_25 = 25, + AARCH64_INSN_REG_26 = 26, + AARCH64_INSN_REG_27 = 27, + AARCH64_INSN_REG_28 = 28, + AARCH64_INSN_REG_29 = 29, + AARCH64_INSN_REG_FP = 29, /* Frame pointer */ + AARCH64_INSN_REG_30 = 30, + AARCH64_INSN_REG_LR = 30, /* Link register */ + AARCH64_INSN_REG_ZR = 31, /* Zero: as source register */ + AARCH64_INSN_REG_SP = 31 /* Stack pointer: as load/store base reg */ +}; + +enum aarch64_insn_special_register { + AARCH64_INSN_SPCLREG_SPSR_EL1 = 0xC200, + AARCH64_INSN_SPCLREG_ELR_EL1 = 0xC201, + AARCH64_INSN_SPCLREG_SP_EL0 = 0xC208, + AARCH64_INSN_SPCLREG_SPSEL = 0xC210, + AARCH64_INSN_SPCLREG_CURRENTEL = 0xC212, + AARCH64_INSN_SPCLREG_DAIF = 0xDA11, + AARCH64_INSN_SPCLREG_NZCV = 0xDA10, + AARCH64_INSN_SPCLREG_FPCR = 0xDA20, + AARCH64_INSN_SPCLREG_DSPSR_EL0 = 0xDA28, + AARCH64_INSN_SPCLREG_DLR_EL0 = 0xDA29, + AARCH64_INSN_SPCLREG_SPSR_EL2 = 0xE200, + AARCH64_INSN_SPCLREG_ELR_EL2 = 0xE201, + AARCH64_INSN_SPCLREG_SP_EL1 = 0xE208, + AARCH64_INSN_SPCLREG_SPSR_INQ = 0xE218, + AARCH64_INSN_SPCLREG_SPSR_ABT = 0xE219, + AARCH64_INSN_SPCLREG_SPSR_UND = 0xE21A, + AARCH64_INSN_SPCLREG_SPSR_FIQ = 0xE21B, + AARCH64_INSN_SPCLREG_SPSR_EL3 = 0xF200, + AARCH64_INSN_SPCLREG_ELR_EL3 = 0xF201, + AARCH64_INSN_SPCLREG_SP_EL2 = 0xF210 +}; + +enum aarch64_insn_variant { + AARCH64_INSN_VARIANT_32BIT, + AARCH64_INSN_VARIANT_64BIT +}; + +enum aarch64_insn_condition { + AARCH64_INSN_COND_EQ = 0x0, /* == */ + AARCH64_INSN_COND_NE = 0x1, /* != */ + AARCH64_INSN_COND_CS = 0x2, /* unsigned >= */ + AARCH64_INSN_COND_CC = 0x3, /* unsigned < */ + AARCH64_INSN_COND_MI = 0x4, /* < 0 */ + AARCH64_INSN_COND_PL = 0x5, /* >= 0 */ + AARCH64_INSN_COND_VS = 0x6, /* overflow */ + AARCH64_INSN_COND_VC = 0x7, /* no overflow */ + AARCH64_INSN_COND_HI = 0x8, /* unsigned > */ + AARCH64_INSN_COND_LS = 0x9, /* unsigned <= */ + AARCH64_INSN_COND_GE = 0xa, /* signed >= */ + AARCH64_INSN_COND_LT = 0xb, /* signed < */ + AARCH64_INSN_COND_GT = 0xc, /* signed > */ + AARCH64_INSN_COND_LE = 0xd, /* signed <= */ + AARCH64_INSN_COND_AL = 0xe, /* always */ +}; + +enum aarch64_insn_branch_type { + AARCH64_INSN_BRANCH_NOLINK, + AARCH64_INSN_BRANCH_LINK, + AARCH64_INSN_BRANCH_RETURN, + AARCH64_INSN_BRANCH_COMP_ZERO, + AARCH64_INSN_BRANCH_COMP_NONZERO, +}; + +enum aarch64_insn_size_type { + AARCH64_INSN_SIZE_8, + AARCH64_INSN_SIZE_16, + AARCH64_INSN_SIZE_32, + AARCH64_INSN_SIZE_64, +}; + +enum aarch64_insn_ldst_type { + AARCH64_INSN_LDST_LOAD_REG_OFFSET, + AARCH64_INSN_LDST_STORE_REG_OFFSET, + AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX, + AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX, + AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX, + AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX, + AARCH64_INSN_LDST_LOAD_EX, + AARCH64_INSN_LDST_STORE_EX, +}; + +enum aarch64_insn_adsb_type { + AARCH64_INSN_ADSB_ADD, + AARCH64_INSN_ADSB_SUB, + AARCH64_INSN_ADSB_ADD_SETFLAGS, + AARCH64_INSN_ADSB_SUB_SETFLAGS +}; + +enum aarch64_insn_movewide_type { + AARCH64_INSN_MOVEWIDE_ZERO, + AARCH64_INSN_MOVEWIDE_KEEP, + AARCH64_INSN_MOVEWIDE_INVERSE +}; + +enum aarch64_insn_bitfield_type { + AARCH64_INSN_BITFIELD_MOVE, + AARCH64_INSN_BITFIELD_MOVE_UNSIGNED, + AARCH64_INSN_BITFIELD_MOVE_SIGNED +}; + +enum aarch64_insn_data1_type { + AARCH64_INSN_DATA1_REVERSE_16, + AARCH64_INSN_DATA1_REVERSE_32, + AARCH64_INSN_DATA1_REVERSE_64, +}; + +enum aarch64_insn_data2_type { + AARCH64_INSN_DATA2_UDIV, + AARCH64_INSN_DATA2_SDIV, + AARCH64_INSN_DATA2_LSLV, + AARCH64_INSN_DATA2_LSRV, + AARCH64_INSN_DATA2_ASRV, + AARCH64_INSN_DATA2_RORV, +}; + +enum aarch64_insn_data3_type { + AARCH64_INSN_DATA3_MADD, + AARCH64_INSN_DATA3_MSUB, +}; + +enum aarch64_insn_logic_type { + AARCH64_INSN_LOGIC_AND, + AARCH64_INSN_LOGIC_BIC, + AARCH64_INSN_LOGIC_ORR, + AARCH64_INSN_LOGIC_ORN, + AARCH64_INSN_LOGIC_EOR, + AARCH64_INSN_LOGIC_EON, + AARCH64_INSN_LOGIC_AND_SETFLAGS, + AARCH64_INSN_LOGIC_BIC_SETFLAGS +}; + +enum aarch64_insn_prfm_type { + AARCH64_INSN_PRFM_TYPE_PLD, + AARCH64_INSN_PRFM_TYPE_PLI, + AARCH64_INSN_PRFM_TYPE_PST, +}; + +enum aarch64_insn_prfm_target { + AARCH64_INSN_PRFM_TARGET_L1, + AARCH64_INSN_PRFM_TARGET_L2, + AARCH64_INSN_PRFM_TARGET_L3, +}; + +enum aarch64_insn_prfm_policy { + AARCH64_INSN_PRFM_POLICY_KEEP, + AARCH64_INSN_PRFM_POLICY_STRM, +}; + +enum aarch64_insn_adr_type { + AARCH64_INSN_ADR_TYPE_ADRP, + AARCH64_INSN_ADR_TYPE_ADR, +}; + +#define __AARCH64_INSN_FUNCS(abbr, mask, val) \ +static __always_inline bool aarch64_insn_is_##abbr(u32 code) \ +{ \ + BUILD_BUG_ON(~(mask) & (val)); \ + return (code & (mask)) == (val); \ +} \ +static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \ +{ \ + return (val); \ +} + +__AARCH64_INSN_FUNCS(adr, 0x9F000000, 0x10000000) +__AARCH64_INSN_FUNCS(adrp, 0x9F000000, 0x90000000) +__AARCH64_INSN_FUNCS(prfm, 0x3FC00000, 0x39800000) +__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000) +__AARCH64_INSN_FUNCS(store_imm, 0x3FC00000, 0x39000000) +__AARCH64_INSN_FUNCS(load_imm, 0x3FC00000, 0x39400000) +__AARCH64_INSN_FUNCS(store_pre, 0x3FE00C00, 0x38000C00) +__AARCH64_INSN_FUNCS(load_pre, 0x3FE00C00, 0x38400C00) +__AARCH64_INSN_FUNCS(store_post, 0x3FE00C00, 0x38000400) +__AARCH64_INSN_FUNCS(load_post, 0x3FE00C00, 0x38400400) +__AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) +__AARCH64_INSN_FUNCS(ldadd, 0x3F20FC00, 0x38200000) +__AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) +__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000) +__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000) +__AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000) +__AARCH64_INSN_FUNCS(load_ex, 0x3F400000, 0x08400000) +__AARCH64_INSN_FUNCS(store_ex, 0x3F400000, 0x08000000) +__AARCH64_INSN_FUNCS(stp, 0x7FC00000, 0x29000000) +__AARCH64_INSN_FUNCS(ldp, 0x7FC00000, 0x29400000) +__AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000) +__AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000) +__AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000) +__AARCH64_INSN_FUNCS(ldp_pre, 0x7FC00000, 0x29C00000) +__AARCH64_INSN_FUNCS(add_imm, 0x7F000000, 0x11000000) +__AARCH64_INSN_FUNCS(adds_imm, 0x7F000000, 0x31000000) +__AARCH64_INSN_FUNCS(sub_imm, 0x7F000000, 0x51000000) +__AARCH64_INSN_FUNCS(subs_imm, 0x7F000000, 0x71000000) +__AARCH64_INSN_FUNCS(movn, 0x7F800000, 0x12800000) +__AARCH64_INSN_FUNCS(sbfm, 0x7F800000, 0x13000000) +__AARCH64_INSN_FUNCS(bfm, 0x7F800000, 0x33000000) +__AARCH64_INSN_FUNCS(movz, 0x7F800000, 0x52800000) +__AARCH64_INSN_FUNCS(ubfm, 0x7F800000, 0x53000000) +__AARCH64_INSN_FUNCS(movk, 0x7F800000, 0x72800000) +__AARCH64_INSN_FUNCS(add, 0x7F200000, 0x0B000000) +__AARCH64_INSN_FUNCS(adds, 0x7F200000, 0x2B000000) +__AARCH64_INSN_FUNCS(sub, 0x7F200000, 0x4B000000) +__AARCH64_INSN_FUNCS(subs, 0x7F200000, 0x6B000000) +__AARCH64_INSN_FUNCS(madd, 0x7FE08000, 0x1B000000) +__AARCH64_INSN_FUNCS(msub, 0x7FE08000, 0x1B008000) +__AARCH64_INSN_FUNCS(udiv, 0x7FE0FC00, 0x1AC00800) +__AARCH64_INSN_FUNCS(sdiv, 0x7FE0FC00, 0x1AC00C00) +__AARCH64_INSN_FUNCS(lslv, 0x7FE0FC00, 0x1AC02000) +__AARCH64_INSN_FUNCS(lsrv, 0x7FE0FC00, 0x1AC02400) +__AARCH64_INSN_FUNCS(asrv, 0x7FE0FC00, 0x1AC02800) +__AARCH64_INSN_FUNCS(rorv, 0x7FE0FC00, 0x1AC02C00) +__AARCH64_INSN_FUNCS(rev16, 0x7FFFFC00, 0x5AC00400) +__AARCH64_INSN_FUNCS(rev32, 0x7FFFFC00, 0x5AC00800) +__AARCH64_INSN_FUNCS(rev64, 0x7FFFFC00, 0x5AC00C00) +__AARCH64_INSN_FUNCS(and, 0x7F200000, 0x0A000000) +__AARCH64_INSN_FUNCS(bic, 0x7F200000, 0x0A200000) +__AARCH64_INSN_FUNCS(orr, 0x7F200000, 0x2A000000) +__AARCH64_INSN_FUNCS(mov_reg, 0x7FE0FFE0, 0x2A0003E0) +__AARCH64_INSN_FUNCS(orn, 0x7F200000, 0x2A200000) +__AARCH64_INSN_FUNCS(eor, 0x7F200000, 0x4A000000) +__AARCH64_INSN_FUNCS(eon, 0x7F200000, 0x4A200000) +__AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000) +__AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000) +__AARCH64_INSN_FUNCS(and_imm, 0x7F800000, 0x12000000) +__AARCH64_INSN_FUNCS(orr_imm, 0x7F800000, 0x32000000) +__AARCH64_INSN_FUNCS(eor_imm, 0x7F800000, 0x52000000) +__AARCH64_INSN_FUNCS(ands_imm, 0x7F800000, 0x72000000) +__AARCH64_INSN_FUNCS(extr, 0x7FA00000, 0x13800000) +__AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000) +__AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000) +__AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000) +__AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000) +__AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000) +__AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000) +__AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000) +__AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) +__AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) +__AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003) +__AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000) +__AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000) +__AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) +__AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) +__AARCH64_INSN_FUNCS(br_auth, 0xFEFFF800, 0xD61F0800) +__AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) +__AARCH64_INSN_FUNCS(blr_auth, 0xFEFFF800, 0xD63F0800) +__AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) +__AARCH64_INSN_FUNCS(ret_auth, 0xFFFFFBFF, 0xD65F0BFF) +__AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F03E0) +__AARCH64_INSN_FUNCS(eret_auth, 0xFFFFFBFF, 0xD69F0BFF) +__AARCH64_INSN_FUNCS(mrs, 0xFFF00000, 0xD5300000) +__AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F) +__AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000) +__AARCH64_INSN_FUNCS(dmb, 0xFFFFF0FF, 0xD50330BF) +__AARCH64_INSN_FUNCS(dsb, 0xFFFFF0FF, 0xD503309F) +__AARCH64_INSN_FUNCS(isb, 0xFFFFF0FF, 0xD50330DF) + +#undef __AARCH64_INSN_FUNCS + +bool aarch64_insn_is_steppable_hint(u32 insn); +bool aarch64_insn_is_branch_imm(u32 insn); + +static inline bool aarch64_insn_is_adr_adrp(u32 insn) +{ + return aarch64_insn_is_adr(insn) || aarch64_insn_is_adrp(insn); +} + +static inline bool aarch64_insn_is_barrier(u32 insn) +{ + return aarch64_insn_is_dmb(insn) || aarch64_insn_is_dsb(insn) || + aarch64_insn_is_isb(insn); +} + +static inline bool aarch64_insn_is_store_single(u32 insn) +{ + return aarch64_insn_is_store_imm(insn) || + aarch64_insn_is_store_pre(insn) || + aarch64_insn_is_store_post(insn); +} + +static inline bool aarch64_insn_is_store_pair(u32 insn) +{ + return aarch64_insn_is_stp(insn) || + aarch64_insn_is_stp_pre(insn) || + aarch64_insn_is_stp_post(insn); +} + +static inline bool aarch64_insn_is_load_single(u32 insn) +{ + return aarch64_insn_is_load_imm(insn) || + aarch64_insn_is_load_pre(insn) || + aarch64_insn_is_load_post(insn); +} + +static inline bool aarch64_insn_is_load_pair(u32 insn) +{ + return aarch64_insn_is_ldp(insn) || + aarch64_insn_is_ldp_pre(insn) || + aarch64_insn_is_ldp_post(insn); +} + +enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); +bool aarch64_insn_uses_literal(u32 insn); +bool aarch64_insn_is_branch(u32 insn); +u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn); +u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, + u32 insn, u64 imm); +u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type, + u32 insn); +u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_branch_type type); +u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_register reg, + enum aarch64_insn_variant variant, + enum aarch64_insn_branch_type type); +u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_condition cond); +u32 aarch64_insn_gen_hint(enum aarch64_insn_hint_cr_op op); +u32 aarch64_insn_gen_nop(void); +u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg, + enum aarch64_insn_branch_type type); +u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg, + enum aarch64_insn_register base, + enum aarch64_insn_register offset, + enum aarch64_insn_size_type size, + enum aarch64_insn_ldst_type type); +u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1, + enum aarch64_insn_register reg2, + enum aarch64_insn_register base, + int offset, + enum aarch64_insn_variant variant, + enum aarch64_insn_ldst_type type); +u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg, + enum aarch64_insn_register base, + enum aarch64_insn_register state, + enum aarch64_insn_size_type size, + enum aarch64_insn_ldst_type type); +u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result, + enum aarch64_insn_register address, + enum aarch64_insn_register value, + enum aarch64_insn_size_type size); +u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address, + enum aarch64_insn_register value, + enum aarch64_insn_size_type size); +u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + int imm, enum aarch64_insn_variant variant, + enum aarch64_insn_adsb_type type); +u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr, + enum aarch64_insn_register reg, + enum aarch64_insn_adr_type type); +u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + int immr, int imms, + enum aarch64_insn_variant variant, + enum aarch64_insn_bitfield_type type); +u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst, + int imm, int shift, + enum aarch64_insn_variant variant, + enum aarch64_insn_movewide_type type); +u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg, + int shift, + enum aarch64_insn_variant variant, + enum aarch64_insn_adsb_type type); +u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_variant variant, + enum aarch64_insn_data1_type type); +u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg, + enum aarch64_insn_variant variant, + enum aarch64_insn_data2_type type); +u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg1, + enum aarch64_insn_register reg2, + enum aarch64_insn_variant variant, + enum aarch64_insn_data3_type type); +u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg, + int shift, + enum aarch64_insn_variant variant, + enum aarch64_insn_logic_type type); +u32 aarch64_insn_gen_move_reg(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_variant variant); +u32 aarch64_insn_gen_logical_immediate(enum aarch64_insn_logic_type type, + enum aarch64_insn_variant variant, + enum aarch64_insn_register Rn, + enum aarch64_insn_register Rd, + u64 imm); +u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant, + enum aarch64_insn_register Rm, + enum aarch64_insn_register Rn, + enum aarch64_insn_register Rd, + u8 lsb); +u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base, + enum aarch64_insn_prfm_type type, + enum aarch64_insn_prfm_target target, + enum aarch64_insn_prfm_policy policy); +s32 aarch64_get_branch_offset(u32 insn); +u32 aarch64_set_branch_offset(u32 insn, s32 offset); + +s32 aarch64_insn_adrp_get_offset(u32 insn); +u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset); + +u32 aarch64_insn_extract_system_reg(u32 insn); + + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_AARCH64_INSN_H */ diff --git a/tools/arch/arm64/lib/aarch64-insn.c b/tools/arch/arm64/lib/aarch64-insn.c new file mode 100644 index 000000000000..18e0b66a8284 --- /dev/null +++ b/tools/arch/arm64/lib/aarch64-insn.c @@ -0,0 +1,1425 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include + +#include +#include + +#define AARCH64_INSN_SF_BIT BIT(31) +#define AARCH64_INSN_N_BIT BIT(22) +#define AARCH64_INSN_LSL_12 BIT(22) + +static const int aarch64_insn_encoding_class[] = { + AARCH64_INSN_CLS_UNKNOWN, + AARCH64_INSN_CLS_UNKNOWN, + AARCH64_INSN_CLS_SVE, + AARCH64_INSN_CLS_UNKNOWN, + AARCH64_INSN_CLS_LDST, + AARCH64_INSN_CLS_DP_REG, + AARCH64_INSN_CLS_LDST, + AARCH64_INSN_CLS_DP_FPSIMD, + AARCH64_INSN_CLS_DP_IMM, + AARCH64_INSN_CLS_DP_IMM, + AARCH64_INSN_CLS_BR_SYS, + AARCH64_INSN_CLS_BR_SYS, + AARCH64_INSN_CLS_LDST, + AARCH64_INSN_CLS_DP_REG, + AARCH64_INSN_CLS_LDST, + AARCH64_INSN_CLS_DP_FPSIMD, +}; + +enum aarch64_insn_encoding_class __kprobes aarch64_get_insn_class(u32 insn) +{ + return aarch64_insn_encoding_class[(insn >> 25) & 0xf]; +} + +bool __kprobes aarch64_insn_is_steppable_hint(u32 insn) +{ + if (!aarch64_insn_is_hint(insn)) + return false; + + switch (insn & 0xFE0) { + case AARCH64_INSN_HINT_XPACLRI: + case AARCH64_INSN_HINT_PACIA_1716: + case AARCH64_INSN_HINT_PACIB_1716: + case AARCH64_INSN_HINT_PACIAZ: + case AARCH64_INSN_HINT_PACIASP: + case AARCH64_INSN_HINT_PACIBZ: + case AARCH64_INSN_HINT_PACIBSP: + case AARCH64_INSN_HINT_BTI: + case AARCH64_INSN_HINT_BTIC: + case AARCH64_INSN_HINT_BTIJ: + case AARCH64_INSN_HINT_BTIJC: + case AARCH64_INSN_HINT_NOP: + return true; + default: + return false; + } +} + +bool aarch64_insn_is_branch_imm(u32 insn) +{ + return (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn) || + aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn) || + aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) || + aarch64_insn_is_bcond(insn)); +} + +bool __kprobes aarch64_insn_uses_literal(u32 insn) +{ + /* ldr/ldrsw (literal), prfm */ + + return aarch64_insn_is_ldr_lit(insn) || + aarch64_insn_is_ldrsw_lit(insn) || + aarch64_insn_is_adr_adrp(insn) || + aarch64_insn_is_prfm_lit(insn); +} + +bool __kprobes aarch64_insn_is_branch(u32 insn) +{ + /* b, bl, cb*, tb*, ret*, b.cond, br*, blr* */ + + return aarch64_insn_is_b(insn) || + aarch64_insn_is_bl(insn) || + aarch64_insn_is_cbz(insn) || + aarch64_insn_is_cbnz(insn) || + aarch64_insn_is_tbz(insn) || + aarch64_insn_is_tbnz(insn) || + aarch64_insn_is_ret(insn) || + aarch64_insn_is_ret_auth(insn) || + aarch64_insn_is_br(insn) || + aarch64_insn_is_br_auth(insn) || + aarch64_insn_is_blr(insn) || + aarch64_insn_is_blr_auth(insn) || + aarch64_insn_is_bcond(insn); +} + +static int __kprobes aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type type, + u32 *maskp, int *shiftp) +{ + u32 mask; + int shift; + + switch (type) { + case AARCH64_INSN_IMM_26: + mask = BIT(26) - 1; + shift = 0; + break; + case AARCH64_INSN_IMM_19: + mask = BIT(19) - 1; + shift = 5; + break; + case AARCH64_INSN_IMM_16: + mask = BIT(16) - 1; + shift = 5; + break; + case AARCH64_INSN_IMM_14: + mask = BIT(14) - 1; + shift = 5; + break; + case AARCH64_INSN_IMM_12: + mask = BIT(12) - 1; + shift = 10; + break; + case AARCH64_INSN_IMM_9: + mask = BIT(9) - 1; + shift = 12; + break; + case AARCH64_INSN_IMM_7: + mask = BIT(7) - 1; + shift = 15; + break; + case AARCH64_INSN_IMM_6: + case AARCH64_INSN_IMM_S: + mask = BIT(6) - 1; + shift = 10; + break; + case AARCH64_INSN_IMM_R: + mask = BIT(6) - 1; + shift = 16; + break; + case AARCH64_INSN_IMM_N: + mask = 1; + shift = 22; + break; + default: + return -EINVAL; + } + + *maskp = mask; + *shiftp = shift; + + return 0; +} + +#define ADR_IMM_HILOSPLIT 2 +#define ADR_IMM_SIZE SZ_2M +#define ADR_IMM_LOMASK ((1 << ADR_IMM_HILOSPLIT) - 1) +#define ADR_IMM_HIMASK ((ADR_IMM_SIZE >> ADR_IMM_HILOSPLIT) - 1) +#define ADR_IMM_LOSHIFT 29 +#define ADR_IMM_HISHIFT 5 + +u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn) +{ + u32 immlo, immhi, mask; + int shift; + + switch (type) { + case AARCH64_INSN_IMM_ADR: + shift = 0; + immlo = (insn >> ADR_IMM_LOSHIFT) & ADR_IMM_LOMASK; + immhi = (insn >> ADR_IMM_HISHIFT) & ADR_IMM_HIMASK; + insn = (immhi << ADR_IMM_HILOSPLIT) | immlo; + mask = ADR_IMM_SIZE - 1; + break; + default: + if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { + pr_err("aarch64_insn_decode_immediate: unknown immediate encoding %d\n", + type); + return 0; + } + } + + return (insn >> shift) & mask; +} + +u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, + u32 insn, u64 imm) +{ + u32 immlo, immhi, mask; + int shift; + + if (insn == AARCH64_BREAK_FAULT) + return AARCH64_BREAK_FAULT; + + switch (type) { + case AARCH64_INSN_IMM_ADR: + shift = 0; + immlo = (imm & ADR_IMM_LOMASK) << ADR_IMM_LOSHIFT; + imm >>= ADR_IMM_HILOSPLIT; + immhi = (imm & ADR_IMM_HIMASK) << ADR_IMM_HISHIFT; + imm = immlo | immhi; + mask = ((ADR_IMM_LOMASK << ADR_IMM_LOSHIFT) | + (ADR_IMM_HIMASK << ADR_IMM_HISHIFT)); + break; + default: + if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { + pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n", + type); + return AARCH64_BREAK_FAULT; + } + } + + /* Update the immediate field. */ + insn &= ~(mask << shift); + insn |= (imm & mask) << shift; + + return insn; +} + +u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type, + u32 insn) +{ + int shift; + + switch (type) { + case AARCH64_INSN_REGTYPE_RT: + case AARCH64_INSN_REGTYPE_RD: + shift = 0; + break; + case AARCH64_INSN_REGTYPE_RN: + shift = 5; + break; + case AARCH64_INSN_REGTYPE_RT2: + case AARCH64_INSN_REGTYPE_RA: + shift = 10; + break; + case AARCH64_INSN_REGTYPE_RM: + shift = 16; + break; + default: + pr_err("%s: unknown register type encoding %d\n", __func__, + type); + return 0; + } + + return (insn >> shift) & GENMASK(4, 0); +} + +static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type, + u32 insn, + enum aarch64_insn_register reg) +{ + int shift; + + if (insn == AARCH64_BREAK_FAULT) + return AARCH64_BREAK_FAULT; + + if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) { + pr_err("%s: unknown register encoding %d\n", __func__, reg); + return AARCH64_BREAK_FAULT; + } + + switch (type) { + case AARCH64_INSN_REGTYPE_RT: + case AARCH64_INSN_REGTYPE_RD: + shift = 0; + break; + case AARCH64_INSN_REGTYPE_RN: + shift = 5; + break; + case AARCH64_INSN_REGTYPE_RT2: + case AARCH64_INSN_REGTYPE_RA: + shift = 10; + break; + case AARCH64_INSN_REGTYPE_RM: + case AARCH64_INSN_REGTYPE_RS: + shift = 16; + break; + default: + pr_err("%s: unknown register type encoding %d\n", __func__, + type); + return AARCH64_BREAK_FAULT; + } + + insn &= ~(GENMASK(4, 0) << shift); + insn |= reg << shift; + + return insn; +} + +static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type, + u32 insn) +{ + u32 size; + + switch (type) { + case AARCH64_INSN_SIZE_8: + size = 0; + break; + case AARCH64_INSN_SIZE_16: + size = 1; + break; + case AARCH64_INSN_SIZE_32: + size = 2; + break; + case AARCH64_INSN_SIZE_64: + size = 3; + break; + default: + pr_err("%s: unknown size encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + insn &= ~GENMASK(31, 30); + insn |= size << 30; + + return insn; +} + +static inline long branch_imm_common(unsigned long pc, unsigned long addr, + long range) +{ + long offset; + + if ((pc & 0x3) || (addr & 0x3)) { + pr_err("%s: A64 instructions must be word aligned\n", __func__); + return range; + } + + offset = ((long)addr - (long)pc); + + if (offset < -range || offset >= range) { + pr_err("%s: offset out of range\n", __func__); + return range; + } + + return offset; +} + +u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_branch_type type) +{ + u32 insn; + long offset; + + /* + * B/BL support [-128M, 128M) offset + * ARM64 virtual address arrangement guarantees all kernel and module + * texts are within +/-128M. + */ + offset = branch_imm_common(pc, addr, SZ_128M); + if (offset >= SZ_128M) + return AARCH64_BREAK_FAULT; + + switch (type) { + case AARCH64_INSN_BRANCH_LINK: + insn = aarch64_insn_get_bl_value(); + break; + case AARCH64_INSN_BRANCH_NOLINK: + insn = aarch64_insn_get_b_value(); + break; + default: + pr_err("%s: unknown branch encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn, + offset >> 2); +} + +u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_register reg, + enum aarch64_insn_variant variant, + enum aarch64_insn_branch_type type) +{ + u32 insn; + long offset; + + offset = branch_imm_common(pc, addr, SZ_1M); + if (offset >= SZ_1M) + return AARCH64_BREAK_FAULT; + + switch (type) { + case AARCH64_INSN_BRANCH_COMP_ZERO: + insn = aarch64_insn_get_cbz_value(); + break; + case AARCH64_INSN_BRANCH_COMP_NONZERO: + insn = aarch64_insn_get_cbnz_value(); + break; + default: + pr_err("%s: unknown branch encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, + offset >> 2); +} + +u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_condition cond) +{ + u32 insn; + long offset; + + offset = branch_imm_common(pc, addr, SZ_1M); + + insn = aarch64_insn_get_bcond_value(); + + if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) { + pr_err("%s: unknown condition encoding %d\n", __func__, cond); + return AARCH64_BREAK_FAULT; + } + insn |= cond; + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, + offset >> 2); +} + +u32 __kprobes aarch64_insn_gen_hint(enum aarch64_insn_hint_cr_op op) +{ + return aarch64_insn_get_hint_value() | op; +} + +u32 __kprobes aarch64_insn_gen_nop(void) +{ + return aarch64_insn_gen_hint(AARCH64_INSN_HINT_NOP); +} + +u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg, + enum aarch64_insn_branch_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_BRANCH_NOLINK: + insn = aarch64_insn_get_br_value(); + break; + case AARCH64_INSN_BRANCH_LINK: + insn = aarch64_insn_get_blr_value(); + break; + case AARCH64_INSN_BRANCH_RETURN: + insn = aarch64_insn_get_ret_value(); + break; + default: + pr_err("%s: unknown branch encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, reg); +} + +u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg, + enum aarch64_insn_register base, + enum aarch64_insn_register offset, + enum aarch64_insn_size_type size, + enum aarch64_insn_ldst_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_LDST_LOAD_REG_OFFSET: + insn = aarch64_insn_get_ldr_reg_value(); + break; + case AARCH64_INSN_LDST_STORE_REG_OFFSET: + insn = aarch64_insn_get_str_reg_value(); + break; + default: + pr_err("%s: unknown load/store encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_ldst_size(size, insn); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, + base); + + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, + offset); +} + +u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1, + enum aarch64_insn_register reg2, + enum aarch64_insn_register base, + int offset, + enum aarch64_insn_variant variant, + enum aarch64_insn_ldst_type type) +{ + u32 insn; + int shift; + + switch (type) { + case AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX: + insn = aarch64_insn_get_ldp_pre_value(); + break; + case AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX: + insn = aarch64_insn_get_stp_pre_value(); + break; + case AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX: + insn = aarch64_insn_get_ldp_post_value(); + break; + case AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX: + insn = aarch64_insn_get_stp_post_value(); + break; + default: + pr_err("%s: unknown load/store encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + if ((offset & 0x3) || (offset < -256) || (offset > 252)) { + pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n", + __func__, offset); + return AARCH64_BREAK_FAULT; + } + shift = 2; + break; + case AARCH64_INSN_VARIANT_64BIT: + if ((offset & 0x7) || (offset < -512) || (offset > 504)) { + pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n", + __func__, offset); + return AARCH64_BREAK_FAULT; + } + shift = 3; + insn |= AARCH64_INSN_SF_BIT; + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, + reg1); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn, + reg2); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, + base); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_7, insn, + offset >> shift); +} + +u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg, + enum aarch64_insn_register base, + enum aarch64_insn_register state, + enum aarch64_insn_size_type size, + enum aarch64_insn_ldst_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_LDST_LOAD_EX: + insn = aarch64_insn_get_load_ex_value(); + break; + case AARCH64_INSN_LDST_STORE_EX: + insn = aarch64_insn_get_store_ex_value(); + break; + default: + pr_err("%s: unknown load/store exclusive encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_ldst_size(size, insn); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, + reg); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, + base); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn, + AARCH64_INSN_REG_ZR); + + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn, + state); +} + +u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result, + enum aarch64_insn_register address, + enum aarch64_insn_register value, + enum aarch64_insn_size_type size) +{ + u32 insn = aarch64_insn_get_ldadd_value(); + + switch (size) { + case AARCH64_INSN_SIZE_32: + case AARCH64_INSN_SIZE_64: + break; + default: + pr_err("%s: unimplemented size encoding %d\n", __func__, size); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_ldst_size(size, insn); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, + result); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, + address); + + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn, + value); +} + +u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address, + enum aarch64_insn_register value, + enum aarch64_insn_size_type size) +{ + /* + * STADD is simply encoded as an alias for LDADD with XZR as + * the destination register. + */ + return aarch64_insn_gen_ldadd(AARCH64_INSN_REG_ZR, address, + value, size); +} + +static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type, + enum aarch64_insn_prfm_target target, + enum aarch64_insn_prfm_policy policy, + u32 insn) +{ + u32 imm_type = 0, imm_target = 0, imm_policy = 0; + + switch (type) { + case AARCH64_INSN_PRFM_TYPE_PLD: + break; + case AARCH64_INSN_PRFM_TYPE_PLI: + imm_type = BIT(0); + break; + case AARCH64_INSN_PRFM_TYPE_PST: + imm_type = BIT(1); + break; + default: + pr_err("%s: unknown prfm type encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (target) { + case AARCH64_INSN_PRFM_TARGET_L1: + break; + case AARCH64_INSN_PRFM_TARGET_L2: + imm_target = BIT(0); + break; + case AARCH64_INSN_PRFM_TARGET_L3: + imm_target = BIT(1); + break; + default: + pr_err("%s: unknown prfm target encoding %d\n", __func__, target); + return AARCH64_BREAK_FAULT; + } + + switch (policy) { + case AARCH64_INSN_PRFM_POLICY_KEEP: + break; + case AARCH64_INSN_PRFM_POLICY_STRM: + imm_policy = BIT(0); + break; + default: + pr_err("%s: unknown prfm policy encoding %d\n", __func__, policy); + return AARCH64_BREAK_FAULT; + } + + /* In this case, imm5 is encoded into Rt field. */ + insn &= ~GENMASK(4, 0); + insn |= imm_policy | (imm_target << 1) | (imm_type << 3); + + return insn; +} + +u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base, + enum aarch64_insn_prfm_type type, + enum aarch64_insn_prfm_target target, + enum aarch64_insn_prfm_policy policy) +{ + u32 insn = aarch64_insn_get_prfm_value(); + + insn = aarch64_insn_encode_ldst_size(AARCH64_INSN_SIZE_64, insn); + + insn = aarch64_insn_encode_prfm_imm(type, target, policy, insn); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, + base); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, 0); +} + +u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + int imm, enum aarch64_insn_variant variant, + enum aarch64_insn_adsb_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_ADSB_ADD: + insn = aarch64_insn_get_add_imm_value(); + break; + case AARCH64_INSN_ADSB_SUB: + insn = aarch64_insn_get_sub_imm_value(); + break; + case AARCH64_INSN_ADSB_ADD_SETFLAGS: + insn = aarch64_insn_get_adds_imm_value(); + break; + case AARCH64_INSN_ADSB_SUB_SETFLAGS: + insn = aarch64_insn_get_subs_imm_value(); + break; + default: + pr_err("%s: unknown add/sub encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + /* We can't encode more than a 24bit value (12bit + 12bit shift) */ + if (imm & ~(BIT(24) - 1)) + goto out; + + /* If we have something in the top 12 bits... */ + if (imm & ~(SZ_4K - 1)) { + /* ... and in the low 12 bits -> error */ + if (imm & (SZ_4K - 1)) + goto out; + + imm >>= 12; + insn |= AARCH64_INSN_LSL_12; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm); + +out: + pr_err("%s: invalid immediate encoding %d\n", __func__, imm); + return AARCH64_BREAK_FAULT; +} + +u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + int immr, int imms, + enum aarch64_insn_variant variant, + enum aarch64_insn_bitfield_type type) +{ + u32 insn; + u32 mask; + + switch (type) { + case AARCH64_INSN_BITFIELD_MOVE: + insn = aarch64_insn_get_bfm_value(); + break; + case AARCH64_INSN_BITFIELD_MOVE_UNSIGNED: + insn = aarch64_insn_get_ubfm_value(); + break; + case AARCH64_INSN_BITFIELD_MOVE_SIGNED: + insn = aarch64_insn_get_sbfm_value(); + break; + default: + pr_err("%s: unknown bitfield encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + mask = GENMASK(4, 0); + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT | AARCH64_INSN_N_BIT; + mask = GENMASK(5, 0); + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + if (immr & ~mask) { + pr_err("%s: invalid immr encoding %d\n", __func__, immr); + return AARCH64_BREAK_FAULT; + } + if (imms & ~mask) { + pr_err("%s: invalid imms encoding %d\n", __func__, imms); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src); + + insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms); +} + +u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst, + int imm, int shift, + enum aarch64_insn_variant variant, + enum aarch64_insn_movewide_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_MOVEWIDE_ZERO: + insn = aarch64_insn_get_movz_value(); + break; + case AARCH64_INSN_MOVEWIDE_KEEP: + insn = aarch64_insn_get_movk_value(); + break; + case AARCH64_INSN_MOVEWIDE_INVERSE: + insn = aarch64_insn_get_movn_value(); + break; + default: + pr_err("%s: unknown movewide encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + if (imm & ~(SZ_64K - 1)) { + pr_err("%s: invalid immediate encoding %d\n", __func__, imm); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + if (shift != 0 && shift != 16) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + if (shift != 0 && shift != 16 && shift != 32 && shift != 48) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + insn |= (shift >> 4) << 21; + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm); +} + +u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg, + int shift, + enum aarch64_insn_variant variant, + enum aarch64_insn_adsb_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_ADSB_ADD: + insn = aarch64_insn_get_add_value(); + break; + case AARCH64_INSN_ADSB_SUB: + insn = aarch64_insn_get_sub_value(); + break; + case AARCH64_INSN_ADSB_ADD_SETFLAGS: + insn = aarch64_insn_get_adds_value(); + break; + case AARCH64_INSN_ADSB_SUB_SETFLAGS: + insn = aarch64_insn_get_subs_value(); + break; + default: + pr_err("%s: unknown add/sub encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + if (shift & ~(SZ_32 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + if (shift & ~(SZ_64 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift); +} + +u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_variant variant, + enum aarch64_insn_data1_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_DATA1_REVERSE_16: + insn = aarch64_insn_get_rev16_value(); + break; + case AARCH64_INSN_DATA1_REVERSE_32: + insn = aarch64_insn_get_rev32_value(); + break; + case AARCH64_INSN_DATA1_REVERSE_64: + if (variant != AARCH64_INSN_VARIANT_64BIT) { + pr_err("%s: invalid variant for reverse64 %d\n", + __func__, variant); + return AARCH64_BREAK_FAULT; + } + insn = aarch64_insn_get_rev64_value(); + break; + default: + pr_err("%s: unknown data1 encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src); +} + +u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg, + enum aarch64_insn_variant variant, + enum aarch64_insn_data2_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_DATA2_UDIV: + insn = aarch64_insn_get_udiv_value(); + break; + case AARCH64_INSN_DATA2_SDIV: + insn = aarch64_insn_get_sdiv_value(); + break; + case AARCH64_INSN_DATA2_LSLV: + insn = aarch64_insn_get_lslv_value(); + break; + case AARCH64_INSN_DATA2_LSRV: + insn = aarch64_insn_get_lsrv_value(); + break; + case AARCH64_INSN_DATA2_ASRV: + insn = aarch64_insn_get_asrv_value(); + break; + case AARCH64_INSN_DATA2_RORV: + insn = aarch64_insn_get_rorv_value(); + break; + default: + pr_err("%s: unknown data2 encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src); + + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg); +} + +u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg1, + enum aarch64_insn_register reg2, + enum aarch64_insn_variant variant, + enum aarch64_insn_data3_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_DATA3_MADD: + insn = aarch64_insn_get_madd_value(); + break; + case AARCH64_INSN_DATA3_MSUB: + insn = aarch64_insn_get_msub_value(); + break; + default: + pr_err("%s: unknown data3 encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RA, insn, src); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, + reg1); + + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, + reg2); +} + +u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_register reg, + int shift, + enum aarch64_insn_variant variant, + enum aarch64_insn_logic_type type) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_LOGIC_AND: + insn = aarch64_insn_get_and_value(); + break; + case AARCH64_INSN_LOGIC_BIC: + insn = aarch64_insn_get_bic_value(); + break; + case AARCH64_INSN_LOGIC_ORR: + insn = aarch64_insn_get_orr_value(); + break; + case AARCH64_INSN_LOGIC_ORN: + insn = aarch64_insn_get_orn_value(); + break; + case AARCH64_INSN_LOGIC_EOR: + insn = aarch64_insn_get_eor_value(); + break; + case AARCH64_INSN_LOGIC_EON: + insn = aarch64_insn_get_eon_value(); + break; + case AARCH64_INSN_LOGIC_AND_SETFLAGS: + insn = aarch64_insn_get_ands_value(); + break; + case AARCH64_INSN_LOGIC_BIC_SETFLAGS: + insn = aarch64_insn_get_bics_value(); + break; + default: + pr_err("%s: unknown logical encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + if (shift & ~(SZ_32 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + if (shift & ~(SZ_64 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src); + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift); +} + +/* + * MOV (register) is architecturally an alias of ORR (shifted register) where + * MOV <*d>, <*m> is equivalent to ORR <*d>, <*ZR>, <*m> + */ +u32 aarch64_insn_gen_move_reg(enum aarch64_insn_register dst, + enum aarch64_insn_register src, + enum aarch64_insn_variant variant) +{ + return aarch64_insn_gen_logical_shifted_reg(dst, AARCH64_INSN_REG_ZR, + src, 0, variant, + AARCH64_INSN_LOGIC_ORR); +} + +u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr, + enum aarch64_insn_register reg, + enum aarch64_insn_adr_type type) +{ + u32 insn; + s32 offset; + + switch (type) { + case AARCH64_INSN_ADR_TYPE_ADR: + insn = aarch64_insn_get_adr_value(); + offset = addr - pc; + break; + case AARCH64_INSN_ADR_TYPE_ADRP: + insn = aarch64_insn_get_adrp_value(); + offset = (addr - ALIGN_DOWN(pc, SZ_4K)) >> 12; + break; + default: + pr_err("%s: unknown adr encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + if (offset < -SZ_1M || offset >= SZ_1M) + return AARCH64_BREAK_FAULT; + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, reg); + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, offset); +} + +/* + * Decode the imm field of a branch, and return the byte offset as a + * signed value (so it can be used when computing a new branch + * target). + */ +s32 aarch64_get_branch_offset(u32 insn) +{ + s32 imm; + + if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) { + imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn); + return (imm << 6) >> 4; + } + + if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) || + aarch64_insn_is_bcond(insn)) { + imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn); + return (imm << 13) >> 11; + } + + if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) { + imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn); + return (imm << 18) >> 16; + } + + /* Unhandled instruction */ + BUG(); +} + +/* + * Encode the displacement of a branch in the imm field and return the + * updated instruction. + */ +u32 aarch64_set_branch_offset(u32 insn, s32 offset) +{ + if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn, + offset >> 2); + + if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) || + aarch64_insn_is_bcond(insn)) + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, + offset >> 2); + + if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_14, insn, + offset >> 2); + + /* Unhandled instruction */ + BUG(); +} + +s32 aarch64_insn_adrp_get_offset(u32 insn) +{ + BUG_ON(!aarch64_insn_is_adrp(insn)); + return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12; +} + +u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset) +{ + BUG_ON(!aarch64_insn_is_adrp(insn)); + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, + offset >> 12); +} + +/* + * Extract the Op/CR data from a msr/mrs instruction. + */ +u32 aarch64_insn_extract_system_reg(u32 insn) +{ + return (insn & 0x1FFFE0) >> 5; +} + +static bool range_of_ones(u64 val) +{ + /* Doesn't handle full ones or full zeroes */ + u64 sval = val >> __ffs64(val); + + /* One of Sean Eron Anderson's bithack tricks */ + return ((sval + 1) & (sval)) == 0; +} + +static u32 aarch64_encode_immediate(u64 imm, + enum aarch64_insn_variant variant, + u32 insn) +{ + unsigned int immr, imms, n, ones, ror, esz, tmp; + u64 mask; + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + esz = 32; + break; + case AARCH64_INSN_VARIANT_64BIT: + insn |= AARCH64_INSN_SF_BIT; + esz = 64; + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + mask = GENMASK(esz - 1, 0); + + /* Can't encode full zeroes, full ones, or value wider than the mask */ + if (!imm || imm == mask || imm & ~mask) + return AARCH64_BREAK_FAULT; + + /* + * Inverse of Replicate(). Try to spot a repeating pattern + * with a pow2 stride. + */ + for (tmp = esz / 2; tmp >= 2; tmp /= 2) { + u64 emask = BIT(tmp) - 1; + + if ((imm & emask) != ((imm >> tmp) & emask)) + break; + + esz = tmp; + mask = emask; + } + + /* N is only set if we're encoding a 64bit value */ + n = esz == 64; + + /* Trim imm to the element size */ + imm &= mask; + + /* That's how many ones we need to encode */ + ones = hweight64(imm); + + /* + * imms is set to (ones - 1), prefixed with a string of ones + * and a zero if they fit. Cap it to 6 bits. + */ + imms = ones - 1; + imms |= 0xf << ffs(esz); + imms &= BIT(6) - 1; + + /* Compute the rotation */ + if (range_of_ones(imm)) { + /* + * Pattern: 0..01..10..0 + * + * Compute how many rotate we need to align it right + */ + ror = __ffs64(imm); + } else { + /* + * Pattern: 0..01..10..01..1 + * + * Fill the unused top bits with ones, and check if + * the result is a valid immediate (all ones with a + * contiguous ranges of zeroes). + */ + imm |= ~mask; + if (!range_of_ones(~imm)) + return AARCH64_BREAK_FAULT; + + /* + * Compute the rotation to get a continuous set of + * ones, with the first bit set at position 0 + */ + ror = fls(~imm); + } + + /* + * immr is the number of bits we need to rotate back to the + * original set of ones. Note that this is relative to the + * element size... + */ + immr = (esz - ror) % esz; + + insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, n); + insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr); + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms); +} + +u32 aarch64_insn_gen_logical_immediate(enum aarch64_insn_logic_type type, + enum aarch64_insn_variant variant, + enum aarch64_insn_register Rn, + enum aarch64_insn_register Rd, + u64 imm) +{ + u32 insn; + + switch (type) { + case AARCH64_INSN_LOGIC_AND: + insn = aarch64_insn_get_and_imm_value(); + break; + case AARCH64_INSN_LOGIC_ORR: + insn = aarch64_insn_get_orr_imm_value(); + break; + case AARCH64_INSN_LOGIC_EOR: + insn = aarch64_insn_get_eor_imm_value(); + break; + case AARCH64_INSN_LOGIC_AND_SETFLAGS: + insn = aarch64_insn_get_ands_imm_value(); + break; + default: + pr_err("%s: unknown logical encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd); + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn); + return aarch64_encode_immediate(imm, variant, insn); +} + +u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant, + enum aarch64_insn_register Rm, + enum aarch64_insn_register Rn, + enum aarch64_insn_register Rd, + u8 lsb) +{ + u32 insn; + + insn = aarch64_insn_get_extr_value(); + + switch (variant) { + case AARCH64_INSN_VARIANT_32BIT: + if (lsb > 31) + return AARCH64_BREAK_FAULT; + break; + case AARCH64_INSN_VARIANT_64BIT: + if (lsb > 63) + return AARCH64_BREAK_FAULT; + insn |= AARCH64_INSN_SF_BIT; + insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, 1); + break; + default: + pr_err("%s: unknown variant encoding %d\n", __func__, variant); + return AARCH64_BREAK_FAULT; + } + + insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, lsb); + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd); + insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn); + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm); +} From patchwork Wed Jan 20 17:37:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368209 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 495E4C433E0 for ; Wed, 20 Jan 2021 18:47:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0832222473 for ; Wed, 20 Jan 2021 18:47:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733264AbhATSqo (ORCPT ); Wed, 20 Jan 2021 13:46:44 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:47095 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387459AbhATRjk (ORCPT ); Wed, 20 Jan 2021 12:39:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164293; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1YEVSMla8UOmgBC4LmzAJMeE/UB0SCvN1vHTnN1GioY=; b=eRFp/dslELn1Z1K8T71nM0v6M9sdr6YvkLoStbkmEJEkXd3ZD4OYVesbtGP+C71U/y8C9n RRgPs1DCiqpljKunWApaWRGpNVr/ZPjLRuru626s9yUsCWAMuRaNVsSp48P2pcks0/lo+5 I7hBgjEZmLB6j5DIDxlvTggHejsaBVw= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-301-H02AeYduP--NCI5z1ZIApw-1; Wed, 20 Jan 2021 12:38:11 -0500 X-MC-Unique: H02AeYduP--NCI5z1ZIApw-1 Received: by mail-wr1-f71.google.com with SMTP id r8so11922927wro.22 for ; Wed, 20 Jan 2021 09:38:11 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1YEVSMla8UOmgBC4LmzAJMeE/UB0SCvN1vHTnN1GioY=; b=J8+Z9FoG1q0GJHVWzzzE2thXikP7PMpFEW0mEuKiFZc4d8J3L4k312jPsyScL43nhd Yy50uIMFQWIITxI2o9rfF0mbjuAa7Z29XcwxP1AA2VJ4laWB4VMzpvn1EVSMabCs2zKR S3p4hD54Xg1wJ0mUPZWshcWflegbim16Sb3IOTu3Fm90rJdxnsIRbM+Mqcpq1fFEKZju JJ2Bkx7LEvdrlihHCVSR/xfiHKgW5HrUmeHqyK4jKbPzHt8z1GkwzRuxtKJpFac6kfij rgithp9fJkWnuoLaISpQh24t5fyOJSZ2DD5hixV2HH1uvjeSldPdbPgKp0WdwyGbm11t fpig== X-Gm-Message-State: AOAM531jhHGz4jG0POGPDYmXSz++ax65yftaGjB98jCgmLqR9SaunlAx xSFad/Ee5US/MlR8N5MHAb7Sra2ZCJTF6S9uAoddxmSGvNkjxufyNNNmhfYuNR69ERCmQXvwild mIXBVM3KVlsLVPOZXDoib X-Received: by 2002:adf:d238:: with SMTP id k24mr10316323wrh.414.1611164290573; Wed, 20 Jan 2021 09:38:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJxsXKBygCbH5ehSM3hv+i9wV2hjiG6FmiP83Wor2Wz+s8QTVOj8s3jD6nPK36EhOefk08Au5A== X-Received: by 2002:adf:d238:: with SMTP id k24mr10316310wrh.414.1611164290420; Wed, 20 Jan 2021 09:38:10 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:08 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 03/17] tools: bug: Remove duplicate definition Date: Wed, 20 Jan 2021 18:37:46 +0100 Message-Id: <20210120173800.1660730-4-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Under tools, bug.h only defines BUILD_BUG_ON_ZERO() which is already defined in build_bug.h. This prevents a file to include both headers at the same time. Have bug.h include build_bug.h instead. Signed-off-by: Julien Thierry --- tools/include/linux/bug.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/include/linux/bug.h b/tools/include/linux/bug.h index 85f80258a15f..548be7cffa8e 100644 --- a/tools/include/linux/bug.h +++ b/tools/include/linux/bug.h @@ -2,10 +2,6 @@ #ifndef _TOOLS_PERF_LINUX_BUG_H #define _TOOLS_PERF_LINUX_BUG_H -/* Force a compilation error if condition is true, but also produce a - result (of value 0 and type size_t), so the expression can be used - e.g. in a structure initializer (or where-ever else comma expressions - aren't permitted). */ -#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) +#include #endif /* _TOOLS_PERF_LINUX_BUG_H */ From patchwork Wed Jan 20 17:37:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367355 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B70CC43333 for ; Wed, 20 Jan 2021 19:22:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 35D48233EB for ; Wed, 20 Jan 2021 19:22:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733303AbhATSqu (ORCPT ); Wed, 20 Jan 2021 13:46:50 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:35389 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387639AbhATRjo (ORCPT ); Wed, 20 Jan 2021 12:39:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164297; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pZtUwFLGKmTk06Edz7BP1qawZG5Xl7GI1AIkrnSV6+8=; b=IbsvKK112hiMdhuwKjf4eSo24x9YHf2cMwNqvCDss+YYJkUuwBsL8f+c7EABtrBg2M4yz3 dhWrk8MzdhbSnfbAsalQwfvKJDVNmCdhebFr5yQqopAC4TXsCrGdMFPeabSWJe6N+J/2Fj zRhF171Xsl5Rwovy85HV8FXNsPU9UI0= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-421-PoKeTDBYPKCg4XOQKt15aw-1; Wed, 20 Jan 2021 12:38:14 -0500 X-MC-Unique: PoKeTDBYPKCg4XOQKt15aw-1 Received: by mail-wr1-f70.google.com with SMTP id l10so11562341wry.16 for ; Wed, 20 Jan 2021 09:38:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pZtUwFLGKmTk06Edz7BP1qawZG5Xl7GI1AIkrnSV6+8=; b=gPw5bLVGvhXqWYL0+sxp6ZyBh1OvqHap3GWnxOHZHuxArYhZPFWtTrvnH/PB+euS2G 8Zz0dsokg6g0Nx1X2LzTvi2Zss39p0V10+Ru9c87v3zRQu8CJAmrrjI6NQCobOREd/F9 eME98GL86OunHtgDJe/VgQlr59NtmVvmOjYeyy2GA+57CEwwBxcyLpgg5N34KwEVhDIp bccckRyGAD6UE/voQl6rxIf0hLvYeJRvMn3PODG7vGboohBEQyOvSb/47+HSqYF5nRK7 PuxLkIUQBGalw+1JoKxu0LRspu7TVd7Af3kk3kN6vMjWcX66wG1TlcSR98wW+5BkYwaG DfZQ== X-Gm-Message-State: AOAM530pQz9mWoiY/zLxdgmk5m4SpUyd+q2ayCGVUTTdQ9F05T/2KPiu VEyMDVEigRs9Y1k0wa9lGbVdc0bW43FJD3lxGA9w5Vjbl5hmAUxdXMWKehiIbfWXoiQ3f27M6aT CQCnLpK8/dnmPoVH9slif X-Received: by 2002:adf:9e47:: with SMTP id v7mr10339900wre.185.1611164292796; Wed, 20 Jan 2021 09:38:12 -0800 (PST) X-Google-Smtp-Source: ABdhPJwmMRPghUxsaTRcr7FJKWN0wZkptspY3JLpZpcYt8/LaAizFtPfNbXSDn+oQyq+nhU2NDK7sQ== X-Received: by 2002:adf:9e47:: with SMTP id v7mr10339890wre.185.1611164292653; Wed, 20 Jan 2021 09:38:12 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:12 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 04/17] objtool: arm64: Add base definition for arm64 backend Date: Wed, 20 Jan 2021 18:37:47 +0100 Message-Id: <20210120173800.1660730-5-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Provide needed definitions for a new architecture instruction decoder. No proper decoding is done yet. Signed-off-by: Julien Thierry --- tools/objtool/Makefile | 5 + tools/objtool/arch/arm64/Build | 8 ++ tools/objtool/arch/arm64/decode.c | 130 ++++++++++++++++++ .../arch/arm64/include/arch/cfi_regs.h | 14 ++ tools/objtool/arch/arm64/include/arch/elf.h | 6 + .../arch/arm64/include/arch/endianness.h | 9 ++ .../objtool/arch/arm64/include/arch/special.h | 21 +++ tools/objtool/arch/arm64/special.c | 21 +++ tools/objtool/sync-check.sh | 5 + 9 files changed, 219 insertions(+) create mode 100644 tools/objtool/arch/arm64/Build create mode 100644 tools/objtool/arch/arm64/decode.c create mode 100644 tools/objtool/arch/arm64/include/arch/cfi_regs.h create mode 100644 tools/objtool/arch/arm64/include/arch/elf.h create mode 100644 tools/objtool/arch/arm64/include/arch/endianness.h create mode 100644 tools/objtool/arch/arm64/include/arch/special.h create mode 100644 tools/objtool/arch/arm64/special.c diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 92ce4fce7bc7..d5cfbec87c02 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -47,6 +47,11 @@ ifeq ($(SRCARCH),x86) SUBCMD_ORC := y endif +ifeq ($(SRCARCH),arm64) + SUBCMD_CHECK := y + CFLAGS += -Wno-nested-externs +endif + export SUBCMD_CHECK SUBCMD_ORC export srctree OUTPUT CFLAGS SRCARCH AWK include $(srctree)/tools/build/Makefile.include diff --git a/tools/objtool/arch/arm64/Build b/tools/objtool/arch/arm64/Build new file mode 100644 index 000000000000..f3de3a50d541 --- /dev/null +++ b/tools/objtool/arch/arm64/Build @@ -0,0 +1,8 @@ +objtool-y += special.o +objtool-y += decode.o + +objtool-y += libhweight.o + +$(OUTPUT)arch/arm64/libhweight.o: ../lib/hweight.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c new file mode 100644 index 000000000000..8ae822f553ca --- /dev/null +++ b/tools/objtool/arch/arm64/decode.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include + +/* Hack needed to avoid depending on brk-imm.h */ +#define FAULT_BRK_IMM 0x100 + +#include + +#include +#include +#include +#include + +#include + +/* Hack needed to avoid depending on kprobes.h */ +#ifndef __kprobes +#define __kprobes +#endif + +#include "../../../arch/arm64/lib/aarch64-insn.c" + +bool arch_callee_saved_reg(unsigned char reg) +{ + switch (reg) { + case AARCH64_INSN_REG_19: + case AARCH64_INSN_REG_20: + case AARCH64_INSN_REG_21: + case AARCH64_INSN_REG_22: + case AARCH64_INSN_REG_23: + case AARCH64_INSN_REG_24: + case AARCH64_INSN_REG_25: + case AARCH64_INSN_REG_26: + case AARCH64_INSN_REG_27: + case AARCH64_INSN_REG_28: + case AARCH64_INSN_REG_FP: + case AARCH64_INSN_REG_LR: + return true; + default: + return false; + } +} + +void arch_initial_func_cfi_state(struct cfi_init_state *state) +{ + int i; + + for (i = 0; i < CFI_NUM_REGS; i++) { + state->regs[i].base = CFI_UNDEFINED; + state->regs[i].offset = 0; + } + + /* initial CFA (call frame address) */ + state->cfa.base = CFI_SP; + state->cfa.offset = 0; +} + +unsigned long arch_dest_reloc_offset(int addend) +{ + return addend; +} + +unsigned long arch_jump_destination(struct instruction *insn) +{ + return insn->offset + insn->immediate; +} + +const char *arch_nop_insn(int len) +{ + static u32 nop = 0; + + if (len != AARCH64_INSN_SIZE) + WARN("invalid NOP size: %d\n", len); + + if (!nop) + nop = aarch64_insn_gen_nop(); + + return (const char*)&nop; +} + +static int is_arm64(const struct elf *elf) +{ + switch (elf->ehdr.e_machine) { + case EM_AARCH64: //0xB7 + return 1; + default: + WARN("unexpected ELF machine type %x", + elf->ehdr.e_machine); + return 0; + } +} + +int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg) +{ + return -1; +} + +int arch_decode_instruction(const struct elf *elf, const struct section *sec, + unsigned long offset, unsigned int maxlen, + unsigned int *len, enum insn_type *type, + unsigned long *immediate, + struct list_head *ops_list) +{ + u32 insn; + + if (!is_arm64(elf)) + return -1; + + if (maxlen < AARCH64_INSN_SIZE) + return 0; + + *len = AARCH64_INSN_SIZE; + *immediate = 0; + + insn = *(u32 *)(sec->data->d_buf + offset); + + switch (aarch64_get_insn_class(insn)) { + case AARCH64_INSN_CLS_UNKNOWN: + WARN("can't decode instruction at %s:0x%lx", sec->name, offset); + return -1; + default: + *type = INSN_OTHER; + break; + } + + return 0; +} diff --git a/tools/objtool/arch/arm64/include/arch/cfi_regs.h b/tools/objtool/arch/arm64/include/arch/cfi_regs.h new file mode 100644 index 000000000000..43ad56b6c3f9 --- /dev/null +++ b/tools/objtool/arch/arm64/include/arch/cfi_regs.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _OBJTOOL_CFI_REGS_H +#define _OBJTOOL_CFI_REGS_H + +#include + +#define CFI_BP AARCH64_INSN_REG_FP +#define CFI_RA AARCH64_INSN_REG_LR +#define CFI_SP AARCH64_INSN_REG_SP + +#define CFI_NUM_REGS 32 + +#endif /* _OBJTOOL_CFI_REGS_H */ diff --git a/tools/objtool/arch/arm64/include/arch/elf.h b/tools/objtool/arch/arm64/include/arch/elf.h new file mode 100644 index 000000000000..a31a29b1a386 --- /dev/null +++ b/tools/objtool/arch/arm64/include/arch/elf.h @@ -0,0 +1,6 @@ +#ifndef _OBJTOOL_ARCH_ELF +#define _OBJTOOL_ARCH_ELF + +#define R_NONE R_AARCH64_NONE + +#endif /* _OBJTOOL_ARCH_ELF */ diff --git a/tools/objtool/arch/arm64/include/arch/endianness.h b/tools/objtool/arch/arm64/include/arch/endianness.h new file mode 100644 index 000000000000..7c362527da20 --- /dev/null +++ b/tools/objtool/arch/arm64/include/arch/endianness.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ARCH_ENDIANNESS_H +#define _ARCH_ENDIANNESS_H + +#include + +#define __TARGET_BYTE_ORDER __LITTLE_ENDIAN + +#endif /* _ARCH_ENDIANNESS_H */ diff --git a/tools/objtool/arch/arm64/include/arch/special.h b/tools/objtool/arch/arm64/include/arch/special.h new file mode 100644 index 000000000000..a82a9b3e51df --- /dev/null +++ b/tools/objtool/arch/arm64/include/arch/special.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _ARM64_ARCH_SPECIAL_H +#define _ARM64_ARCH_SPECIAL_H + +#define EX_ENTRY_SIZE 8 +#define EX_ORIG_OFFSET 0 +#define EX_NEW_OFFSET 4 + +#define JUMP_ENTRY_SIZE 16 +#define JUMP_ORIG_OFFSET 0 +#define JUMP_NEW_OFFSET 4 + +#define ALT_ENTRY_SIZE 12 +#define ALT_ORIG_OFFSET 0 +#define ALT_NEW_OFFSET 4 +#define ALT_FEATURE_OFFSET 8 +#define ALT_ORIG_LEN_OFFSET 10 +#define ALT_NEW_LEN_OFFSET 11 + +#endif /* _ARM64_ARCH_SPECIAL_H */ diff --git a/tools/objtool/arch/arm64/special.c b/tools/objtool/arch/arm64/special.c new file mode 100644 index 000000000000..45f283283091 --- /dev/null +++ b/tools/objtool/arch/arm64/special.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +void arch_handle_alternative(unsigned short feature, struct special_alt *alt) +{ +} + +bool arch_support_alt_relocation(struct special_alt *special_alt, + struct instruction *insn, + struct reloc *reloc) +{ + return false; +} + + +struct reloc *arch_find_switch_table(struct objtool_file *file, + struct instruction *insn) +{ + return NULL; +} diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh index 606a4b5e929f..69e7ebe8911b 100755 --- a/tools/objtool/sync-check.sh +++ b/tools/objtool/sync-check.sh @@ -21,6 +21,11 @@ arch/x86/include/asm/insn.h -I '^#include [\"<]\(asm/\)*inat.h[\">]' arch/x86/lib/inat.c -I '^#include [\"<]\(../include/\)*asm/insn.h[\">]' arch/x86/lib/insn.c -I '^#include [\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]' -I '^#include [\"<]\(../include/\)*asm/emulate_prefix.h[\">]' " +elif [ "$SRCARCH" = "arm64" ]; then +FILES="$FILES +arch/arm64/include/asm/aarch64-insn.h -I '^#include [\"<]\(asm/\)*brk-imm.h[\">]' +arch/arm64/lib/aarch64-insn.c -I '^#include [\"<]\(asm/\)*kprobes.h[\">]' +" fi check_2 () { From patchwork Wed Jan 20 17:37:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367351 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA9D0C43331 for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 90082233EB for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729130AbhATSqw (ORCPT ); Wed, 20 Jan 2021 13:46:52 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:38790 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387575AbhATRjo (ORCPT ); Wed, 20 Jan 2021 12:39:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164297; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5kZxUm2npMwQG1TG1qATstMBS9/a58lwU+qMaeV/pLI=; b=ADEJXoOhqVNUGVjqh+0Axs0I+X4AnFUEl1klJY70TozcHDeFuPrPpRuA7T9OEGwr4NR1F9 SeiEv8Qj8qg9iK6C72DL2968KgmW9QZJxinKEnf8kKzj4+Sjwi4S9A8DSxkxvFstyLFCbD Tr/3Ga3hNw+ewG9Fe/TdJ1GLO1ZGviw= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-113-JrerUjulPCuzuDVDY44GkQ-1; Wed, 20 Jan 2021 12:38:15 -0500 X-MC-Unique: JrerUjulPCuzuDVDY44GkQ-1 Received: by mail-wr1-f72.google.com with SMTP id q18so11966152wrc.20 for ; Wed, 20 Jan 2021 09:38:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5kZxUm2npMwQG1TG1qATstMBS9/a58lwU+qMaeV/pLI=; b=KBMKwDA5S+66Cey6D4OrIuFAI4M6+2TN/XAwUcYj94YRd8lCGqqGB0pks6QerY/s1Y s/g/iN/whdJr0ZU9Ck3jZEW1RzRiXGU7YCjFucz1Unpo/SKF3bOu1+GbPlfPJE0suF8W SYKfBS0aUzqTdi76wC7aZLGDgKDCJTxMdECs+0KijqKqC/jFq78TlJzobTKYRS3TKtSF R+M+DkMLTqwr6f+FLBnSB97qsqtzz/qgGjWjFLCSLN7qkxpp3EU5DpJk3ZQuJUfAr+G/ 9szvci11D78ja4Z1vCUPhJoK0vvUG+xd8do7iuwUKw/LejNK1MNcBAZ25ABQXbPT6f/1 eYOA== X-Gm-Message-State: AOAM531krGcIN09gZlNdfsAgfj2PL0Ec6zWFXyDekvx75blsClG0bEsk PJJ481E4hNX4a52y433RjctSY4LWFMf3OpsFZyCyxVK333cohlQfI3EmZGwEoD4C8+t6Hx+7Z4J RrJcuQL67mu6dkNPvaxzh X-Received: by 2002:adf:8145:: with SMTP id 63mr10098327wrm.8.1611164294397; Wed, 20 Jan 2021 09:38:14 -0800 (PST) X-Google-Smtp-Source: ABdhPJzQzDN3HBtD5u6jA4hqcs01Fugkowpn2vULtp1RxBDFANC375MC0WgDFgHupnT7fa0d1iia8Q== X-Received: by 2002:adf:8145:: with SMTP id 63mr10098306wrm.8.1611164294279; Wed, 20 Jan 2021 09:38:14 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:13 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 05/17] objtool: arm64: Decode add/sub instructions Date: Wed, 20 Jan 2021 18:37:48 +0100 Message-Id: <20210120173800.1660730-6-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Decode aarch64 additions and substractions and create stack_ops for instructions interacting with SP or FP. Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/decode.c | 84 +++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index 8ae822f553ca..0f312dd1b146 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -23,6 +23,13 @@ #include "../../../arch/arm64/lib/aarch64-insn.c" +static unsigned long sign_extend(unsigned long x, int nbits) +{ + unsigned long sign_bit = (x >> (nbits - 1)) & 1; + + return ((~0UL + (sign_bit ^ 1)) << nbits) | x; +} + bool arch_callee_saved_reg(unsigned char reg) { switch (reg) { @@ -98,6 +105,53 @@ int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg) return -1; } +static struct stack_op *arm_make_add_op(enum aarch64_insn_register dest, + enum aarch64_insn_register src, + int val) +{ + struct stack_op *op; + + op = calloc(1, sizeof(*op)); + op->dest.type = OP_DEST_REG; + op->dest.reg = dest; + op->src.reg = src; + op->src.type = val != 0 ? OP_SRC_ADD : OP_SRC_REG; + op->src.offset = val; + + return op; +} + +static void arm_decode_add_sub_imm(u32 instr, bool set_flags, + enum insn_type *type, + unsigned long *immediate, + struct list_head *ops_list) +{ + u32 rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, instr); + u32 rn = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, instr); + + *type = INSN_OTHER; + *immediate = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_12, instr); + + if (instr & AARCH64_INSN_LSL_12) + *immediate <<= 12; + + if ((!set_flags && rd == AARCH64_INSN_REG_SP) || + rd == AARCH64_INSN_REG_FP || + rn == AARCH64_INSN_REG_FP || + rn == AARCH64_INSN_REG_SP) { + struct stack_op *op; + int value; + + if (aarch64_insn_is_subs_imm(instr) || aarch64_insn_is_sub_imm(instr)) + value = -*immediate; + else + value = *immediate; + + op = arm_make_add_op(rd, rn, value); + list_add_tail(&op->list, ops_list); + } +} + int arch_decode_instruction(const struct elf *elf, const struct section *sec, unsigned long offset, unsigned int maxlen, unsigned int *len, enum insn_type *type, @@ -121,6 +175,36 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, case AARCH64_INSN_CLS_UNKNOWN: WARN("can't decode instruction at %s:0x%lx", sec->name, offset); return -1; + case AARCH64_INSN_CLS_DP_IMM: + /* Mov register to and from SP are aliases of add_imm */ + if (aarch64_insn_is_add_imm(insn) || + aarch64_insn_is_sub_imm(insn)) + arm_decode_add_sub_imm(insn, false, type, immediate, + ops_list); + else if (aarch64_insn_is_adds_imm(insn) || + aarch64_insn_is_subs_imm(insn)) + arm_decode_add_sub_imm(insn, true, type, immediate, + ops_list); + else + *type = INSN_OTHER; + break; + case AARCH64_INSN_CLS_DP_REG: + if (aarch64_insn_is_mov_reg(insn)) { + enum aarch64_insn_register rd; + enum aarch64_insn_register rm; + + rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn); + rm = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RM, insn); + if (rd == AARCH64_INSN_REG_FP || rm == AARCH64_INSN_REG_FP) { + struct stack_op *op; + + op = arm_make_add_op(rd, rm, 0); + list_add_tail(&op->list, ops_list); + break; + } + } + *type = INSN_OTHER; + break; default: *type = INSN_OTHER; break; From patchwork Wed Jan 20 17:37:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367352 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75F52C4332E for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4E82B233EB for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387628AbhATSrE (ORCPT ); Wed, 20 Jan 2021 13:47:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:20615 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387691AbhATRjr (ORCPT ); Wed, 20 Jan 2021 12:39:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164301; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ybADuVVj33zXJpBTN6zXgGLfnzshZUI1ojUuRxuiGxo=; b=IRoiuwMiNY+QQxnVSMo7/6CPPzufqAPivop7ams7efCwxaQDMr8fYjEaskDWgRJmOe8Gvg 0I4R75lsO2csRkzMLfdFN2i9mm4ALYTTCWRjC8RNWuZqKtX3mgafOmnjoQwR15emi4M5p5 ths8w+XJ3f1FEp35NYBzq6O3eWNKqtg= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-107-t1PYqZ0gPJqQco4dvbWvmg-1; Wed, 20 Jan 2021 12:38:20 -0500 X-MC-Unique: t1PYqZ0gPJqQco4dvbWvmg-1 Received: by mail-wr1-f69.google.com with SMTP id q2so11965437wrp.4 for ; Wed, 20 Jan 2021 09:38:20 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ybADuVVj33zXJpBTN6zXgGLfnzshZUI1ojUuRxuiGxo=; b=a3htd2N4+/BZSQpFDKirQaoAooUOzrE+UEht19QCZgJrlXo4PCaq4riNIwzLWQ1cf1 M+dmymPRkcbKWSri0Wd8pTNuau9vCgseOPsmL01mhIug3NUzxXMfVqwl4fV48BZZXI3p aeVHaI7r2HMqy6k83M+2TmEYlXNHy390IX1CfDmcHlFydM/H2UjV8a5VvOIxXWoamX8B kGC2+DS57qrfmd2NtBy8gUffd/SUhWEK0Kotw/mX1MIzA0tM9JYFP6mQRctfYi/zai8u exA4Ra3yKeCt8IV1WN62MPs1ApAoXnj0Lr9ZSeLpuhVP827WlGvdxuyMKPeg48G7j8fH XYpg== X-Gm-Message-State: AOAM532I5yhXxdxwYmfaqqZ4hWZAavi4Knuy/Tkm3dOscRlfDQ8zGRvg rUc7Sjvqt0poc0ZrXx3NMFxeL0kAvS+CtnFavKBtyd1MCbZETWvM2DowogO7WmOFb7PXiJfg+Dy 3Tfib0BTxaYlfiysqzX5y X-Received: by 2002:a5d:5917:: with SMTP id v23mr10790331wrd.308.1611164298825; Wed, 20 Jan 2021 09:38:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJwCWhKh32IYPGwQ7eOyS6NFprZttJ5fMUAm09DXGKOoX6f0LQRibhfxka+az9xnCWXYUtnyTw== X-Received: by 2002:a5d:5917:: with SMTP id v23mr10790318wrd.308.1611164298719; Wed, 20 Jan 2021 09:38:18 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:18 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 06/17] objtool: arm64: Decode jump and call related instructions Date: Wed, 20 Jan 2021 18:37:49 +0100 Message-Id: <20210120173800.1660730-7-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Decode branch, branch and link (aarch64's call) and return instructions. Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/decode.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index 0f312dd1b146..924121b4b466 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -205,6 +205,28 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, } *type = INSN_OTHER; break; + case AARCH64_INSN_CLS_BR_SYS: + if (aarch64_insn_is_ret(insn) && + aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, insn) == AARCH64_INSN_REG_LR) { + *type = INSN_RETURN; + } else if (aarch64_insn_is_bl(insn)) { + *type = INSN_CALL; + *immediate = aarch64_get_branch_offset(insn); + } else if (aarch64_insn_is_blr(insn)) { + *type = INSN_CALL_DYNAMIC; + } else if (aarch64_insn_is_b(insn)) { + *type = INSN_JUMP_UNCONDITIONAL; + *immediate = aarch64_get_branch_offset(insn); + } else if (aarch64_insn_is_br(insn)) { + *type = INSN_JUMP_DYNAMIC; + } else if (aarch64_insn_is_branch_imm(insn)) { + /* Remaining branch opcodes are conditional */ + *type = INSN_JUMP_CONDITIONAL; + *immediate = aarch64_get_branch_offset(insn); + } else { + *type = INSN_OTHER; + } + break; default: *type = INSN_OTHER; break; From patchwork Wed Jan 20 17:37:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368201 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E5FEC4332D for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2A32623403 for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387673AbhATSrG (ORCPT ); Wed, 20 Jan 2021 13:47:06 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:52223 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387744AbhATRjv (ORCPT ); Wed, 20 Jan 2021 12:39:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164304; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D/xnDCC8nOFGfsA+lStDur0FhQOLzj3Vyiz97OzDpc8=; b=gUFlrtaEr7qsAtT1h1dRYUW3jycPC8WQ4rOwmnolbIFHWNmPUoEhd6J++ryIQ0s/4aMX4U +XKqAMBV2pEgXfgpI1fPA8ZOlCv7uyZBsetDiK01L6ScObo2dYZ3GzBRCT7EWQQeUILb0c Ow4KS0HV9M9C3pA6pW0OnT9vzBflld8= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-344-cun7JWzdMV64Uq3rRnKJgg-1; Wed, 20 Jan 2021 12:38:22 -0500 X-MC-Unique: cun7JWzdMV64Uq3rRnKJgg-1 Received: by mail-wr1-f69.google.com with SMTP id d7so2797307wri.23 for ; Wed, 20 Jan 2021 09:38:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=D/xnDCC8nOFGfsA+lStDur0FhQOLzj3Vyiz97OzDpc8=; b=MAvxrf708ViZ9jnXrGWKsiEDgKqnikbnkiiKyb47zNQBE0NPdryi11TFWUFt6R0EOo QG6SVgTbma0XW6S+clPLZgWciod2vhG7oWM61DX19ETtPqvJZ6joc9iz7T6tM3rBBMdV HT52pcRxAWu1/ysm0H/9uyuPGw2aIh0GBTeCYEd6cONG+vQ9Zx1pRov2DxLy1/qB8Oi7 gd5UiktMKukt9JZ48tcgjGFn7Nqpa04ivFtoWuDNMXubS4prFibHBij+Uh+4k0rQLGzL 9MueD2Vz3TqtyGVWi9aZ5XXi4uFNDw+lwlwXnbB0ZexnNUcH+olr+firAe8XG0lX5FzP dBEA== X-Gm-Message-State: AOAM532fa/vDtqbUWTZM4TLRp0MIA9zoe5dJwKVtxAefMFCHqzh9fqht W6hb/eKcEniWHUXVpIOSVJY0dK5w8BVWMtTbnWDslzwqgQy2P7rgoBteln7TN7gRfxcbl25JIbe XpXcJM98/hH4k1s2TFTpY X-Received: by 2002:a5d:660c:: with SMTP id n12mr10531780wru.291.1611164300887; Wed, 20 Jan 2021 09:38:20 -0800 (PST) X-Google-Smtp-Source: ABdhPJx5Gt3Pu1qW2EdggZtB7MguFp/4lDK5HfkXjM4AsXdknZgXR2j5+4eIlyKpZr1CO2oaPexByA== X-Received: by 2002:a5d:660c:: with SMTP id n12mr10531762wru.291.1611164300731; Wed, 20 Jan 2021 09:38:20 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:20 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 07/17] objtool: arm64: Decode other system instructions Date: Wed, 20 Jan 2021 18:37:50 +0100 Message-Id: <20210120173800.1660730-8-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Decode ERET, BRK and NOPs Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/decode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index 924121b4b466..a4a587c400a1 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -223,6 +223,13 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, /* Remaining branch opcodes are conditional */ *type = INSN_JUMP_CONDITIONAL; *immediate = aarch64_get_branch_offset(insn); + } else if (aarch64_insn_is_eret(insn)) { + *type = INSN_CONTEXT_SWITCH; + } else if (aarch64_insn_is_steppable_hint(insn)) { + *type = INSN_NOP; + } else if (aarch64_insn_is_brk(insn)) { + *immediate = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_16, insn); + *type = INSN_BUG; } else { *type = INSN_OTHER; } From patchwork Wed Jan 20 17:37:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368202 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D88BC433E9 for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D4535233EB for ; Wed, 20 Jan 2021 19:22:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387718AbhATSrH (ORCPT ); Wed, 20 Jan 2021 13:47:07 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:53120 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387841AbhATRjx (ORCPT ); Wed, 20 Jan 2021 12:39:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164306; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hMguHZY/sCxCSurZhMfyymWiW0UnVLAVgK8Kmo5II94=; b=SwimEIuurf362w7DdAiFG6Z9WwhdF13Urc8ZziqYsrjAjdtg1pm5C7JApYPV6KpsdxJG2b ZhA+x3itdHT4sqsnyxyeGq7n3v9f8n5hwjEuH2bNI3Nl6fTn/W/LQ3Dai2MMiYXey1ADx9 54fmPM9wLm5r7/LsZFXPZevibmckp7U= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-500-SlB0ZcMYMUyi1Ippz8oZdA-1; Wed, 20 Jan 2021 12:38:24 -0500 X-MC-Unique: SlB0ZcMYMUyi1Ippz8oZdA-1 Received: by mail-wr1-f72.google.com with SMTP id r8so11923138wro.22 for ; Wed, 20 Jan 2021 09:38:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hMguHZY/sCxCSurZhMfyymWiW0UnVLAVgK8Kmo5II94=; b=phKDsUBAVkZsQUB5f5NFxoUzYNEXJjrVXtBTW3s/wSz/DJ/l5wlpwV/RouX8cWlzKS HGlsc1epeG4eJT4jWm7mShpSMXNGqPkGRNjoSbmdf0QFOVsSDMlH9batcMvyPOVwoyoh Fx+xipl5vRAP2vcx7GbmVNfS2R8YkFDN1JOVzOOkyKL29Gt272nVelTJsQvUH8Q4kb7Y uVlX22ZbVJSOfI+18rb2jxN8U9CdUL2ZAehq1EB7m+y+Nga96dJ6+arcgr8Ts3ztjcBo Ri564w2vYu1WnYTx2IgqIu/6qRfDhk5DT2GyKU0AtC71zLEAwM+WLCj6r5KVktLaE2xK 9ToA== X-Gm-Message-State: AOAM532WmkbUHF5e426iQQyNiSBRHFSRnMReQlu9age4rXG1fcI6bcFR BD3URJQwBDcS27P6rp4IIQigXa6Zgx4myyPscXbZHoKKclCLVFn3HtEu1ieXj7HrA+EV8Eqqxse Rm1kkl+bHFN3DDu2udFvs X-Received: by 2002:a5d:5112:: with SMTP id s18mr10242710wrt.267.1611164302691; Wed, 20 Jan 2021 09:38:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJwfzo6NlUcDC38dNrSR8pTXGMXlfQTTcZKajys6pTqFZqQ1R+z9gv6rpXRif0O4vIIw0NAjMg== X-Received: by 2002:a5d:5112:: with SMTP id s18mr10242694wrt.267.1611164302569; Wed, 20 Jan 2021 09:38:22 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:22 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 08/17] objtool: arm64: Decode load/store instructions Date: Wed, 20 Jan 2021 18:37:51 +0100 Message-Id: <20210120173800.1660730-9-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Decode load/store operations and create corresponding stack_ops for operations targetting SP or FP. Operations storing/loading multiple registers are split into separate stack_ops storing single registers. Operations modifying the base register get an additional stack_op for the register update. Since the atomic register(s) load/store + base register update gets split into multiple operations, to make sure objtool always sees a valid stack, consider store instruction to perform stack allocations (i.e. modifying the base pointer before the storing) and loads de-allocations (i.e. modifying the base pointer after the load). Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/decode.c | 127 ++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index a4a587c400a1..1087ede67bcd 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -105,6 +105,40 @@ int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg) return -1; } +static struct stack_op *arm_make_store_op(enum aarch64_insn_register base, + enum aarch64_insn_register reg, + int offset) +{ + struct stack_op *op; + + op = calloc(1, sizeof(*op)); + op->dest.type = OP_DEST_REG_INDIRECT; + op->dest.reg = base; + op->dest.offset = offset; + op->src.type = OP_SRC_REG; + op->src.reg = reg; + op->src.offset = 0; + + return op; +} + +static struct stack_op *arm_make_load_op(enum aarch64_insn_register base, + enum aarch64_insn_register reg, + int offset) +{ + struct stack_op *op; + + op = calloc(1, sizeof(*op)); + op->dest.type = OP_DEST_REG; + op->dest.reg = reg; + op->dest.offset = 0; + op->src.type = OP_SRC_REG_INDIRECT; + op->src.reg = base; + op->src.offset = offset; + + return op; +} + static struct stack_op *arm_make_add_op(enum aarch64_insn_register dest, enum aarch64_insn_register src, int val) @@ -121,6 +155,94 @@ static struct stack_op *arm_make_add_op(enum aarch64_insn_register dest, return op; } +static bool arm_decode_load_store(u32 insn, enum insn_type *type, + unsigned long *immediate, + struct list_head *ops_list) +{ + enum aarch64_insn_register base; + enum aarch64_insn_register rt; + struct stack_op *op; + int size; + int offset; + + *type = INSN_OTHER; + + if (aarch64_insn_is_store_single(insn) || + aarch64_insn_is_load_single(insn)) + size = 1 << ((insn & GENMASK(31, 30)) >> 30); + else + size = 4 << ((insn >> 31) & 1); + + if (aarch64_insn_is_store_imm(insn) || aarch64_insn_is_load_imm(insn)) + *immediate = size * aarch64_insn_decode_immediate(AARCH64_INSN_IMM_12, + insn); + else if (aarch64_insn_is_store_pre(insn) || + aarch64_insn_is_load_pre(insn) || + aarch64_insn_is_store_post(insn) || + aarch64_insn_is_load_post(insn)) + *immediate = sign_extend(aarch64_insn_decode_immediate(AARCH64_INSN_IMM_9, + insn), + 9); + else if (aarch64_insn_is_stp(insn) || aarch64_insn_is_ldp(insn) || + aarch64_insn_is_stp_pre(insn) || + aarch64_insn_is_ldp_pre(insn) || + aarch64_insn_is_stp_post(insn) || + aarch64_insn_is_ldp_post(insn)) + *immediate = size * sign_extend(aarch64_insn_decode_immediate(AARCH64_INSN_IMM_7, + insn), + 7); + else + return false; + + base = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, insn); + if (base != AARCH64_INSN_REG_FP && base != AARCH64_INSN_REG_SP) + return true; + + offset = *immediate; + + if (aarch64_insn_is_store_pre(insn) || aarch64_insn_is_stp_pre(insn) || + aarch64_insn_is_store_post(insn) || aarch64_insn_is_stp_post(insn)) { + op = arm_make_add_op(base, base, *immediate); + list_add_tail(&op->list, ops_list); + + if (aarch64_insn_is_store_post(insn) || aarch64_insn_is_stp_post(insn)) + offset = -*immediate; + else + offset = 0; + } else if (aarch64_insn_is_load_post(insn) || aarch64_insn_is_ldp_post(insn)) { + offset = 0; + } + + /* First register */ + rt = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RT, insn); + if (aarch64_insn_is_store_single(insn) || + aarch64_insn_is_store_pair(insn)) + op = arm_make_store_op(base, rt, offset); + else + op = arm_make_load_op(base, rt, offset); + list_add_tail(&op->list, ops_list); + + /* Second register (if present) */ + if (aarch64_insn_is_store_pair(insn) || + aarch64_insn_is_load_pair(insn)) { + rt = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RT2, + insn); + if (aarch64_insn_is_store_pair(insn)) + op = arm_make_store_op(base, rt, offset + size); + else + op = arm_make_load_op(base, rt, offset + size); + list_add_tail(&op->list, ops_list); + } + + if (aarch64_insn_is_load_pre(insn) || aarch64_insn_is_ldp_pre(insn) || + aarch64_insn_is_load_post(insn) || aarch64_insn_is_ldp_post(insn)) { + op = arm_make_add_op(base, base, *immediate); + list_add_tail(&op->list, ops_list); + } + + return true; +} + static void arm_decode_add_sub_imm(u32 instr, bool set_flags, enum insn_type *type, unsigned long *immediate, @@ -234,6 +356,11 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, *type = INSN_OTHER; } break; + case AARCH64_INSN_CLS_LDST: + if (arm_decode_load_store(insn, type, immediate, ops_list)) + break; + *type = INSN_OTHER; + break; default: *type = INSN_OTHER; break; From patchwork Wed Jan 20 17:37:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368208 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E03B9C433DB for ; Wed, 20 Jan 2021 18:47:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB64F233CE for ; Wed, 20 Jan 2021 18:47:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388711AbhATSrJ (ORCPT ); Wed, 20 Jan 2021 13:47:09 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:20795 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388426AbhATRj6 (ORCPT ); Wed, 20 Jan 2021 12:39:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164308; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SLYnG2np6zR1YTUi6SYwuFsGaDYy69xYRKMeP5onVfI=; b=BH+Mq+om61isFKXPAO6czL7qRnSkQdVUt14pQpV5xXjTjxGDjxmU9oMRBq+smfmUaIyP+j XFniDxP6gx482SzAKyGl85PXOBjai70d5ZPHeCWh0YERB69m+tyCLpM+t5l2yIPtA6vVfa HJGh9JMOI4b/a7rY1Y8LMfv21rVnHOE= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-270-0IETbB0pMOW8PMvX7qS_JQ-1; Wed, 20 Jan 2021 12:38:26 -0500 X-MC-Unique: 0IETbB0pMOW8PMvX7qS_JQ-1 Received: by mail-wm1-f69.google.com with SMTP id 5so997778wmq.0 for ; Wed, 20 Jan 2021 09:38:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SLYnG2np6zR1YTUi6SYwuFsGaDYy69xYRKMeP5onVfI=; b=FSo+Dgzjpxlx79mbPiHyyEklHVcBVZriYFoOZIkqDiMu/KjG/pGjBM3JWO10CMGXfQ CIcqfaacbXr9OyLwRTHaIMgrAUedLxK3KPmCHooAlXS3kK5IBCgiJC1fGn1fAQ1fKVRY y2L74meu9OPEmNlZLprDe4r1dBeM3X0/9smmZ+o743/895pfTj2VPjpUYY3i6Za6eRKS Ttexb+j1uSCMoKDhb3u/QCb+zg1unwTY3uuEF+4wIJx4F9/ng5Oayv2L+TOHijfKK3Wj 16gUwAezXGTic/8MfS2svqXxpl1HcKl+bqPAYeplr+VIVI9ScghD8SGteo2Qp96wCjzX GHWQ== X-Gm-Message-State: AOAM5327YkY70sH8XGS/gEPBUvBUlt3CUoOYgGWFbFnCAwd9wOcYixb+ Bc8KmqvGTr3/RelRb2mEeYLBod60ByTwp2TKw6fYJHOrq+xLPMxlOhMTgttLY3ks74qetJbykLZ Vg5n3n81MhhfkyF+O+Ruj X-Received: by 2002:adf:d187:: with SMTP id v7mr10468647wrc.50.1611164305257; Wed, 20 Jan 2021 09:38:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJwXI5rY8SF1/vD1xUKEd0IWosD2vQICkqK1CgWZpdLBSm0Mws61ej9sdam8XkbTpo9ZQuIaXQ== X-Received: by 2002:adf:d187:: with SMTP id v7mr10468627wrc.50.1611164305073; Wed, 20 Jan 2021 09:38:25 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:24 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 09/17] objtool: arm64: Decode LDR instructions Date: Wed, 20 Jan 2021 18:37:52 +0100 Message-Id: <20210120173800.1660730-10-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Load literal instructions can generate constants inside code sections. Record the locations of the constants in order to be able to remove their corresponding "struct instruction". Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/decode.c | 86 ++++++++++++++++++++++++++++ tools/objtool/arch/x86/decode.c | 5 ++ tools/objtool/check.c | 3 + tools/objtool/include/objtool/arch.h | 3 + 4 files changed, 97 insertions(+) diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index 1087ede67bcd..b4d4d5b051b0 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -30,6 +30,73 @@ static unsigned long sign_extend(unsigned long x, int nbits) return ((~0UL + (sign_bit ^ 1)) << nbits) | x; } +struct insn_loc { + const struct section *sec; + unsigned long offset; + struct hlist_node hnode; + bool ignorable; +}; + +DEFINE_HASHTABLE(invalid_insns, 16); + +static int record_invalid_insn(const struct section *sec, + unsigned long offset, + bool ignore) +{ + struct insn_loc *loc; + struct hlist_head *l; + + l = &invalid_insns[hash_min(offset, HASH_BITS(invalid_insns))]; + if (!hlist_empty(l)) { + loc = hlist_entry(l->first, struct insn_loc, hnode); + loc->ignorable |= ignore; + return 0; + } + + loc = malloc(sizeof(*loc)); + if (!loc) { + WARN("malloc failed"); + return -1; + } + + loc->sec = sec; + loc->offset = offset; + loc->ignorable = ignore; + + hash_add(invalid_insns, &loc->hnode, loc->offset); + + return 0; +} + +int arch_post_process_instructions(struct objtool_file *file) +{ + struct hlist_node *tmp; + struct insn_loc *loc; + unsigned int bkt; + int res = 0; + + hash_for_each_safe(invalid_insns, bkt, tmp, loc, hnode) { + struct instruction *insn; + + insn = find_insn(file, (struct section *) loc->sec, loc->offset); + if (insn) { + if (loc->ignorable) { + list_del(&insn->list); + hash_del(&insn->hash); + free(insn); + } else { + WARN_FUNC("can't decode instruction", insn->sec, insn->offset); + return -1; + } + } + + hash_del(&loc->hnode); + free(loc); + } + + return res; +} + bool arch_callee_saved_reg(unsigned char reg) { switch (reg) { @@ -359,6 +426,25 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, case AARCH64_INSN_CLS_LDST: if (arm_decode_load_store(insn, type, immediate, ops_list)) break; + if (aarch64_insn_is_ldr_lit(insn)) { + long pc_offset; + + pc_offset = insn & GENMASK(23, 5); + /* Sign extend and multiply by 4 */ + pc_offset = (pc_offset << (64 - 23)); + pc_offset = ((pc_offset >> (64 - 23)) >> 5) << 2; + + if (record_invalid_insn(sec, offset + pc_offset, true)) + return -1; + + /* 64-bit literal */ + if (insn & BIT(30)) { + if (record_invalid_insn(sec, + offset + pc_offset + 4, + true)) + return -1; + } + } *type = INSN_OTHER; break; default: diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 6baa22732ca6..e76d987ce3c7 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -549,6 +549,11 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, return 0; } +int arch_post_process_instructions(struct objtool_file *file) +{ + return 0; +} + void arch_initial_func_cfi_state(struct cfi_init_state *state) { int i; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 270b507e7098..d902697a388e 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -319,6 +319,9 @@ static int decode_instructions(struct objtool_file *file) if (stats) printf("nr_insns: %lu\n", nr_insns); + if (arch_post_process_instructions(file)) + return -1; + return 0; err: diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h index 6ff0685f5cc5..456d0465b676 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -66,6 +66,7 @@ struct stack_op { struct list_head list; }; +struct objtool_file; struct instruction; void arch_initial_func_cfi_state(struct cfi_init_state *state); @@ -76,6 +77,8 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, unsigned long *immediate, struct list_head *ops_list); +int arch_post_process_instructions(struct objtool_file *file); + bool arch_callee_saved_reg(unsigned char reg); unsigned long arch_jump_destination(struct instruction *insn); From patchwork Wed Jan 20 17:37:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367353 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3152DC43381 for ; Wed, 20 Jan 2021 19:22:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 073C5233FE for ; Wed, 20 Jan 2021 19:22:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387841AbhATSrI (ORCPT ); Wed, 20 Jan 2021 13:47:08 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:35711 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388711AbhATRj6 (ORCPT ); Wed, 20 Jan 2021 12:39:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164312; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TunnN2Rmw/3iiIk96y5NqcKwVnXUUTnNVIzyUwYw5qc=; b=bLssEi5fnN4xUMa1/lfSXAslVrhp3VFTatskxRi6mNlR3KiMxE3C/on9ovYWGB6KtrrZl0 qnfN5BFcrSpDOGHIJa6ZVtCMP0XIpV94Aug1L5P2yFe0JD+fV5gdG81e32vlvNB2gdZvTw sPbz1ZzjvUrCvXIpXxx1KTYVkRmRpyk= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-294-6sEN8mhEPlCz24vWKAqUAw-1; Wed, 20 Jan 2021 12:38:30 -0500 X-MC-Unique: 6sEN8mhEPlCz24vWKAqUAw-1 Received: by mail-wr1-f71.google.com with SMTP id q18so11966435wrc.20 for ; Wed, 20 Jan 2021 09:38:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TunnN2Rmw/3iiIk96y5NqcKwVnXUUTnNVIzyUwYw5qc=; b=qEEiYMqNXaS8ZXN6yvYgJX+C+6bKHXoN7F0HabPIJkVQVIZZRWHaR5eAFvdXqn9mb0 2p6Lj2aR0I5C4qivjZ14+Ppi7zrMPOLT1Ofv1mrFDdU5fEY8uV7N1aCn+nF2SrjDf28k R81GeeQ254jMvty6vXEUzttz0qNfcC3CSOmrA9A9m3+mhEGsO4nSLwlMbmBzg/FPiAUT LtlV2hiplE7fL6b+voGbZl+QShKoGcnGgzjqLa2+hg6sP4Ep7t8ueERsbHJm8Phx/ITj iwNptWd/QWo/O4Htjs/tGttptFD1yeqikmfDe9sIkLMnND6RPx6oiIACe4zpgoFhC+ax MDVw== X-Gm-Message-State: AOAM530tO7eA0379CPDI//q5O7+I29ELmzRQpT2HJUVbU6uM6Zvdb+wD Lp8+IXwTw2MIlEo0Q3zxwyD89dzVk/UWsBeL/rY1fkL+/LZZJu8axFxUjfokWu/crjbsExU2PiB KRJOjC2h5S63gPfNAIE0p X-Received: by 2002:a1c:a501:: with SMTP id o1mr5442917wme.21.1611164309133; Wed, 20 Jan 2021 09:38:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJzdkiqIhQMa9qAcvB3y1xPRPRu1ifQGBBsVjTbJnRN8ssR5UHer5yLxDQqnoMtLa25rFV9xTQ== X-Received: by 2002:a1c:a501:: with SMTP id o1mr5442896wme.21.1611164308963; Wed, 20 Jan 2021 09:38:28 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:28 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 10/17] objtool: arm64: Accept padding in code sections Date: Wed, 20 Jan 2021 18:37:53 +0100 Message-Id: <20210120173800.1660730-11-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The compiler can introduce some '0' words in code sections to pad the end of functions. Similar to load literal functions, record these zero words to remove the "struct instruction" created for them. Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/decode.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c index b4d4d5b051b0..ed5ef0b52bbe 100644 --- a/tools/objtool/arch/arm64/decode.c +++ b/tools/objtool/arch/arm64/decode.c @@ -362,8 +362,23 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, switch (aarch64_get_insn_class(insn)) { case AARCH64_INSN_CLS_UNKNOWN: - WARN("can't decode instruction at %s:0x%lx", sec->name, offset); - return -1; + { + /* + * There are a few reasons we might have non-valid opcodes in + * code sections: + * - For load literal, assembler can generate the data to be + * loaded in the code section + * - Compiler/assembler can generate zeroes to pad function that + * do not end on 8-byte alignment + */ + /* Compiler might put zeroes as padding */ + if (record_invalid_insn(sec, offset, insn == 0x0)) + return -1; + + *type = INSN_OTHER; + + break; + } case AARCH64_INSN_CLS_DP_IMM: /* Mov register to and from SP are aliases of add_imm */ if (aarch64_insn_is_add_imm(insn) || From patchwork Wed Jan 20 17:37:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368203 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF70DC433DB for ; Wed, 20 Jan 2021 19:22:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9638F233FE for ; Wed, 20 Jan 2021 19:22:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390159AbhATSrO (ORCPT ); Wed, 20 Jan 2021 13:47:14 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:31552 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390085AbhATRkO (ORCPT ); Wed, 20 Jan 2021 12:40:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164316; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oGGCmA0OrDAFQ859/Q0LnejciDnPGfHlYFyTyvifQtk=; b=eGmZcYGE0h/Y8fXx0KRtSR1jxg/4LWz6TO2YYAQ3TTNz5kpCOZ17z1q63cidN3Rq5qC9C4 hw53UE7bh/8mzzECZcRarlmJJYtczN1jXOxCb830ORfq7Q2RSSrftTTEIOYAmyAEXgeuK7 TcZonuhbDNcvm12WmniHPHsBxaWgEYQ= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-6-WT4w-_WMOy63MNWG9YnLPg-1; Wed, 20 Jan 2021 12:38:33 -0500 X-MC-Unique: WT4w-_WMOy63MNWG9YnLPg-1 Received: by mail-wr1-f69.google.com with SMTP id z8so11985741wrh.5 for ; Wed, 20 Jan 2021 09:38:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oGGCmA0OrDAFQ859/Q0LnejciDnPGfHlYFyTyvifQtk=; b=LUsbTrQ0GimNbiXOEhMOayQsOAqSMEBsM07l2NGEQ6L0xAp0m75U+9ezcnDraksM0N bs4SgoqVvdw4q93DRQLtLICWhwFS0W+1SSmpBbLieBIe+PGDQ9c46qQS3Lf6DjHRhdGP WagCvTROGjigN+4u6Ky5zvE+pq+UPQSMRNTdADAPmp4QogUdZWCl1pJ5QcaqiLN3UxR3 6T6Cip0tmD8Qwf68cZn+e9uPnldwCUvJIUHMO9cWsJhkgmAvXoGd6MdMHhcDljL6zDZk dVz151d8cHoIG5Vun3DvTcuExTdtPpy26RLGnhCDD6OD0oJhRVgIqKo+uesEbSTZViC4 B9PQ== X-Gm-Message-State: AOAM53048pUOfpgLRzG9h8jU30mC4iY19srRN3ruTTF7F6Vv/iu12iMt ht4G8E8hSAdmypdwAveBFFf3UC49cwQ8W5FeeJcxL0f1GE5p29O+HeOIMtPLjWdlY/8VfMBYoNM LLkJ9H7iiPAAzvck1Ql29 X-Received: by 2002:a5d:4a09:: with SMTP id m9mr10650926wrq.359.1611164311854; Wed, 20 Jan 2021 09:38:31 -0800 (PST) X-Google-Smtp-Source: ABdhPJykIx+mFRDz39bWZUr6EuNu+ftrUmcrlFbF3bvA/9HzFKbHf9ER+LSC2Ppw5dI+TMNMsSLSCQ== X-Received: by 2002:a5d:4a09:: with SMTP id m9mr10650911wrq.359.1611164311737; Wed, 20 Jan 2021 09:38:31 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:31 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 11/17] efi: libstub: Ignore relocations for .discard sections Date: Wed, 20 Jan 2021 18:37:54 +0100 Message-Id: <20210120173800.1660730-12-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org EFI stub cannot have absolute relocations in sections affecting the execution flow. However, for sections that get discarded at link time, it doesn't really matter if they have absolute relocations. Ignore the relocation associated with such sections. Signed-off-by: Julien Thierry --- drivers/firmware/efi/libstub/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 8a94388e38b3..70e9c7f45d30 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -133,7 +133,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE # quiet_cmd_stubcopy = STUBCPY $@ cmd_stubcopy = \ - $(STRIP) --strip-debug -o $@ $<; \ + $(STRIP) --strip-debug --remove-relocations=".discard.*" -o $@ $<; \ if $(OBJDUMP) -r $@ | grep $(STUBCOPY_RELOC-y); then \ echo "$@: absolute symbol references not allowed in the EFI stub" >&2; \ /bin/false; \ From patchwork Wed Jan 20 17:37:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368207 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E98CC433E0 for ; Wed, 20 Jan 2021 18:48:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BE77620575 for ; Wed, 20 Jan 2021 18:48:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732223AbhATSrt (ORCPT ); Wed, 20 Jan 2021 13:47:49 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:44646 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390112AbhATRkO (ORCPT ); Wed, 20 Jan 2021 12:40:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164318; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HHhNdzHCl7p80Y/M7nY7DxKk34o5+fUa+j9rxomz5s4=; b=ZggiUkzsz3LLmNMwGw4MR9ModJKot9da7BJxWVJPIbDaAzDMwll3mLXVyCHsb4gCk1Kihy trMfI/1/ZhpVQFyZ/JUEY53DZ7a0lIaNQXker32jV2or7ol1brSOS4hYR5djJ/pPXRFpZY vZv+c5wgt4fknxqEoJFvQa1q22xboUk= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-404-ZdZmG3OsM32cb4tRupA6PQ-1; Wed, 20 Jan 2021 12:38:37 -0500 X-MC-Unique: ZdZmG3OsM32cb4tRupA6PQ-1 Received: by mail-wm1-f72.google.com with SMTP id k67so1829279wmk.5 for ; Wed, 20 Jan 2021 09:38:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HHhNdzHCl7p80Y/M7nY7DxKk34o5+fUa+j9rxomz5s4=; b=PR+87OqL+8MsnsHpIx3qYKcg/zKvCKCIEYVx0ttryStIBhkVDHXNfNFbocP7prtEQT QJe2gnYDsiz4ar9MJIOSK4Mlsx7RiX4LfQ1ut5qE6qJyYhqyk3TRYoklXjVQaT85sv9B J/pr7K7lzwb+mPGIsXi9zhcw48o/P8itathDBgh6ORb20JuoSG/ekclrJZSvXY8uleII dV5G6cxgZ0NFwOKGpUv/qw5JokqRmIz1VYGvoGyfHMuUBkCniZC7QVp+mRdWecij/EnI GfWiPpVyidnibRZ2cdoC9GdQiWJroCHcOlIFTZeEHT6m8n6rfovXDkyegXYqcK4zEJ/q Y/7g== X-Gm-Message-State: AOAM5303tOwDXSEozJBZ54IKmRSTyBjkgDzY3l/nbrQRJi8ZceeoebZo yME4qXVc8dNMtckwz//FesrhMxu0C6XWb0AHfAFAVcAj0RUeYKSqufwl/MNnxC9IasH5uGIqeQI ApiVC8rfY4BUHLhSoBP/t X-Received: by 2002:a5d:40d2:: with SMTP id b18mr10109908wrq.369.1611164315798; Wed, 20 Jan 2021 09:38:35 -0800 (PST) X-Google-Smtp-Source: ABdhPJwjV6xTRe8CsL12wyOOS7WHO27yHrkDMb/ei4CrUSn1wqWS6eScNSd6CJ15BCe3ivDz3BoWUQ== X-Received: by 2002:a5d:40d2:: with SMTP id b18mr10109889wrq.369.1611164315617; Wed, 20 Jan 2021 09:38:35 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:35 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Raphael Gault , Julien Thierry Subject: [RFC PATCH 12/17] gcc-plugins: objtool: Add plugin to detect switch table on arm64 Date: Wed, 20 Jan 2021 18:37:55 +0100 Message-Id: <20210120173800.1660730-13-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Raphael Gault This plugins comes into play before the final 2 RTL passes of GCC and detects switch-tables that are to be outputed in the ELF and writes information in an ".discard.switch_table_info" section which will be used by objtool. Signed-off-by: Raphael Gault [J.T.: Change section name to store switch table information, Make plugin Kconfig be selected rather than opt-in by user, Add a relocation in the switch_table_info that points to the jump operation itself] Signed-off-by: Julien Thierry --- arch/arm64/Kconfig | 1 + scripts/Makefile.gcc-plugins | 2 + scripts/gcc-plugins/Kconfig | 4 + .../arm64_switch_table_detection_plugin.c | 85 +++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 scripts/gcc-plugins/arm64_switch_table_detection_plugin.c diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 05e17351e4f3..93a320cc8e03 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -100,6 +100,7 @@ config ARM64 select DMA_DIRECT_REMAP select EDAC_SUPPORT select FRAME_POINTER + select GCC_PLUGIN_SWITCH_TABLES if STACK_VALIDATION select GENERIC_ALLOCATOR select GENERIC_ARCH_TOPOLOGY select GENERIC_CLOCKEVENTS_BROADCAST diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 952e46876329..8af322311f6b 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -46,6 +46,8 @@ ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK endif export DISABLE_ARM_SSP_PER_TASK_PLUGIN +gcc-plugin-$(CONFIG_GCC_PLUGIN_SWITCH_TABLES) += arm64_switch_table_detection_plugin.so + # All the plugin CFLAGS are collected here in case a build target needs to # filter them out of the KBUILD_CFLAGS. GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index ab9eb4cbe33a..76efbb97d223 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -104,4 +104,8 @@ config GCC_PLUGIN_ARM_SSP_PER_TASK bool depends on GCC_PLUGINS && ARM +config GCC_PLUGIN_SWITCH_TABLES + bool + depends on GCC_PLUGINS && ARM64 + endif diff --git a/scripts/gcc-plugins/arm64_switch_table_detection_plugin.c b/scripts/gcc-plugins/arm64_switch_table_detection_plugin.c new file mode 100644 index 000000000000..60ef00ff2c5b --- /dev/null +++ b/scripts/gcc-plugins/arm64_switch_table_detection_plugin.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include "gcc-common.h" + +__visible int plugin_is_GPL_compatible; + +#define GEN_QUAD(rtx) assemble_integer_with_op(".quad ", rtx) + +/* + * Create an array of metadata for each jump table found in the rtl. + * The metadata contains: + * - A reference to first instruction part of the RTL expanded into an + * acutal jump + * - The number of entries in the table of offsets + * - A reference to each possible jump target + * + * Separate each entry with a null quad word. + */ +static unsigned int arm64_switchtbl_rtl_execute(void) +{ + rtx_insn *insn; + rtx_insn *labelp = NULL; + rtx_jump_table_data *tablep = NULL; + section *swt_sec; + section *curr_sec = current_function_section(); + + swt_sec = get_section(".discard.switch_table_info", + SECTION_DEBUG | SECTION_EXCLUDE, NULL); + + for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) { + /* + * Find a tablejump_p INSN (using a dispatch table) + */ + if (!tablejump_p(insn, &labelp, &tablep)) + continue; + + if (labelp && tablep) { + rtx_code_label *label_to_jump; + rtvec jump_labels = tablep->get_labels(); + int nr_labels = GET_NUM_ELEM(jump_labels); + int i; + + label_to_jump = gen_label_rtx(); + SET_LABEL_KIND(label_to_jump, LABEL_NORMAL); + emit_label_before(label_to_jump, insn); + LABEL_PRESERVE_P(label_to_jump) = 1; + + switch_to_section(swt_sec); + GEN_QUAD(GEN_INT(0)); // mark separation between rela tables + GEN_QUAD(gen_rtx_LABEL_REF(Pmode, label_to_jump)); + GEN_QUAD(GEN_INT(nr_labels)); + for (i = 0; i < nr_labels; i++) + GEN_QUAD(gen_rtx_LABEL_REF(Pmode, + label_ref_label(RTVEC_ELT(jump_labels, i)))); + switch_to_section(curr_sec); + delete_insn(label_to_jump); + } + } + return 0; +} + +#define PASS_NAME arm64_switchtbl_rtl + +#define NO_GATE +#include "gcc-generate-rtl-pass.h" + +__visible int plugin_init(struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; + + if (!plugin_default_version_check(version, &gcc_version)) { + error(G_("incompatible gcc/plugin versions")); + return 1; + } + + PASS_INFO(arm64_switchtbl_rtl, "final", 1, + PASS_POS_INSERT_BEFORE); + + register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, + NULL, &arm64_switchtbl_rtl_pass_info); + + return 0; +} From patchwork Wed Jan 20 17:37:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 368206 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A08FCC43381 for ; Wed, 20 Jan 2021 18:48:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5A0C4233CE for ; Wed, 20 Jan 2021 18:48:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390148AbhATSrp (ORCPT ); Wed, 20 Jan 2021 13:47:45 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:22105 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390153AbhATRkO (ORCPT ); Wed, 20 Jan 2021 12:40:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164321; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ItOqFi7Hkwlfc8KmljIH1mggd+0HU8t9o2eCKjOp56I=; b=ijE99I4Yucd8Y6nh5XnVLMTyvCbWbFYR+PZox87tVKXwySkxckvFMzOnqf3jMw5k0UJWbB yOuaJch9u974dJWiIRmXKBv68SPyNsjq+zR+Ds5nVzt2hVP7pQNHZ7HW0Z7Q/O4gsbE892 4GX2n2e4tjpORy2keLs+nuMQLIe6WUE= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-273-TgnogpXVPLmsO6ISG5El4g-1; Wed, 20 Jan 2021 12:38:39 -0500 X-MC-Unique: TgnogpXVPLmsO6ISG5El4g-1 Received: by mail-wr1-f70.google.com with SMTP id y4so1505430wrt.18 for ; Wed, 20 Jan 2021 09:38:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ItOqFi7Hkwlfc8KmljIH1mggd+0HU8t9o2eCKjOp56I=; b=DJbzs8Y8lFujqljs2WtvI6TglheyKyoZOUTecyy4bwYfAsSlp2ShHEpp/4jHJ+LY8J 3oa9r4nj40BlSAc2blVpDDXm3Eg7YAFj2RXkUQRVn4GsF+X8fCZF8VQWxMLTI8X3NpNz MBCcXxg5mmDSPyvpGkOSkDcrbHkmyL7aY9HO5QHenBniGIWxxVGxp96BGHi2DW0Dc9in TLqyAohDa0lnWLO3kJfB30jK5cDDMF/ilPx7P7RHOEMW+CgFuhUT45ncbj5VsbYmVhMx YpRIIkoAfptxGxKUOvI5SZzQkbR2FnCZctrb5xuzCNNQSelKbEXrGoZwrCqotVKZgum6 rlTg== X-Gm-Message-State: AOAM530kiorB7L04Bo3j5yIlIstGQUtzMh17D1dv2gbOlh533sWGNFqw vyw4RZ07q1WQSnNfpJLWTBU3eKJM2DGO1dF0MHub+mAusNkyfwHKywtfz8l2M0QeAJn/Ph1AGM7 Kn8ishwwZpzts4DQ3EEbY X-Received: by 2002:adf:e705:: with SMTP id c5mr10165904wrm.303.1611164318293; Wed, 20 Jan 2021 09:38:38 -0800 (PST) X-Google-Smtp-Source: ABdhPJyI7z1jfE1krdbjitvV3YQPLDza0TWB9nv2zK4QcJTxmxyvfDnFk8J4YJ4dvyZr3q+eSQSNsg== X-Received: by 2002:adf:e705:: with SMTP id c5mr10165894wrm.303.1611164318164; Wed, 20 Jan 2021 09:38:38 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:37 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry , Raphael Gault Subject: [RFC PATCH 13/17] objtool: arm64: Implement functions to add switch tables alternatives Date: Wed, 20 Jan 2021 18:37:56 +0100 Message-Id: <20210120173800.1660730-14-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org This patch implements the functions required to identify and add as alternatives all the possible destinations of the switch table. This implementation relies on the new plugin introduced previously which records information about the switch-table in a .discard.switch_table_information section. Signed-off-by: Raphael Gault [J.T.: Update arch implementation to new prototypes, Update switch table information section name, Do some clean up, Use the offset sign information, Use the newly added rela to find the corresponding jump instruction] Signed-off-by: Julien Thierry --- .../objtool/arch/arm64/include/arch/special.h | 2 + tools/objtool/arch/arm64/special.c | 85 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/tools/objtool/arch/arm64/include/arch/special.h b/tools/objtool/arch/arm64/include/arch/special.h index a82a9b3e51df..b96bcee308cf 100644 --- a/tools/objtool/arch/arm64/include/arch/special.h +++ b/tools/objtool/arch/arm64/include/arch/special.h @@ -3,6 +3,8 @@ #ifndef _ARM64_ARCH_SPECIAL_H #define _ARM64_ARCH_SPECIAL_H +#include + #define EX_ENTRY_SIZE 8 #define EX_ORIG_OFFSET 0 #define EX_NEW_OFFSET 4 diff --git a/tools/objtool/arch/arm64/special.c b/tools/objtool/arch/arm64/special.c index 45f283283091..396b9c5feebd 100644 --- a/tools/objtool/arch/arm64/special.c +++ b/tools/objtool/arch/arm64/special.c @@ -1,6 +1,26 @@ // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include + +#include + #include +#include +#include + +/* + * The arm64_switch_table_detection_plugin generate an array of elements + * described by the following structure. + * Each jump table found in the compilation unit is associated with one of + * entries of the array. + */ +struct switch_table_info { + u64 padding; + u64 jump_ref; + u64 nb_entries; + u64 dest_relocations[]; +} __attribute__((__packed__)); void arch_handle_alternative(unsigned short feature, struct special_alt *alt) { @@ -14,8 +34,73 @@ bool arch_support_alt_relocation(struct special_alt *special_alt, } +/* + * Aarch64 jump tables are just arrays of offsets (of varying size/signess) + * representing the potential destination from a base address loaded by an adr + * instruction. + * + * Sadly, extracting the actual offset might require to consider multiple + * instructions and decoding them to understand what they do. To make life + * easier, the gcc plugin will generate a list of relocation entries for + * each jump table target, conforming to the format expected by + * add_jump_table(). + * + * Aarch64 branches to jump tables are composed of multiple instructions: + * + * ldr x_offset, [x_offsets_table, x_index, ...] + * adr x_dest_base, + * add x_dest, x_target_base, x_offset, ... + * br x_dest + * + * The arm64_switch_table_detection_plugin will make the connection between + * the instruction setting x_offsets_table (jump_ref) and the list of + * relocations. + */ struct reloc *arch_find_switch_table(struct objtool_file *file, struct instruction *insn) { + struct switch_table_info *sti; + struct section *table_info_sec; + void *sti_sec_start; + struct reloc *text_reloc; + + table_info_sec = find_section_by_name(file->elf, + ".discard.switch_table_info"); + if (!table_info_sec) + goto try_c_jmptbl; + + sti_sec_start = table_info_sec->data->d_buf; + sti = sti_sec_start; + + while ((char *)sti - (char *)sti_sec_start < table_info_sec->len) { + struct reloc *target_reloc = find_reloc_by_dest(file->elf, + table_info_sec, + (char *)&sti->jump_ref - (char *)sti_sec_start); + + if (!target_reloc) { + WARN("Malformed switch table entry"); + return NULL; + } + + if (target_reloc->sym->sec == insn->sec && + target_reloc->addend == insn->offset) + return find_reloc_by_dest(file->elf, table_info_sec, + (char *)&sti->dest_relocations[0] - (char *)sti_sec_start); + + /* Get next jump table entry */ + sti = (struct switch_table_info *) (&sti->dest_relocations[0] + sti->nb_entries); + } + +try_c_jmptbl: + text_reloc = find_reloc_by_dest(file->elf, insn->sec, insn->offset); + if (!text_reloc || text_reloc->sym->type != STT_SECTION || + !text_reloc->sym->sec->rodata) + return NULL; + + /* Handle C jump tables */ + if (!strcmp(text_reloc->sym->sec->name, C_JUMP_TABLE_SECTION)) + return find_reloc_by_dest(file->elf, text_reloc->sym->sec, + text_reloc->addend); + return NULL; } From patchwork Wed Jan 20 17:37:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367358 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 208B8C43381 for ; Wed, 20 Jan 2021 18:47:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E3B2222473 for ; Wed, 20 Jan 2021 18:47:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388426AbhATSrM (ORCPT ); Wed, 20 Jan 2021 13:47:12 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:47093 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390159AbhATRkO (ORCPT ); Wed, 20 Jan 2021 12:40:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164324; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h+7NJAZ5HEs+o3c9ngN8mAhWOXYs+DN99Jpiq66kpMs=; b=D3qNyoZVcvH8C0V2VVeWeUCOpamLcnYtoxeqHM4csD5Ul+uhJD07H9Ep/K+ziBElpjZDdp C8hfmdy9wmXUZFJz80GrkVHSUkVzOCb4UNijqSEb2mGDz4c85OdnAa3DWu6UeU86KZFlPc 0y840ETW9Yxp9W8L5+oDauA8Y3TQEcI= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-523-N92naAeXMVy1f0CzKoWd9w-1; Wed, 20 Jan 2021 12:38:43 -0500 X-MC-Unique: N92naAeXMVy1f0CzKoWd9w-1 Received: by mail-wm1-f69.google.com with SMTP id s24so1831824wmj.3 for ; Wed, 20 Jan 2021 09:38:42 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=h+7NJAZ5HEs+o3c9ngN8mAhWOXYs+DN99Jpiq66kpMs=; b=aLqOLdAMUYesM3osgNtqeBnt9wk2sRvW8trhOVWyECw22u7cWkmq+NYYxP0R6RQDko xSXa7tr49x+lQAQ4Kfu+ZvPEMwbt/O15fKQHefG1RJ59ul9ocg1W0WXMzxG68XLWPWHd OcXTD3wITSwLVZHpzuSllRMH30X96cn2tFZn7MSfQHtwJoGf0QeffLkPKrmKo8q1g5oL 286DfBACeRsAQW0ow2qoV2xiGzbFydgkz+1YC4wkjqM1xdLEAyjvbsXAyA85+3c+UnYB kczyecCyM6ji4fDgscR4UP4bZ+Ncvaa3LH4jTJUDEQfgXpkgHoEj4GuwT77jLWYsSZsm NmCQ== X-Gm-Message-State: AOAM533aC9Q49jbbX7s0zUFSimsKVV32WQaLzi1j8yT5/3fhE68OHfJ8 H69MnP1OFsDShPCaEbQQMVcYhv2a+epO6e5A7m3t2zVi4uB9CddiRUp/P3EzRzwRrW9ie6SOEPB Kl+kFc4XFcVaqh+ZSRIU3 X-Received: by 2002:adf:fa92:: with SMTP id h18mr4344309wrr.142.1611164320484; Wed, 20 Jan 2021 09:38:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJzDeWheflvYEpolU09LBJTJ+72qBUJL1UqdbbjxQT7QJExRg0tyCLTSK2CpCQqblVViiEwsaA== X-Received: by 2002:adf:fa92:: with SMTP id h18mr4344296wrr.142.1611164320375; Wed, 20 Jan 2021 09:38:40 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:40 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 14/17] objtool: arm64: Cache section with switch table information Date: Wed, 20 Jan 2021 18:37:57 +0100 Message-Id: <20210120173800.1660730-15-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Section ".discard.switch_table_info", created by the gcc plugin will be looked up for every dynamic jump in the object file while the section might not even exist. Cache the result of the first lookup. Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/special.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/objtool/arch/arm64/special.c b/tools/objtool/arch/arm64/special.c index 396b9c5feebd..c9c3e0bfd581 100644 --- a/tools/objtool/arch/arm64/special.c +++ b/tools/objtool/arch/arm64/special.c @@ -33,6 +33,19 @@ bool arch_support_alt_relocation(struct special_alt *special_alt, return false; } +static struct section *get_switch_table_info_section(struct objtool_file *file) +{ + static bool first = true; + static struct section *info_section = NULL; + + if (first) { + first = false; + info_section = find_section_by_name(file->elf, + ".discard.switch_table_info"); + } + + return info_section; +} /* * Aarch64 jump tables are just arrays of offsets (of varying size/signess) @@ -64,8 +77,7 @@ struct reloc *arch_find_switch_table(struct objtool_file *file, void *sti_sec_start; struct reloc *text_reloc; - table_info_sec = find_section_by_name(file->elf, - ".discard.switch_table_info"); + table_info_sec = get_switch_table_info_section(file); if (!table_info_sec) goto try_c_jmptbl; From patchwork Wed Jan 20 17:37:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367356 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2D7AC433E0 for ; Wed, 20 Jan 2021 18:49:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 583F022473 for ; Wed, 20 Jan 2021 18:49:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389673AbhATSrc (ORCPT ); Wed, 20 Jan 2021 13:47:32 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:48678 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390156AbhATRkO (ORCPT ); Wed, 20 Jan 2021 12:40:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164325; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yRnNjmYT/ZeNDPernGD7mn1nezFUsPnB2CCiwO9XXDo=; b=eqojv05tKpkrWvVh6rF5Qcj8bp4JrIvQEj0sDladv/cTL8YKVZW2DgRq6dsiAXLTu5dlsb XjUY5tjFX7dUKXmRnEGYOQUVRYh0BXE5i0TPBzTQwYNoSfYxmPye98CY/rIr+BEXRZZvlU E4YlD/kBFFVLtc9K2CLbMIdzkZNEzow= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-94-UDSbkgCIPr69vNnAO5LMcg-1; Wed, 20 Jan 2021 12:38:43 -0500 X-MC-Unique: UDSbkgCIPr69vNnAO5LMcg-1 Received: by mail-wm1-f69.google.com with SMTP id u67so1887403wmb.0 for ; Wed, 20 Jan 2021 09:38:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yRnNjmYT/ZeNDPernGD7mn1nezFUsPnB2CCiwO9XXDo=; b=DW6Cjp/HRs0eMzBuW3F90OB0Nz6VgONbosDXoRAproz2J8T+dWufIiT3I0XF9IVfPA VXnFUde4/5zYi02B9BYq/HEMBd11rXMgGxq3qkEdHPJg9/RTeSVPxjaNRqzr8J3lFA/h /fsL78iu8IN03JEgWKN+ngYZ9t1dp5WKqkAy2DH9cObcWjoiLQNgjT3843xitfePayje gi2EEYNZYYtyJDvSWFl15vMp53Ku/3RREIBuodtCtl9T6mtD7UN6Xj0TNb59DshtQQXB oD/8yujMhIrLGginmWZouwsbGBYBzG3ovhVFbbcJnUE28zvgXsWkQ2wENYzC7lYf9zME 49qA== X-Gm-Message-State: AOAM530GgLWzr+V3HvzE8VQEVZNTscxqUr9jS+JgVKez13wLMwczRzlw j+tBi3nQpLm5g6fmBjNVvsO+ru85Wqomw8vc60qFmRCLMTLk7+1L7KfbSm1aJcVrWJEVrHsgyVC U4CSGvHRoN/t/dgm0ja// X-Received: by 2002:a05:6000:18a3:: with SMTP id b3mr10468150wri.373.1611164322333; Wed, 20 Jan 2021 09:38:42 -0800 (PST) X-Google-Smtp-Source: ABdhPJxEuPLL/MUsHXrjcP2RWYCjypmma6HnlV61saf901CvvVF6JcK5tnGFyGuV8565mW/HkAJnQw== X-Received: by 2002:a05:6000:18a3:: with SMTP id b3mr10468144wri.373.1611164322230; Wed, 20 Jan 2021 09:38:42 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:41 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 15/17] objtool: arm64: Handle supported relocations in alternatives Date: Wed, 20 Jan 2021 18:37:58 +0100 Message-Id: <20210120173800.1660730-16-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Based on get_alt_insn() in arch/arm64/kernel/alternative.c, arm64 alternative code adapts offsets for static branches and adrp instructions. Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/special.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/objtool/arch/arm64/special.c b/tools/objtool/arch/arm64/special.c index c9c3e0bfd581..d47e5590ed60 100644 --- a/tools/objtool/arch/arm64/special.c +++ b/tools/objtool/arch/arm64/special.c @@ -30,7 +30,11 @@ bool arch_support_alt_relocation(struct special_alt *special_alt, struct instruction *insn, struct reloc *reloc) { - return false; + u32 opcode = *(u32 *)(insn->sec->data->d_buf + insn->offset); + + return aarch64_insn_is_branch_imm(opcode) || + aarch64_insn_is_adrp(opcode) || + !aarch64_insn_uses_literal(opcode); } static struct section *get_switch_table_info_section(struct objtool_file *file) From patchwork Wed Jan 20 17:37:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367354 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4E72C433E0 for ; Wed, 20 Jan 2021 19:22:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77D9B233EB for ; Wed, 20 Jan 2021 19:22:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389952AbhATSrQ (ORCPT ); Wed, 20 Jan 2021 13:47:16 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:38703 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390201AbhATRkO (ORCPT ); Wed, 20 Jan 2021 12:40:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164326; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9GqcdDd08Zk15EP4JDTkI5z15oNQedvKunbBtce3hNY=; b=WJRLkgvbY5DXeyGg+gO6NxUuotjuuSXTKqmR+EzbiByNmPyy9A0XUX3cUXqp+iPbdaZMwC E4kVaGCgwG+3lJigD7ZLcSjMxBoTI4nJF/2iob2zGpgatyzgUQah0pH+/Rr8hETzZZdnkm NX0iONWzYds7ufii7etU1I1c+gayre0= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-276-lu62xhX5P1-FwCTqbKUMIQ-1; Wed, 20 Jan 2021 12:38:45 -0500 X-MC-Unique: lu62xhX5P1-FwCTqbKUMIQ-1 Received: by mail-wr1-f71.google.com with SMTP id q2so11966073wrp.4 for ; Wed, 20 Jan 2021 09:38:44 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9GqcdDd08Zk15EP4JDTkI5z15oNQedvKunbBtce3hNY=; b=IEDWjfoIGlFl2p0+yE0czt8sOJ6hnOAAOcghrFfwJ4DrSseqAtx9BxPYbW/GOKqK3y yjzpXYuti0z6yMiY3P9wKron+kUIj8MN/Q1ZOlPLa9queX0+7rXttQUaxfBiXFyo0rZR EDF95lo5FdL1M+ZlGfvSt6p+kkE2rk2gDXSQ8Ro2dlXIDQxQKeMgTwyW8SmPVobgC13R iCZSuEMtjr9AznpG6o+oti+K5UrbAt7hmTAxFVQS1FyMdiy57g925DsKwg9xaYkI0TVt LYIXsWZsekurBmCW60GC3yTsP65tKRCKFkNmcjpm8McPTfzMFMSxGuZxXW5rwsdiwa6t BK/w== X-Gm-Message-State: AOAM532jIWwwOzrJdrsb0U6ceVNOgEqwAP6y0zEYtS0y8hgzY8s2vVeQ 90Sj+8vZIZigYa4SFAiVi9k0JQAQlb5v8hiXTgEdcBd8ZyPg9Y8XKiG02/Kxm4EaEPMwJUh9olQ JRs2WDBMQkIWXRn7TrrEa X-Received: by 2002:a1c:6a02:: with SMTP id f2mr5525600wmc.36.1611164323970; Wed, 20 Jan 2021 09:38:43 -0800 (PST) X-Google-Smtp-Source: ABdhPJz3m5zpvqhoSgn4NA796inwCeJU9v3FtPD1K/BYY6WVb/FI0tRzJHQ322lTzH3clEsPdXWdpg== X-Received: by 2002:a1c:6a02:: with SMTP id f2mr5525587wmc.36.1611164323845; Wed, 20 Jan 2021 09:38:43 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:43 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Julien Thierry Subject: [RFC PATCH 16/17] objtool: arm64: Ignore replacement section for alternative callback Date: Wed, 20 Jan 2021 18:37:59 +0100 Message-Id: <20210120173800.1660730-17-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org ARM64_CB_PATCH doesn't have static replacement instructions. Skip trying to validate the alternative section. Signed-off-by: Julien Thierry --- tools/objtool/arch/arm64/special.c | 12 ++++++++++++ tools/objtool/check.c | 3 +++ 2 files changed, 15 insertions(+) diff --git a/tools/objtool/arch/arm64/special.c b/tools/objtool/arch/arm64/special.c index d47e5590ed60..aff8577e71e9 100644 --- a/tools/objtool/arch/arm64/special.c +++ b/tools/objtool/arch/arm64/special.c @@ -24,6 +24,18 @@ struct switch_table_info { void arch_handle_alternative(unsigned short feature, struct special_alt *alt) { + if (alt->orig_len && !alt->new_len) { + /* + * ARM64_CB_PATCH has no alternative instruction. + * a callback is called at alternative replacement time + * to dynamically change the original instructions. + * + * ARM64_CB_PATCH is the last ARM64 feature, it's value changes + * every time a new feature is added. So the orig/alt region + * length are used to detect those alternatives + */ + alt->skip_alt = true; + } } bool arch_support_alt_relocation(struct special_alt *special_alt, diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d902697a388e..8840af09f843 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1182,6 +1182,9 @@ static int add_special_section_alts(struct objtool_file *file) continue; } + if (special_alt->skip_alt && !special_alt->new_len) + continue; + ret = handle_group_alt(file, special_alt, orig_insn, &new_insn); if (ret) From patchwork Wed Jan 20 17:38:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 367357 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C3D5C433E6 for ; Wed, 20 Jan 2021 18:48:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2BE9220575 for ; Wed, 20 Jan 2021 18:48:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390254AbhATSrw (ORCPT ); Wed, 20 Jan 2021 13:47:52 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:50531 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390320AbhATRkR (ORCPT ); Wed, 20 Jan 2021 12:40:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611164331; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oYWTEQ/huFSMzsrpwj0azmoT19+DGoe9MjwOTg0OH5c=; b=OYOW84UWpt+8SUrCbZAXXaai1E8SVi2esOyGtPEoAUgM7Ykdk5Hpeb+9DLL21tqsH6r2c2 WHoxF3GgSNVb+Bp6M4i2GrHcIBBfXJjDRhcG7mp62wSQ0mUAkReXWpz5vehfRIHKxKGlQY zuMEMbZD9XgFe7fuOSGjQ9k4W4vUJgk= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-456-svp07V-tOqOl1PmP0_VJlA-1; Wed, 20 Jan 2021 12:38:47 -0500 X-MC-Unique: svp07V-tOqOl1PmP0_VJlA-1 Received: by mail-wm1-f70.google.com with SMTP id f16so1819356wmq.7 for ; Wed, 20 Jan 2021 09:38:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oYWTEQ/huFSMzsrpwj0azmoT19+DGoe9MjwOTg0OH5c=; b=A2OHoZSgODa1ImkGqbgpFXTisvYUbCegR4CphhLKci02K6m3Stw/Um8w9/5w2v/1O6 G2IMcVv9K2l3Ublt+AX/JHfobjkAPupp5d7/hvWnPi31xd2tRozLbA+w9a+qxVrH/+x/ GekVTFkhohfu6UL8ad61qJ8MosrQDxiPYrt/rDsac+5NHCuE6YA7VJv5HaMGOVUsnrWE RyFqB3P/WeTEBxXiKBDHD3RpW9eU20gdfBpiQnx4XFSEOU0YIctY9GVyQkoC5VOdobsr r0n64KqKNiwUXAkB4qYvwP9GiIeeNPLf9KzUXMsEEC17mYDyvsUCLxIX0wOPhZwCdt+s WKXA== X-Gm-Message-State: AOAM531xpVm+L4PvXD7i9HTQObiC1MtUcj6icwt0Z8+P3XUlsISvFpWo V6BV1klabviI172hG/R4MCIzyF9TgUyNHd/zsXLVqJdm0efI8o8ts9uxdGmCmwT5G5dfPbRNsqS VKPnmfaYBYV47P4UTJdeg X-Received: by 2002:a1c:9dd5:: with SMTP id g204mr5387434wme.37.1611164326104; Wed, 20 Jan 2021 09:38:46 -0800 (PST) X-Google-Smtp-Source: ABdhPJxTEEAVF5Wb5DvfyKAa6iIpcJZxKaj/uKR/NeIqD5Cr6bWjyZklj7zuAijYtvvTiqRBg2VXRA== X-Received: by 2002:a1c:9dd5:: with SMTP id g204mr5387418wme.37.1611164325951; Wed, 20 Jan 2021 09:38:45 -0800 (PST) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id x11sm4948325wmi.4.2021.01.20.09.38.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jan 2021 09:38:45 -0800 (PST) From: Julien Thierry To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: catalin.marinas@arm.com, will@kernel.org, ardb@kernel.org, masahiroy@kernel.org, keescook@chromium.org, michal.lkml@markovi.net, jpoimboe@redhat.com, peterz@infradead.org, mark.rutland@arm.com, broonie@kernel.org, linux-efi@vger.kernel.org, linux-hardening@vger.kernel.org, Raphael Gault , Julien Thierry Subject: [RFC PATCH 17/17] objtool: arm64: Enable stack validation for arm64 Date: Wed, 20 Jan 2021 18:38:00 +0100 Message-Id: <20210120173800.1660730-18-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20210120173800.1660730-1-jthierry@redhat.com> References: <20210120173800.1660730-1-jthierry@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Raphael Gault Add build option to run stack validation at compile time. Signed-off-by: Raphael Gault Signed-off-by: Julien Thierry --- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 93a320cc8e03..3f297d61b56b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -185,6 +185,7 @@ config ARM64 select MMU_GATHER_RCU_TABLE_FREE select HAVE_RSEQ select HAVE_STACKPROTECTOR + select HAVE_STACK_VALIDATION if CC_IS_GCC select HAVE_SYSCALL_TRACEPOINTS select HAVE_KPROBES select HAVE_KRETPROBES