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=-15.8 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 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 215C9C4361B for ; Fri, 11 Dec 2020 19:28:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D7B042405C for ; Fri, 11 Dec 2020 19:28:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405725AbgLKRso (ORCPT ); Fri, 11 Dec 2020 12:48:44 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:54453 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405633AbgLKRr5 (ORCPT ); Fri, 11 Dec 2020 12:47:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1607708789; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=FzP6paV2OVK1R/7FuD7jU8vd9PKyeesd/swefA4DzN8=; b=OU988ktpNvBfpTQ1Nyi2FO9kO839nfWVdikLJ1v/3cl8+6FTHrbV+fV8sK4+cYtvJD2Rwg L52Z4pA3bUAdJkssU7frMzJFVQnhX3Y680oDGN4lCFv7il1ZgcnUepBraq3ei54qyJpNUj NfShYR6l6pxqddi5W/rwmHNWL7xKT5g= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-302-ky9U20HmPFyLH8tA_rrRjg-1; Fri, 11 Dec 2020 12:46:20 -0500 X-MC-Unique: ky9U20HmPFyLH8tA_rrRjg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1B38F81E24B; Fri, 11 Dec 2020 17:46:18 +0000 (UTC) Received: from treble (ovpn-115-21.rdu2.redhat.com [10.10.115.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6574710021AA; Fri, 11 Dec 2020 17:46:17 +0000 (UTC) Date: Fri, 11 Dec 2020 11:46:10 -0600 From: Josh Poimboeuf To: Peter Zijlstra Cc: Nick Desaulniers , Arnd Bergmann , Linux Kernel Mailing List , clang-built-linux Subject: Re: objtool crashes with some clang produced .o files Message-ID: <20201211174610.2bfprpvrrlg66awd@treble> References: <20201211093205.GU2414@hirez.programming.kicks-ass.net> <20201211163748.b37gashl6an6misu@treble> <20201211164915.GA2414@hirez.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20201211164915.GA2414@hirez.programming.kicks-ass.net> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Dec 11, 2020 at 05:49:15PM +0100, Peter Zijlstra wrote: > Do we want to capture all that gunk in something like > elf_reloc_to_insn(reloc, insn) instead of duplicating the magic? Yup, here's an actual patch From: Josh Poimboeuf Subject: [PATCH] objtool: Support Clang non-section symbols in static call generation The Clang assembler likes to strip section symbols, which means you can't reference some text code by its section. This confuses objtool greatly, causing it to seg fault. The fix is similar to what was done before, for ORC reloc generation: e81e07244325 ("objtool: Support Clang non-section symbols in ORC generation") Factor out that code into a common helper and use it for static call reloc generation as well. Reported-by: Arnd Bergmann Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 11 +++++++++-- tools/objtool/elf.c | 26 ++++++++++++++++++++++++++ tools/objtool/elf.h | 2 ++ tools/objtool/orc_gen.c | 29 +++++------------------------ 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index c6ab44543c92..5f8d3eed78a1 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -467,13 +467,20 @@ static int create_static_call_sections(struct objtool_file *file) /* populate reloc for 'addr' */ reloc = malloc(sizeof(*reloc)); + if (!reloc) { perror("malloc"); return -1; } memset(reloc, 0, sizeof(*reloc)); - reloc->sym = insn->sec->sym; - reloc->addend = insn->offset; + + insn_to_reloc_sym_addend(insn->sec, insn->offset, reloc); + if (!reloc->sym) { + WARN_FUNC("static call tramp: missing containing symbol", + insn->sec, insn->offset); + return -1; + } + reloc->type = R_X86_64_PC32; reloc->offset = idx * sizeof(struct static_call_site); reloc->sec = reloc_sec; diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 4e1d7460574b..be89c741ba9a 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -262,6 +262,32 @@ struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, uns return find_reloc_by_dest_range(elf, sec, offset, 1); } +void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset, + struct reloc *reloc) +{ + if (sec->sym) { + reloc->sym = sec->sym; + reloc->addend = offset; + return; + } + + /* + * The Clang assembler strips section symbols, so we have to reference + * the function symbol instead: + */ + reloc->sym = find_symbol_containing(sec, offset); + if (!reloc->sym) { + /* + * Hack alert. This happens when we need to reference the NOP + * pad insn immediately after the function. + */ + reloc->sym = find_symbol_containing(sec, offset - 1); + } + + if (reloc->sym) + reloc->addend = offset - reloc->sym->offset; +} + static int read_sections(struct elf *elf) { Elf_Scn *s = NULL; diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h index 807f8c670097..e6890cc70a25 100644 --- a/tools/objtool/elf.h +++ b/tools/objtool/elf.h @@ -140,6 +140,8 @@ 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); +void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset, + struct reloc *reloc); int elf_rebuild_reloc_section(struct elf *elf, struct section *sec); #define for_each_sec(file, sec) \ diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index 235663b96adc..9ce68b385a1b 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -105,30 +105,11 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti } memset(reloc, 0, sizeof(*reloc)); - if (insn_sec->sym) { - reloc->sym = insn_sec->sym; - reloc->addend = insn_off; - } else { - /* - * The Clang assembler doesn't produce section symbols, so we - * have to reference the function symbol instead: - */ - reloc->sym = find_symbol_containing(insn_sec, insn_off); - if (!reloc->sym) { - /* - * Hack alert. This happens when we need to reference - * the NOP pad insn immediately after the function. - */ - reloc->sym = find_symbol_containing(insn_sec, - insn_off - 1); - } - if (!reloc->sym) { - WARN("missing symbol for insn at offset 0x%lx\n", - insn_off); - return -1; - } - - reloc->addend = insn_off - reloc->sym->offset; + insn_to_reloc_sym_addend(insn_sec, insn_off, reloc); + if (!reloc->sym) { + WARN("missing symbol for insn at offset 0x%lx", + insn_off); + return -1; } reloc->type = R_X86_64_PC32; -- 2.25.4