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 <tony.luck@xxxxxxxxx> CC: Fenghua Yu <fenghua.yu@xxxxxxxxx> CC: linux-ia64@xxxxxxxxxxxxxxx CC: linux-kernel@xxxxxxxxxxxxxxx Bug: https://github.com/strace/strace/issues/33 Bug: https://gcc.gnu.org/PR84184 Reported-by: Émeric Maschino <emeric.maschino@xxxxxxxxx> Signed-off-by: Sergei Trofimovich <slyfox@xxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-ia64" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
![]() |