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

Re: [PATCH] Arm: do a 4th linking pass if necessary



On 5/20/26 1:53 PM, Jan Beulich wrote:
The .rodata growth between 1st and 2nd linking passes may affect the
number of stubs the linker wants to insert, which in turn affects the
number of symbols. If symbol table sizes change after the 2nd linking
pass, insert another one before the final one. (As a comment in Linux puts
it, "In theory it's possible this results in even more stubs, but
unlikely.")

To use the $(compare-symbol-tables) macro in a shell "if", it needs
slightly adjusting (and then wrapping to be run in a sub-shell).

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
There's imo no good Fixes: tag, since (aiui) stubs (veneers) may also be
inserted for reasons other than errata workarounds.

For context: The Cortex A53 erratum 843419 workaround in GNU ld comes in
two flavors: In the general case a stub is inserted, but if the problem
ADRP can be replaced by ADR (i.e. the target symbol is within ±1Mb), then
that's preferred and no stub is needed. The addition of the symbol table
data is what then results in the stub-less form to no longer be usable in
affected configurations. A possible countermeasure could be to move
.rodata ahead of .text. (Also, from looking at generated code, it may well
be that newer gcc simply avoids producing problematic insn sequences.)

Linux simply compares object file sizes, but I consider that fragile: A
change in size of one of the symbol table constituents may not necessarily
change the object file size, due to padding which may be in use.

Once we generalize linking, we may want to introduce an equivalent of
Linux'es KALLSYMS_EXTRA_PASS as well. I don't think doing this right here
would make overly much sense, though.

Probably we want to have the similar for RISC-V. Not so far time ago in downstream we faced the following issue:
https://gitlab.com/xen-project/people/olkur/xen/-/jobs/14389897308

Unfortunately I wasn't able to reproduce it locally and it was only on CI but I suggested the similar to this fix and it helped:

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index a1124eb5d072..72b9789cfd9c 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -52,9 +52,15 @@ $(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)
        $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
-           $(dot-target).2.o -o $@
+           $(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)
+       $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
+           $(dot-target).3.o -o $@
        $(NM) -pa --format=sysv $@ \
                | $(objtree)/tools/symbols --all-symbols --xensyms --sysv 
--sort \
                > $@.map

The fix wasn't sent as after merging some extra patches on top of it the issue just disappear.


--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -99,9 +99,20 @@ $(TARGET)-syms: $(objtree)/prelink.o $(o
                | $(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 \
+               $(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
--- a/xen/scripts/Kbuild.include
+++ b/xen/scripts/Kbuild.include
@@ -65,7 +65,7 @@ define compare-symbol-tables
      $(OBJDUMP) -t $(@D)/.cst.$$$$ > $(1).sym; \
      ln -f $(2) $(@D)/.cst.$$$$; \
      $(OBJDUMP) -t $(@D)/.cst.$$$$ > $(2).sym; \
-    rm -f $(@D)/.cst.$$$$
+    rm -f $(@D)/.cst.$$$$; \
      diff -u $(1).sym $(2).sym
  endef

LGTM:
 Reviewed-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>

Thanks.

~ Oleksii



 


Rackspace

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