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 X-Spam-Level: X-Spam-Status: No, score=-8.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,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 AFBE3C43613 for ; Mon, 24 Jun 2019 09:57:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8397420679 for ; Mon, 24 Jun 2019 09:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728658AbfFXJ4S (ORCPT ); Mon, 24 Jun 2019 05:56:18 -0400 Received: from foss.arm.com ([217.140.110.172]:44868 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728601AbfFXJ4O (ORCPT ); Mon, 24 Jun 2019 05:56:14 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B56A9C15; Mon, 24 Jun 2019 02:56:13 -0700 (PDT) Received: from e121650-lin.cambridge.arm.com (e121650-lin.cambridge.arm.com [10.1.196.120]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7C4223F71E; Mon, 24 Jun 2019 02:56:12 -0700 (PDT) From: Raphael Gault To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: jpoimboe@redhat.com, peterz@infradead.org, catalin.marinas@arm.com, will.deacon@arm.com, julien.thierry@arm.com, Raphael Gault Subject: [RFC V3 02/18] objtool: orc: Refactor ORC API for other architectures to implement. Date: Mon, 24 Jun 2019 10:55:32 +0100 Message-Id: <20190624095548.8578-3-raphael.gault@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190624095548.8578-1-raphael.gault@arm.com> References: <20190624095548.8578-1-raphael.gault@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The ORC unwinder is only supported on x86 at the moment and should thus be in the x86 architecture code. In order not to break the whole structure in case another architecture decides to support the ORC unwinder via objtool we choose to let the implementation be done in the architecture dependent code. Signed-off-by: Raphael Gault --- tools/objtool/Build | 2 - tools/objtool/arch.h | 3 + tools/objtool/arch/x86/Build | 2 + tools/objtool/{ => arch/x86}/orc_dump.c | 4 +- tools/objtool/{ => arch/x86}/orc_gen.c | 104 ++++++++++++++++++++++-- tools/objtool/check.c | 99 +--------------------- tools/objtool/orc.h | 4 +- 7 files changed, 111 insertions(+), 107 deletions(-) rename tools/objtool/{ => arch/x86}/orc_dump.c (98%) rename tools/objtool/{ => arch/x86}/orc_gen.c (66%) diff --git a/tools/objtool/Build b/tools/objtool/Build index 749becdf5b90..2ed83344e0a5 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -2,8 +2,6 @@ objtool-y += arch/$(SRCARCH)/ objtool-y += builtin-check.o objtool-y += builtin-orc.o objtool-y += check.o -objtool-y += orc_gen.o -objtool-y += orc_dump.o objtool-y += elf.o objtool-y += special.o objtool-y += objtool.o diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h index 2a38a834cf40..ce7db772248e 100644 --- a/tools/objtool/arch.h +++ b/tools/objtool/arch.h @@ -10,6 +10,7 @@ #include #include "elf.h" #include "cfi.h" +#include "orc.h" #define INSN_JUMP_CONDITIONAL 1 #define INSN_JUMP_UNCONDITIONAL 2 @@ -75,6 +76,8 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, bool arch_callee_saved_reg(unsigned char reg); +int arch_orc_read_unwind_hints(struct objtool_file *file); + unsigned long arch_jump_destination(struct instruction *insn); unsigned long arch_dest_rela_offset(int addend); diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build index b998412c017d..1f11b45999d0 100644 --- a/tools/objtool/arch/x86/Build +++ b/tools/objtool/arch/x86/Build @@ -1,4 +1,6 @@ objtool-y += decode.o +objtool-y += orc_dump.o +objtool-y += orc_gen.o inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = arch/x86/lib/x86-opcode-map.txt diff --git a/tools/objtool/orc_dump.c b/tools/objtool/arch/x86/orc_dump.c similarity index 98% rename from tools/objtool/orc_dump.c rename to tools/objtool/arch/x86/orc_dump.c index 13ccf775a83a..cfe8f96bdd68 100644 --- a/tools/objtool/orc_dump.c +++ b/tools/objtool/arch/x86/orc_dump.c @@ -4,8 +4,8 @@ */ #include -#include "orc.h" -#include "warn.h" +#include "../../orc.h" +#include "../../warn.h" static const char *reg_name(unsigned int reg) { diff --git a/tools/objtool/orc_gen.c b/tools/objtool/arch/x86/orc_gen.c similarity index 66% rename from tools/objtool/orc_gen.c rename to tools/objtool/arch/x86/orc_gen.c index 27a4112848c2..b4f285bf5271 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/arch/x86/orc_gen.c @@ -6,11 +6,11 @@ #include #include -#include "orc.h" -#include "check.h" -#include "warn.h" +#include "../../orc.h" +#include "../../check.h" +#include "../../warn.h" -int create_orc(struct objtool_file *file) +int arch_create_orc(struct objtool_file *file) { struct instruction *insn; @@ -116,7 +116,7 @@ static int create_orc_entry(struct section *u_sec, struct section *ip_relasec, return 0; } -int create_orc_sections(struct objtool_file *file) +int arch_create_orc_sections(struct objtool_file *file) { struct instruction *insn, *prev_insn; struct section *sec, *u_sec, *ip_relasec; @@ -209,3 +209,97 @@ int create_orc_sections(struct objtool_file *file) return 0; } + +int arch_orc_read_unwind_hints(struct objtool_file *file) +{ + struct section *sec, *relasec; + struct rela *rela; + struct unwind_hint *hint; + struct instruction *insn; + struct cfi_reg *cfa; + int i; + + sec = find_section_by_name(file->elf, ".discard.unwind_hints"); + if (!sec) + return 0; + + relasec = sec->rela; + if (!relasec) { + WARN("missing .rela.discard.unwind_hints section"); + return -1; + } + + if (sec->len % sizeof(struct unwind_hint)) { + WARN("struct unwind_hint size mismatch"); + return -1; + } + + file->hints = true; + + for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) { + hint = (struct unwind_hint *)sec->data->d_buf + i; + + rela = find_rela_by_dest(sec, i * sizeof(*hint)); + if (!rela) { + WARN("can't find rela for unwind_hints[%d]", i); + return -1; + } + + insn = find_insn(file, rela->sym->sec, rela->addend); + if (!insn) { + WARN("can't find insn for unwind_hints[%d]", i); + return -1; + } + + cfa = &insn->state.cfa; + + if (hint->type == UNWIND_HINT_TYPE_SAVE) { + insn->save = true; + continue; + + } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) { + insn->restore = true; + insn->hint = true; + continue; + } + + insn->hint = true; + + switch (hint->sp_reg) { + case ORC_REG_UNDEFINED: + cfa->base = CFI_UNDEFINED; + break; + case ORC_REG_SP: + cfa->base = CFI_SP; + break; + case ORC_REG_BP: + cfa->base = CFI_BP; + break; + case ORC_REG_SP_INDIRECT: + cfa->base = CFI_SP_INDIRECT; + break; + case ORC_REG_R10: + cfa->base = CFI_R10; + break; + case ORC_REG_R13: + cfa->base = CFI_R13; + break; + case ORC_REG_DI: + cfa->base = CFI_DI; + break; + case ORC_REG_DX: + cfa->base = CFI_DX; + break; + default: + WARN_FUNC("unsupported unwind_hint sp base reg %d", + insn->sec, insn->offset, hint->sp_reg); + return -1; + } + + cfa->offset = hint->sp_offset; + insn->state.type = hint->type; + insn->state.end = hint->end; + } + + return 0; +} diff --git a/tools/objtool/check.c b/tools/objtool/check.c index b37ca4822f25..1a7ee85e9878 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1147,99 +1147,6 @@ static int add_switch_table_alts(struct objtool_file *file) return 0; } -static int read_unwind_hints(struct objtool_file *file) -{ - struct section *sec, *relasec; - struct rela *rela; - struct unwind_hint *hint; - struct instruction *insn; - struct cfi_reg *cfa; - int i; - - sec = find_section_by_name(file->elf, ".discard.unwind_hints"); - if (!sec) - return 0; - - relasec = sec->rela; - if (!relasec) { - WARN("missing .rela.discard.unwind_hints section"); - return -1; - } - - if (sec->len % sizeof(struct unwind_hint)) { - WARN("struct unwind_hint size mismatch"); - return -1; - } - - file->hints = true; - - for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) { - hint = (struct unwind_hint *)sec->data->d_buf + i; - - rela = find_rela_by_dest(sec, i * sizeof(*hint)); - if (!rela) { - WARN("can't find rela for unwind_hints[%d]", i); - return -1; - } - - insn = find_insn(file, rela->sym->sec, rela->addend); - if (!insn) { - WARN("can't find insn for unwind_hints[%d]", i); - return -1; - } - - cfa = &insn->state.cfa; - - if (hint->type == UNWIND_HINT_TYPE_SAVE) { - insn->save = true; - continue; - - } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) { - insn->restore = true; - insn->hint = true; - continue; - } - - insn->hint = true; - - switch (hint->sp_reg) { - case ORC_REG_UNDEFINED: - cfa->base = CFI_UNDEFINED; - break; - case ORC_REG_SP: - cfa->base = CFI_SP; - break; - case ORC_REG_BP: - cfa->base = CFI_BP; - break; - case ORC_REG_SP_INDIRECT: - cfa->base = CFI_SP_INDIRECT; - break; - case ORC_REG_R10: - cfa->base = CFI_R10; - break; - case ORC_REG_R13: - cfa->base = CFI_R13; - break; - case ORC_REG_DI: - cfa->base = CFI_DI; - break; - case ORC_REG_DX: - cfa->base = CFI_DX; - break; - default: - WARN_FUNC("unsupported unwind_hint sp base reg %d", - insn->sec, insn->offset, hint->sp_reg); - return -1; - } - - cfa->offset = hint->sp_offset; - insn->state.type = hint->type; - insn->state.end = hint->end; - } - - return 0; -} static int read_retpoline_hints(struct objtool_file *file) { @@ -1334,7 +1241,7 @@ static int decode_sections(struct objtool_file *file) if (ret) return ret; - ret = read_unwind_hints(file); + ret = arch_orc_read_unwind_hints(file); if (ret) return ret; @@ -2457,11 +2364,11 @@ int check(const char *_objname, bool orc) } if (orc) { - ret = create_orc(&file); + ret = arch_create_orc(&file); if (ret < 0) goto out; - ret = create_orc_sections(&file); + ret = arch_create_orc_sections(&file); if (ret < 0) goto out; diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h index ee2832221e62..fd7fa1d34a81 100644 --- a/tools/objtool/orc.h +++ b/tools/objtool/orc.h @@ -10,8 +10,8 @@ struct objtool_file; -int create_orc(struct objtool_file *file); -int create_orc_sections(struct objtool_file *file); +int arch_create_orc(struct objtool_file *file); +int arch_create_orc_sections(struct objtool_file *file); int orc_dump(const char *objname); -- 2.17.1 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 X-Spam-Level: X-Spam-Status: No, score=-8.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,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 E4AF7C48BE3 for ; Mon, 24 Jun 2019 09:57:08 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BAA6420679 for ; Mon, 24 Jun 2019 09:57:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="aNPd1pck" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BAA6420679 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=eTvhXWlFRhNye3J6lgPExPcv753KEJV8bPt1u+JxUB8=; b=aNPd1pckdmNGFgGcFp6d81zaGI xrH4wqAtS/ZpiofWAj8rkXlDkf6dHlGNGwELwOHilHxAVRktazuMA3RZ8I5LWIQoHWvHeGsmhU9A7 dnK7K6+CgkLwgR5uZrjuLiZcfKsL/r046YpjWUcFs7j9JpWxQOWY/OaRYnEZH2QUdk+1Elsg048q2 Bj7Z3p1+NlJ6ci3xvDaqvafU3nF1FiszA+ISNryyoXth9LkLfqKUOe4ZbEfQ98jJCA44KosVD/sAB vay8zYs0JLIoW6l7Zr6bMzJ01rJtAx8PW9rLODXshifkPaNmgl6KGMB1EJmMFhanJSaeljHvqPd/9 Lnm2o1Ng==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hfLid-0005mq-CP; Mon, 24 Jun 2019 09:56:59 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hfLhw-0005B8-1o for linux-arm-kernel@lists.infradead.org; Mon, 24 Jun 2019 09:56:17 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B56A9C15; Mon, 24 Jun 2019 02:56:13 -0700 (PDT) Received: from e121650-lin.cambridge.arm.com (e121650-lin.cambridge.arm.com [10.1.196.120]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7C4223F71E; Mon, 24 Jun 2019 02:56:12 -0700 (PDT) From: Raphael Gault To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC V3 02/18] objtool: orc: Refactor ORC API for other architectures to implement. Date: Mon, 24 Jun 2019 10:55:32 +0100 Message-Id: <20190624095548.8578-3-raphael.gault@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190624095548.8578-1-raphael.gault@arm.com> References: <20190624095548.8578-1-raphael.gault@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190624_025616_204233_2D6E153C X-CRM114-Status: GOOD ( 15.73 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: julien.thierry@arm.com, peterz@infradead.org, catalin.marinas@arm.com, will.deacon@arm.com, Raphael Gault , jpoimboe@redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org The ORC unwinder is only supported on x86 at the moment and should thus be in the x86 architecture code. In order not to break the whole structure in case another architecture decides to support the ORC unwinder via objtool we choose to let the implementation be done in the architecture dependent code. Signed-off-by: Raphael Gault --- tools/objtool/Build | 2 - tools/objtool/arch.h | 3 + tools/objtool/arch/x86/Build | 2 + tools/objtool/{ => arch/x86}/orc_dump.c | 4 +- tools/objtool/{ => arch/x86}/orc_gen.c | 104 ++++++++++++++++++++++-- tools/objtool/check.c | 99 +--------------------- tools/objtool/orc.h | 4 +- 7 files changed, 111 insertions(+), 107 deletions(-) rename tools/objtool/{ => arch/x86}/orc_dump.c (98%) rename tools/objtool/{ => arch/x86}/orc_gen.c (66%) diff --git a/tools/objtool/Build b/tools/objtool/Build index 749becdf5b90..2ed83344e0a5 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -2,8 +2,6 @@ objtool-y += arch/$(SRCARCH)/ objtool-y += builtin-check.o objtool-y += builtin-orc.o objtool-y += check.o -objtool-y += orc_gen.o -objtool-y += orc_dump.o objtool-y += elf.o objtool-y += special.o objtool-y += objtool.o diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h index 2a38a834cf40..ce7db772248e 100644 --- a/tools/objtool/arch.h +++ b/tools/objtool/arch.h @@ -10,6 +10,7 @@ #include #include "elf.h" #include "cfi.h" +#include "orc.h" #define INSN_JUMP_CONDITIONAL 1 #define INSN_JUMP_UNCONDITIONAL 2 @@ -75,6 +76,8 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, bool arch_callee_saved_reg(unsigned char reg); +int arch_orc_read_unwind_hints(struct objtool_file *file); + unsigned long arch_jump_destination(struct instruction *insn); unsigned long arch_dest_rela_offset(int addend); diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build index b998412c017d..1f11b45999d0 100644 --- a/tools/objtool/arch/x86/Build +++ b/tools/objtool/arch/x86/Build @@ -1,4 +1,6 @@ objtool-y += decode.o +objtool-y += orc_dump.o +objtool-y += orc_gen.o inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = arch/x86/lib/x86-opcode-map.txt diff --git a/tools/objtool/orc_dump.c b/tools/objtool/arch/x86/orc_dump.c similarity index 98% rename from tools/objtool/orc_dump.c rename to tools/objtool/arch/x86/orc_dump.c index 13ccf775a83a..cfe8f96bdd68 100644 --- a/tools/objtool/orc_dump.c +++ b/tools/objtool/arch/x86/orc_dump.c @@ -4,8 +4,8 @@ */ #include -#include "orc.h" -#include "warn.h" +#include "../../orc.h" +#include "../../warn.h" static const char *reg_name(unsigned int reg) { diff --git a/tools/objtool/orc_gen.c b/tools/objtool/arch/x86/orc_gen.c similarity index 66% rename from tools/objtool/orc_gen.c rename to tools/objtool/arch/x86/orc_gen.c index 27a4112848c2..b4f285bf5271 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/arch/x86/orc_gen.c @@ -6,11 +6,11 @@ #include #include -#include "orc.h" -#include "check.h" -#include "warn.h" +#include "../../orc.h" +#include "../../check.h" +#include "../../warn.h" -int create_orc(struct objtool_file *file) +int arch_create_orc(struct objtool_file *file) { struct instruction *insn; @@ -116,7 +116,7 @@ static int create_orc_entry(struct section *u_sec, struct section *ip_relasec, return 0; } -int create_orc_sections(struct objtool_file *file) +int arch_create_orc_sections(struct objtool_file *file) { struct instruction *insn, *prev_insn; struct section *sec, *u_sec, *ip_relasec; @@ -209,3 +209,97 @@ int create_orc_sections(struct objtool_file *file) return 0; } + +int arch_orc_read_unwind_hints(struct objtool_file *file) +{ + struct section *sec, *relasec; + struct rela *rela; + struct unwind_hint *hint; + struct instruction *insn; + struct cfi_reg *cfa; + int i; + + sec = find_section_by_name(file->elf, ".discard.unwind_hints"); + if (!sec) + return 0; + + relasec = sec->rela; + if (!relasec) { + WARN("missing .rela.discard.unwind_hints section"); + return -1; + } + + if (sec->len % sizeof(struct unwind_hint)) { + WARN("struct unwind_hint size mismatch"); + return -1; + } + + file->hints = true; + + for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) { + hint = (struct unwind_hint *)sec->data->d_buf + i; + + rela = find_rela_by_dest(sec, i * sizeof(*hint)); + if (!rela) { + WARN("can't find rela for unwind_hints[%d]", i); + return -1; + } + + insn = find_insn(file, rela->sym->sec, rela->addend); + if (!insn) { + WARN("can't find insn for unwind_hints[%d]", i); + return -1; + } + + cfa = &insn->state.cfa; + + if (hint->type == UNWIND_HINT_TYPE_SAVE) { + insn->save = true; + continue; + + } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) { + insn->restore = true; + insn->hint = true; + continue; + } + + insn->hint = true; + + switch (hint->sp_reg) { + case ORC_REG_UNDEFINED: + cfa->base = CFI_UNDEFINED; + break; + case ORC_REG_SP: + cfa->base = CFI_SP; + break; + case ORC_REG_BP: + cfa->base = CFI_BP; + break; + case ORC_REG_SP_INDIRECT: + cfa->base = CFI_SP_INDIRECT; + break; + case ORC_REG_R10: + cfa->base = CFI_R10; + break; + case ORC_REG_R13: + cfa->base = CFI_R13; + break; + case ORC_REG_DI: + cfa->base = CFI_DI; + break; + case ORC_REG_DX: + cfa->base = CFI_DX; + break; + default: + WARN_FUNC("unsupported unwind_hint sp base reg %d", + insn->sec, insn->offset, hint->sp_reg); + return -1; + } + + cfa->offset = hint->sp_offset; + insn->state.type = hint->type; + insn->state.end = hint->end; + } + + return 0; +} diff --git a/tools/objtool/check.c b/tools/objtool/check.c index b37ca4822f25..1a7ee85e9878 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1147,99 +1147,6 @@ static int add_switch_table_alts(struct objtool_file *file) return 0; } -static int read_unwind_hints(struct objtool_file *file) -{ - struct section *sec, *relasec; - struct rela *rela; - struct unwind_hint *hint; - struct instruction *insn; - struct cfi_reg *cfa; - int i; - - sec = find_section_by_name(file->elf, ".discard.unwind_hints"); - if (!sec) - return 0; - - relasec = sec->rela; - if (!relasec) { - WARN("missing .rela.discard.unwind_hints section"); - return -1; - } - - if (sec->len % sizeof(struct unwind_hint)) { - WARN("struct unwind_hint size mismatch"); - return -1; - } - - file->hints = true; - - for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) { - hint = (struct unwind_hint *)sec->data->d_buf + i; - - rela = find_rela_by_dest(sec, i * sizeof(*hint)); - if (!rela) { - WARN("can't find rela for unwind_hints[%d]", i); - return -1; - } - - insn = find_insn(file, rela->sym->sec, rela->addend); - if (!insn) { - WARN("can't find insn for unwind_hints[%d]", i); - return -1; - } - - cfa = &insn->state.cfa; - - if (hint->type == UNWIND_HINT_TYPE_SAVE) { - insn->save = true; - continue; - - } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) { - insn->restore = true; - insn->hint = true; - continue; - } - - insn->hint = true; - - switch (hint->sp_reg) { - case ORC_REG_UNDEFINED: - cfa->base = CFI_UNDEFINED; - break; - case ORC_REG_SP: - cfa->base = CFI_SP; - break; - case ORC_REG_BP: - cfa->base = CFI_BP; - break; - case ORC_REG_SP_INDIRECT: - cfa->base = CFI_SP_INDIRECT; - break; - case ORC_REG_R10: - cfa->base = CFI_R10; - break; - case ORC_REG_R13: - cfa->base = CFI_R13; - break; - case ORC_REG_DI: - cfa->base = CFI_DI; - break; - case ORC_REG_DX: - cfa->base = CFI_DX; - break; - default: - WARN_FUNC("unsupported unwind_hint sp base reg %d", - insn->sec, insn->offset, hint->sp_reg); - return -1; - } - - cfa->offset = hint->sp_offset; - insn->state.type = hint->type; - insn->state.end = hint->end; - } - - return 0; -} static int read_retpoline_hints(struct objtool_file *file) { @@ -1334,7 +1241,7 @@ static int decode_sections(struct objtool_file *file) if (ret) return ret; - ret = read_unwind_hints(file); + ret = arch_orc_read_unwind_hints(file); if (ret) return ret; @@ -2457,11 +2364,11 @@ int check(const char *_objname, bool orc) } if (orc) { - ret = create_orc(&file); + ret = arch_create_orc(&file); if (ret < 0) goto out; - ret = create_orc_sections(&file); + ret = arch_create_orc_sections(&file); if (ret < 0) goto out; diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h index ee2832221e62..fd7fa1d34a81 100644 --- a/tools/objtool/orc.h +++ b/tools/objtool/orc.h @@ -10,8 +10,8 @@ struct objtool_file; -int create_orc(struct objtool_file *file); -int create_orc_sections(struct objtool_file *file); +int arch_create_orc(struct objtool_file *file); +int arch_create_orc_sections(struct objtool_file *file); int orc_dump(const char *objname); -- 2.17.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel