Commit d7d3ae5c authored by Stephanos Ioannidis's avatar Stephanos Ioannidis Committed by Daniel DeGrasse
Browse files

arch: arm: cortex_m: Force literal pool placement in inline asm block



When LTO is enabled, linker may relocate literal pools out of Thumb LDR
instruction's reach causing "offset out of range" errors while linking.

This commit adds `.ltorg` directive in the inline asm blocks where absolute
addresses are loaded using the `ldr` instructions, in order to ensure that
the literal pool containing the absolute addresses are placed near the
`ldr` instructions.

Note that the `.ltorg` directive is recognised by all toolchains supported
by Zephyr and no toolchain abstraction is provided for now.

Signed-off-by: default avatarStephanos Ioannidis <root@stephanos.io>
parent d7ff0e4b
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -557,6 +557,8 @@ void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr,
			 "ldr   r4, =z_thread_entry\n"
			 "ldr   r4, =z_thread_entry\n"
			 /* We don’t intend to return, so there is no need to link. */
			 /* We don’t intend to return, so there is no need to link. */
			 "bx    r4\n"
			 "bx    r4\n"
			 /* Force a literal pool placement for the addresses referenced above */
			 ".ltorg\n"
			 :
			 :
			 : "r"(_main), "r"(stack_ptr)
			 : "r"(_main), "r"(stack_ptr)
			 : "r0", "r1", "r2", "r3", "r4", "ip", "lr", "memory");
			 : "r0", "r1", "r2", "r3", "r4", "ip", "lr", "memory");
@@ -623,6 +625,8 @@ FUNC_NORETURN void z_arm_switch_to_main_no_multithreading(k_thread_entry_t main_
		"ldr r0, =arch_irq_lock_outlined\n"
		"ldr r0, =arch_irq_lock_outlined\n"
		"blx r0\n"
		"blx r0\n"
		"loop: b loop\n\t" /* while (true); */
		"loop: b loop\n\t" /* while (true); */
		/* Force a literal pool placement for the addresses referenced above */
		".ltorg\n"
		:
		:
		: [_p1] "r"(p1), [_p2] "r"(p2), [_p3] "r"(p3), [_psp] "r"(psp),
		: [_p1] "r"(p1), [_p2] "r"(p2), [_p3] "r"(p3), [_psp] "r"(psp),
		  [_main_entry] "r"(main_entry)
		  [_main_entry] "r"(main_entry)