From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752645AbeBBWMl (ORCPT ); Fri, 2 Feb 2018 17:12:41 -0500 Received: from smtp.gentoo.org ([140.211.166.183]:60942 "EHLO smtp.gentoo.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752211AbeBBWMg (ORCPT ); Fri, 2 Feb 2018 17:12:36 -0500 From: Sergei Trofimovich To: Tony Luck , Fenghua Yu , linux-ia64@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sergei Trofimovich Subject: [PATCH] ia64: fix ptrace(PTRACE_GETREGS) (unbreaks strace, gdb) Date: Fri, 2 Feb 2018 22:12:24 +0000 Message-Id: <20180202221224.16597-1-slyfox@gentoo.org> X-Mailer: git-send-email 2.16.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The strace breakage looks like that: ./strace: get_regs: get_regs_error: Input/output error It happens because ia64 needs to load unwind tables to read certain registers. Unwind tables fail to load due to GCC quirk on the following code: extern char __end_unwind[]; const struct unw_table_entry *end = (struct unw_table_entry *)table_end; table->end = segment_base + end[-1].end_offset; GCC does not generate correct code for this single memory reference after constant propagation (see https://gcc.gnu.org/PR84184). Two triggers are required for bad code generation: - '__end_unwind' has alignment lower (char), than 'struct unw_table_entry' (8). - symbol offset is negative. This commit workarounds it by fixing alignment of '__end_unwind'. While at it use hidden symbols to generate shorter gp-relative relocations. CC: Tony Luck CC: Fenghua Yu CC: linux-ia64@vger.kernel.org CC: linux-kernel@vger.kernel.org Bug: https://github.com/strace/strace/issues/33 Bug: https://gcc.gnu.org/PR84184 Reported-by: Émeric Maschino Signed-off-by: Sergei Trofimovich --- arch/ia64/include/asm/sections.h | 1 - arch/ia64/kernel/unwind.c | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h index f3481408594e..0fc4f1757a44 100644 --- a/arch/ia64/include/asm/sections.h +++ b/arch/ia64/include/asm/sections.h @@ -24,7 +24,6 @@ extern char __start_gate_mckinley_e9_patchlist[], __end_gate_mckinley_e9_patchli extern char __start_gate_vtop_patchlist[], __end_gate_vtop_patchlist[]; extern char __start_gate_fsyscall_patchlist[], __end_gate_fsyscall_patchlist[]; extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_bubble_down_patchlist[]; -extern char __start_unwind[], __end_unwind[]; extern char __start_ivt_text[], __end_ivt_text[]; #undef dereference_function_descriptor diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index e04efa088902..025ba6700790 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -2243,7 +2243,20 @@ __initcall(create_gate_table); void __init unw_init (void) { - extern char __gp[]; + #define __ia64_hidden __attribute__((visibility("hidden"))) + /* + * We use hidden symbols to generate more efficient code using + * gp-relative addressing. + */ + extern char __gp[] __ia64_hidden; + /* + * Unwind tables need to have proper alignment as init_unwind_table() + * uses negative offsets against '__end_unwind'. + * See https://gcc.gnu.org/PR84184 + */ + extern const struct unw_table_entry __start_unwind[] __ia64_hidden; + extern const struct unw_table_entry __end_unwind[] __ia64_hidden; + #undef __ia64_hidden extern void unw_hash_index_t_is_too_narrow (void); long i, off; -- 2.16.1