Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARC: change some branchs to jumps to resolve linkage errors

When kernel's binary becomes large enough (32M and more) errors
may occur during the final linkage stage. It happens because
the build system uses short relocations for ARC by default.
This problem may be easily resolved by passing -mlong-calls
option to GCC to use long absolute jumps (j) instead of short
relative branchs (b).

But there are fragments of pure assembler code exist which use
branchs in inappropriate places and cause a linkage error because
of relocations overflow.

First of these fragments is .fixup insertion in futex.h and
unaligned.c. It inserts a code in the separate section (.fixup)
with branch instruction. It leads to the linkage error when
kernel becomes large.

Second of these fragments is calling scheduler's functions
(common kernel code) from entry.S of ARC's code. When kernel's
binary becomes large it may lead to the linkage error because
scheduler may occur far enough from ARC's code in the final
binary.

Signed-off-by: Yuriy Kolerov <yuriy.kolerov@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>

authored by

Yuriy Kolerov and committed by
Vineet Gupta
6de6066c eb2cd8b7

+9 -9
+3 -3
arch/arc/include/asm/futex.h
··· 31 31 " .section .fixup,\"ax\" \n" \ 32 32 " .align 4 \n" \ 33 33 "4: mov %0, %4 \n" \ 34 - " b 3b \n" \ 34 + " j 3b \n" \ 35 35 " .previous \n" \ 36 36 " .section __ex_table,\"a\" \n" \ 37 37 " .align 4 \n" \ ··· 58 58 " .section .fixup,\"ax\" \n" \ 59 59 " .align 4 \n" \ 60 60 "4: mov %0, %4 \n" \ 61 - " b 3b \n" \ 61 + " j 3b \n" \ 62 62 " .previous \n" \ 63 63 " .section __ex_table,\"a\" \n" \ 64 64 " .align 4 \n" \ ··· 178 178 "3: \n" 179 179 " .section .fixup,\"ax\" \n" 180 180 "4: mov %0, %5 \n" 181 - " b 3b \n" 181 + " j 3b \n" 182 182 " .previous \n" 183 183 " .section __ex_table,\"a\" \n" 184 184 " .align 4 \n"
+3 -3
arch/arc/kernel/entry.S
··· 42 42 ; when the forked child comes here from the __switch_to function 43 43 ; r0 has the last task pointer. 44 44 ; put last task in scheduler queue 45 - bl @schedule_tail 45 + jl @schedule_tail 46 46 47 47 ld r9, [sp, PT_status32] 48 48 brne r9, 0, 1f ··· 320 320 ; --- (Slow Path #1) task preemption --- 321 321 bbit0 r9, TIF_NEED_RESCHED, .Lchk_pend_signals 322 322 mov blink, resume_user_mode_begin ; tail-call to U mode ret chks 323 - b @schedule ; BTST+Bnz causes relo error in link 323 + j @schedule ; BTST+Bnz causes relo error in link 324 324 325 325 .Lchk_pend_signals: 326 326 IRQ_ENABLE r10 ··· 381 381 bbit0 r9, TIF_NEED_RESCHED, .Lrestore_regs 382 382 383 383 ; Invoke PREEMPTION 384 - bl preempt_schedule_irq 384 + jl preempt_schedule_irq 385 385 386 386 ; preempt_schedule_irq() always returns with IRQ disabled 387 387 #endif
+3 -3
arch/arc/kernel/unaligned.c
··· 34 34 " .section .fixup,\"ax\"\n" \ 35 35 " .align 4\n" \ 36 36 "3: mov %0, 1\n" \ 37 - " b 2b\n" \ 37 + " j 2b\n" \ 38 38 " .previous\n" \ 39 39 " .section __ex_table,\"a\"\n" \ 40 40 " .align 4\n" \ ··· 82 82 " .section .fixup,\"ax\"\n" \ 83 83 " .align 4\n" \ 84 84 "4: mov %0, 1\n" \ 85 - " b 3b\n" \ 85 + " j 3b\n" \ 86 86 " .previous\n" \ 87 87 " .section __ex_table,\"a\"\n" \ 88 88 " .align 4\n" \ ··· 113 113 " .section .fixup,\"ax\"\n" \ 114 114 " .align 4\n" \ 115 115 "6: mov %0, 1\n" \ 116 - " b 5b\n" \ 116 + " j 5b\n" \ 117 117 " .previous\n" \ 118 118 " .section __ex_table,\"a\"\n" \ 119 119 " .align 4\n" \