From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C085DC433F5 for ; Fri, 29 Apr 2022 09:45:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356741AbiD2Jsg (ORCPT ); Fri, 29 Apr 2022 05:48:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356736AbiD2Jsc (ORCPT ); Fri, 29 Apr 2022 05:48:32 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C4741A814; Fri, 29 Apr 2022 02:45:13 -0700 (PDT) Received: from dggpemm500020.china.huawei.com (unknown [172.30.72.56]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4KqSFj5Q4xzGpTX; Fri, 29 Apr 2022 17:42:33 +0800 (CST) Received: from dggpemm500013.china.huawei.com (7.185.36.172) by dggpemm500020.china.huawei.com (7.185.36.49) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Fri, 29 Apr 2022 17:45:12 +0800 Received: from ubuntu1804.huawei.com (10.67.175.36) by dggpemm500013.china.huawei.com (7.185.36.172) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Fri, 29 Apr 2022 17:45:11 +0800 From: Chen Zhongjin To: , , CC: , , , , , , , , , , , , , , Subject: [RFC PATCH v4 14/37] objtool: check: Support data in text section Date: Fri, 29 Apr 2022 17:43:32 +0800 Message-ID: <20220429094355.122389-15-chenzhongjin@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220429094355.122389-1-chenzhongjin@huawei.com> References: <20220429094355.122389-1-chenzhongjin@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.67.175.36] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To dggpemm500013.china.huawei.com (7.185.36.172) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-arch@vger.kernel.org From: Julien Thierry Assembly code can mix code and data in text sections through the use of SYM_DATA_*() macros. Skip the content of these symbols when decoding instructions of text sections. Signed-off-by: Julien Thierry Signed-off-by: Chen Zhongjin --- tools/objtool/check.c | 19 +++++++++++++++++-- tools/objtool/elf.c | 14 ++++++++++++++ tools/objtool/include/objtool/elf.h | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index ae75e88c4885..52978b8f2ae9 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -356,7 +356,7 @@ static int decode_instructions(struct objtool_file *file) { struct section *sec; struct symbol *func; - unsigned long offset; + unsigned long offset, next_offset; struct instruction *insn; int ret; @@ -374,7 +374,14 @@ static int decode_instructions(struct objtool_file *file) !strcmp(sec->name, ".entry.text")) sec->noinstr = true; - for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) { + for (offset = 0; offset < sec->sh.sh_size; offset = next_offset) { + struct symbol *obj_sym = find_object_containing(sec, offset); + if (obj_sym) { + /* This is data in the middle of text section, skip it */ + next_offset = obj_sym->offset + obj_sym->len; + continue; + } + insn = malloc(sizeof(*insn)); if (!insn) { WARN("malloc failed"); @@ -407,6 +414,14 @@ static int decode_instructions(struct objtool_file *file) hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset)); list_add_tail(&insn->list, &file->insn_list); nr_insns++; + + /* This case is rare, but can cause infinite loop */ + if (!insn->len) { + WARN("zero instruction length"); + return -1; + } + + next_offset = offset + insn->len; } list_for_each_entry(func, &sec->symbol_list, list) { diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index d7b99a737496..5b35d89b54d4 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -236,6 +236,20 @@ struct symbol *find_func_containing(struct section *sec, unsigned long offset) return NULL; } +struct symbol *find_object_containing(struct section *sec, unsigned long offset) +{ + struct rb_node *node; + + rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { + struct symbol *s = rb_entry(node, struct symbol, node); + + if (s->type == STT_OBJECT) + return s; + } + + return NULL; +} + struct symbol *find_symbol_by_name(const struct elf *elf, const char *name) { struct symbol *sym; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h index 22ba7e2b816e..52ecf1e23cb6 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -157,6 +157,7 @@ struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, uns struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, unsigned long offset, unsigned int len); struct symbol *find_func_containing(struct section *sec, unsigned long offset); +struct symbol *find_object_containing(struct section *sec, unsigned long offset); #define for_each_sec(file, sec) \ list_for_each_entry(sec, &file->elf->sections, list) -- 2.17.1