[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v6 23/23] xen/riscv: do a 4th linking pass if necessary



Embedding the symbol table can shift sections and flip relaxation
decisions, changing code size and thus the set of emitted tools/symbols
(e.g. gap end markers).  Re-link with a regenerated table when its
size differs from the previous pass.

This takes the same remedy as commit 35de7285d508 ("Arm: do a 4th
linking pass if necessary"), though the underlying cause differs:
here no symbol (dis)appears from the ELF symbol table; instead the
set of end markers emitted by tools/symbols legitimately changes,
because want_symbol_end() depends on code layout, and layout differs
between passes due to linker relaxation.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
I faced this issue again in downstream:
  https://gitlab.com/xen-project/people/olkur/xen/-/jobs/15171254706

Root cause: embedding the symbol table shifts .init.text far enough
that 4 JAL call sites from .text into .init.text (e.g. to
alloc_boot_pages()) exceed the ±1MB range the linker can relax, so
they fall back to auipc+jalr, growing .text by 16 bytes total. That
shift moves simple_strtoull() by the same amount, closing a 16-byte
alignment gap that used to precede turn_on_mmu(). Since
want_symbol_end() no longer sees a gap, tools/symbols stops emitting
the synthetic "end of symbol" marker for simple_strtoull(), which is
why symbols_addresses/symbols_names differ in size between pass 1
and pass 2.
---
Changes in v6:
 - Update the commit message and footer after it.
---
Changes in v5:
 - New patch.
---
---
 xen/arch/riscv/Makefile | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index fc6b34661111..046f73f4d87c 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -50,9 +50,21 @@ $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
                | $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
                > $(dot-target).2.S
        $(MAKE) $(build)=$(@D) $(dot-target).2.o
-       $(call compare-symbol-tables, $(dot-target).1.o, $(dot-target).2.o)
+       if ! { $(call compare-symbol-tables, $(dot-target).1.o, 
$(dot-target).2.o) >/dev/null; }; \
+       then \
+               set -e; \
+               $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
+                   $(dot-target).2.o -o $(dot-target).2; \
+               $(NM) -pa --format=sysv $(dot-target).2 \
+                       | $(objtree)/tools/symbols $(all_symbols) --sysv --sort 
\
+                       > $(dot-target).3.S; \
+               $(MAKE) $(build)=$(@D) $(dot-target).3.o; \
+               $(call compare-symbol-tables, $(dot-target).2.o, 
$(dot-target).3.o); \
+       else \
+               ln -sf $(dot-target).2.o $(dot-target).3.o; \
+       fi
        $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
-           $(dot-target).2.o -o $@
+           $(dot-target).3.o -o $@
        $(NM) -pa --format=sysv $@ \
                | $(objtree)/tools/symbols --all-symbols --xensyms --sysv 
--sort \
                > $@.map
-- 
2.54.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.