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

Oleksii Kurochko <[email protected]>
Newsgroups org.xenproject.lists.xen-devel
Message-ID <ff85121d7aea88f5e1e8eec729a11512f22c168c.1784559209.git.oleksii.kurochko@gmail.com>
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 <[email protected]>
---
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 \
 		> [email protected]
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.