Received: by 2002:a25:f815:0:0:0:0:0 with SMTP id u21csp2743404ybd; Thu, 27 Jun 2019 18:51:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqzxkm6DpUfyyJ5F8Lz38mRZV9xmCTP6O19dABujiOErAT6tmJAfbUf8y1uUYDu7tZuMsm32 X-Received: by 2002:a63:2a8d:: with SMTP id q135mr6753413pgq.46.1561686719450; Thu, 27 Jun 2019 18:51:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561686719; cv=none; d=google.com; s=arc-20160816; b=pHPREPokA+O0FVmxgLk7kf/6j552Th/dyUq3uQ08wlTMjt0IGmztFtK5A2fkyYOIsQ G6ZGAktXsSL7HwQIro+GrQdWqQYSxw9UnDy8c0itPtSy7XBBCzttE2vwsGqX54gppaur tu5lduSLe++ATwf5syePcKgw5KQSkk167D0RlLljZQfu4INWfXbJLvBxoQESwUGy5D8g NU5OVx2u2nkunTEm5BV3vOUBp+faUfkJNe+gq4u4Qo2hjBzEUYEBxjCMx1WRXDvqje1Z AyKP2NBWAunsLv7/cWOJrWNKXNqRuO0VpNVJgEPsCGAEx95LRrk/Zlrdkw9Nqxt22FNy GUbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=YDjZw70XWtBkq25+iIaLhZ8Y8HXhNum4622HRpBYLP8=; b=JaVCdgrTvI0OADD8M8ANSAZHCUNjWLdmriYCOMMhHGAJ1T9cjxeYbmM8igzMiy0hKB z2MTgcrh3BS9uC3ITvUscwDkEaWDQQAVxFZ+uu+arPNWgFbOQbJUYdAWXi1lSOeWQLxG 3AXu7uSYXpCtkgBD9srrJQcRR2k3sqTyXNypllQk7Ay66cAuDJVCb9xQ1roHg4BlTKNp 6eQCBS3LDwMQoPTiHMG20xEKBq6rDV/KmWtZR/fnXSQqTpH28GV3vJwgZtQGSNoKiEfO /YBkUnxr5hJXgHRjELh7hursdLh+7oEeCy6A8euoNUN25DnN3OXt33NH0KA77GHS7cog MF/A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m67si830963pgm.319.2019.06.27.18.51.43; Thu, 27 Jun 2019 18:51:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726550AbfF1Bvg (ORCPT + 99 others); Thu, 27 Jun 2019 21:51:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56214 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725770AbfF1Bvf (ORCPT ); Thu, 27 Jun 2019 21:51:35 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2E62C30820C9; Fri, 28 Jun 2019 01:51:35 +0000 (UTC) Received: from treble.redhat.com (ovpn-126-66.rdu2.redhat.com [10.10.126.66]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0E3441948D; Fri, 28 Jun 2019 01:51:32 +0000 (UTC) From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Peter Zijlstra , Song Liu , Kairui Song , Steven Rostedt , Thomas Gleixner , Borislav Petkov , Ingo Molnar , Alexei Starovoitov , Daniel Borkmann Subject: [PATCH v4 1/2] objtool: Add support for C jump tables Date: Thu, 27 Jun 2019 20:50:46 -0500 Message-Id: <0ba2ca30442b16b97165992381ce643dc27b3d1a.1561685471.git.jpoimboe@redhat.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 28 Jun 2019 01:51:35 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Objtool doesn't know how to read C jump tables, so it has to whitelist functions which use them, causing missing ORC unwinder data for such functions, e.g. ___bpf_prog_run(). C jump tables are very similar to GCC switch jump tables, which objtool already knows how to read. So adding support for C jump tables is easy. It just needs to be able to find the tables and distinguish them from other data. To allow the jump tables to be found, create an __annotate_jump_table macro which can be used to annotate them. The annotation is done by placing the jump table in an .rodata..c_jump_table section. The '.rodata' prefix ensures that the data will be placed in the rodata section by the vmlinux linker script. The double periods are part of an existing convention which distinguishes kernel sections from GCC sections. Signed-off-by: Josh Poimboeuf --- include/linux/compiler.h | 5 +++++ tools/objtool/check.c | 27 ++++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 8aaf7cd026b0..f0fd5636fddb 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -116,9 +116,14 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, ".pushsection .discard.unreachable\n\t" \ ".long 999b - .\n\t" \ ".popsection\n\t" + +/* Annotate a C jump table to allow objtool to follow the code flow */ +#define __annotate_jump_table __section(".rodata..c_jump_table") + #else #define annotate_reachable() #define annotate_unreachable() +#define __annotate_jump_table #endif #ifndef ASM_UNREACHABLE diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 172f99195726..27818a93f0b1 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -18,6 +18,8 @@ #define FAKE_JUMP_OFFSET -1 +#define C_JUMP_TABLE_SECTION ".rodata..c_jump_table" + struct alternative { struct list_head list; struct instruction *insn; @@ -1035,9 +1037,15 @@ static struct rela *find_switch_table(struct objtool_file *file, /* * Make sure the .rodata address isn't associated with a - * symbol. gcc jump tables are anonymous data. + * symbol. GCC jump tables are anonymous data. + * + * Also support C jump tables which are in the same format as + * switch jump tables. For objtool to recognize them, they + * need to be placed in the C_JUMP_TABLE_SECTION section. They + * have symbols associated with them. */ - if (find_symbol_containing(rodata_sec, table_offset)) + if (find_symbol_containing(rodata_sec, table_offset) && + strcmp(rodata_sec->name, C_JUMP_TABLE_SECTION)) continue; rodata_rela = find_rela_by_dest(rodata_sec, table_offset); @@ -1277,13 +1285,18 @@ static void mark_rodata(struct objtool_file *file) bool found = false; /* - * This searches for the .rodata section or multiple .rodata.func_name - * sections if -fdata-sections is being used. The .str.1.1 and .str.1.8 - * rodata sections are ignored as they don't contain jump tables. + * Search for the following rodata sections, each of which can + * potentially contain jump tables: + * + * - .rodata: can contain GCC switch tables + * - .rodata.: same, if -fdata-sections is being used + * - .rodata..c_jump_table: contains C annotated jump tables + * + * .rodata.str1.* sections are ignored; they don't contain jump tables. */ for_each_sec(file, sec) { - if (!strncmp(sec->name, ".rodata", 7) && - !strstr(sec->name, ".str1.")) { + if ((!strncmp(sec->name, ".rodata", 7) && !strstr(sec->name, ".str1.")) || + !strcmp(sec->name, C_JUMP_TABLE_SECTION)) { sec->rodata = true; found = true; } -- 2.20.1