Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78f3cdfa authored by Chris Zankel's avatar Chris Zankel
Browse files

xtensa: Fix linker script to include .literal sections



Fix resembles implementation from Marc Gauthier and Piet Denaly:

In the Xtensa architecture, assembly generates literals which must always
precede the code (the L32R instruction that loads them only uses negative
PC-relative offsets).  For any *.text section, literals are placed in a
corresponding *.literal section.  The linker script (vmlinux.lds) must
place these in the correct order.  It must also combine them, when the
*.text section can be larger than L32R's 256 kB range.

For example, this doesn't work:  *(.literal) *(.text) because L32R
instructions at the end of .text can't reach the literals.

The linker can solve this if they are combined in parentheses, like this:
       *(.literal .text)
because it is now allowed mix literals in .text to bring them in range.

None of this is done by standard vmlinux.lds.h macros such as TEXT_TEXT
and INIT_TEXT.  To avoid replicating the logic of that header file, we
instead post-process the generated linker script to convert *(xxx.text)
to *(xxx.literal xxx.text) for the following text sections:
       .text .ref.text .*init.text .*exit.text .text.*
using a sed script.  To do this we must override the default rule for
vmlinux.lds (see scripts/Makefile.build and the top-level Makefile)
to insert this extra step.

Signed-off-by: default avatarMarc Gauthier <marc@tensilica.com>
Signed-off-by: default avatarPete Delaney <piet@tensilica.com>
Signed-off-by: default avatarChris Zankel <chris@zankel.net>
parent 866e514d
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -4,15 +4,30 @@

extra-y := head.o vmlinux.lds


obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \
	 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o  \
	 pci-dma.o init_task.o io.o

## windowspill.o

obj-$(CONFIG_KGDB) += xtensa-stub.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o

# In the Xtensa architecture, assembly generates literals which must always
# precede the L32R instruction with a relative offset less than 256 kB.
# Therefore, the .text and .literal section must be combined in parenthesis
# in the linker script, such as: *(.literal .text).
#
# We need to post-process the generated vmlinux.lds scripts to convert
# *(xxx.text) to  *(xxx.literal xxx.text) for the following text sections:
#   .text .ref.text .*init.text .*exit.text .text.*
#
# Replicate rules in scripts/Makefile.build

sed-y = -e 's/(\(\.[a-z]*it\|\.ref\|\)\.text)/(\1.literal \1.text)/g'	\
	-e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g'

quiet_cmd__cpp_lds_S = LDS     $@
      cmd__cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ $< | sed $(sed-y) >$@

$(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE
	$(call if_changed_dep,_cpp_lds_S)
+1 −3
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ SECTIONS
  {
    /* The HEAD_TEXT section must be the first section! */
    HEAD_TEXT
    *(.literal .text)
    TEXT_TEXT
    VMLINUX_SYMBOL(__sched_text_start) = .;
    *(.sched.literal .sched.text)
    VMLINUX_SYMBOL(__sched_text_end) = .;
@@ -139,8 +139,6 @@ SECTIONS
  __init_begin = .;
  .init.text : {
  	_sinittext = .;
	*(.init.literal) *(.cpuinit.literal) 
	*(.devinit.literal) *(.meminit.literal)
	INIT_TEXT
	_einittext = .;
  }