[PATCH] RFC: xen/x86: Enable --gc-sections

Jason Andryuk posted 1 patch 5 days, 6 hours ago
xen/arch/x86/Makefile     |  3 +++
xen/arch/x86/xen.lds.S    | 38 +++++++++++++++++++-------------------
xen/include/xen/xen.lds.h | 18 +++++++++---------
3 files changed, 31 insertions(+), 28 deletions(-)
[PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jason Andryuk 5 days, 6 hours ago
When linking to create xen-syms, add --gc-sections to garbage collect
unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS

We need to add KEEP() to the linker script in assorted places to retain
appropriate data - especially the arrays created therein.

Something is off though.  In a test where memory_add() is unreachable,
it is still included.  I'm not sure, but I am wondering if it's the
alternatives somehow keeping a reference to it.

Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
---
With --print-gc-sections on defconfig:
ld: removing unused section '.text.__bitmap_full' in file 'prelink.o'
ld: removing unused section '.text.__bitmap_xor' in file 'prelink.o'
ld: removing unused section '.text.__bitmap_set' in file 'prelink.o'
ld: removing unused section '.text.__bitmap_clear' in file 'prelink.o'
ld: removing unused section '.text.bitmap_find_free_region' in file 'prelink.o'
ld: removing unused section '.text.bitmap_release_region' in file 'prelink.o'
ld: removing unused section '.text.domain_has_ioreq_server' in file 'prelink.o'
ld: removing unused section '.text.compat_kexec_op' in file 'prelink.o'
ld: removing unused section '.text.in_atomic' in file 'prelink.o'
ld: removing unused section '.text.radix_tree_next_hole' in file 'prelink.o'
ld: removing unused section '.text.radix_tree_prev_hole' in file 'prelink.o'
ld: removing unused section '.text.radix_tree_gang_lookup_slot' in file 'prelink.o'
ld: removing unused section '.text._nrspin_trylock' in file 'prelink.o'
ld: removing unused section '.text.xen_compile_host' in file 'prelink.o'
ld: removing unused section '.text.vscnprintf' in file 'prelink.o'
ld: removing unused section '.text.wake_up_one' in file 'prelink.o'
ld: removing unused section '.text.xmem_pool_get_used_size' in file 'prelink.o'
ld: removing unused section '.text.xmem_pool_get_total_size' in file 'prelink.o'
ld: removing unused section '.text.xmem_pool_maxalloc' in file 'prelink.o'
ld: removing unused section '.text.xlat_start_info' in file 'prelink.o'
ld: removing unused section '.text.elf_sym_by_name' in file 'prelink.o'
ld: removing unused section '.text.elf_sym_by_index' in file 'prelink.o'
ld: removing unused section '.text.elf_get_ptr' in file 'prelink.o'
ld: removing unused section '.text.elf_lookup_addr' in file 'prelink.o'
ld: removing unused section '.text.serial_vuart_info' in file 'prelink.o'
ld: removing unused section '.text.pci_find_next_cap' in file 'prelink.o'
ld: removing unused section '.text.free_hvm_irq_dpci' in file 'prelink.o'
ld: removing unused section '.text.mce_barrier_init' in file 'prelink.o'
ld: removing unused section '.text.mce_barrier_dec' in file 'prelink.o'
ld: removing unused section '.text.mce_barrier' in file 'prelink.o'
ld: removing unused section '.text.apei_read_mce' in file 'prelink.o'
ld: removing unused section '.text.apei_check_mce' in file 'prelink.o'
ld: removing unused section '.text.apei_clear_mce' in file 'prelink.o'
ld: removing unused section '.text.efi_halt_system' in file 'prelink.o'
ld: removing unused section '.text.get_vvmcs_virtual_safe' in file 'prelink.o'
ld: removing unused section '.text.get_vvmcs_real_safe' in file 'prelink.o'
ld: removing unused section '.text.set_vvmcs_real' in file 'prelink.o'
ld: removing unused section '.text.set_vvmcs_virtual_safe' in file 'prelink.o'
ld: removing unused section '.text.set_vvmcs_real_safe' in file 'prelink.o'
ld: removing unused section '.text.domain_set_alloc_bitsize' in file 'prelink.o'
ld: removing unused section '.text.watchdog_enabled' in file 'prelink.o'
ld: removing unused section '.text.unset_nmi_callback' in file 'prelink.o'
ld: removing unused section '.text.sha2_256_init' in file 'prelink.o'
ld: removing unused section '.text.xxh64_copy_state' in file 'prelink.o'
ld: removing unused section '.text.xxh64' in file 'prelink.o'
ld: removing unused section '.discard' in file 'prelink.o'
ld: removing unused section '.rodata.xen_compile_host.str1.1' in file 'prelink.o'
ld: removing unused section '.rodata.elf_lookup_addr.str1.1' in file 'prelink.o'
ld: removing unused section '.rodata.apei_read_mce.str1.8' in file 'prelink.o'
ld: removing unused section '.rodata.efi_halt_system.str1.8' in file 'prelink.o'
ld: removing unused section '.rodata.play_dead.str1.1' in file 'prelink.o'
ld: removing unused section '.data.rel.ro.local.fetch_type_names' in file 'prelink.o'
---
 xen/arch/x86/Makefile     |  3 +++
 xen/arch/x86/xen.lds.S    | 38 +++++++++++++++++++-------------------
 xen/include/xen/xen.lds.h | 18 +++++++++---------
 3 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 300cc67407..934c79411a 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -137,18 +137,21 @@ $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
 	$(objtree)/tools/symbols $(all_symbols) --empty > $(dot-target).0.S
 	$(MAKE) $(build)=$(@D) $(dot-target).0.o
 	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
+	      --gc-sections \
 	      $(dot-target).0.o -o $(dot-target).0
 	$(NM) -pa --format=sysv $(dot-target).0 \
 		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
 		> $(dot-target).1.S
 	$(MAKE) $(build)=$(@D) $(dot-target).1.o
 	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
+	      --gc-sections \
 	    $(dot-target).1.o -o $(dot-target).1
 	$(NM) -pa --format=sysv $(dot-target).1 \
 		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort $(syms-warn-dup-y) \
 		> $(dot-target).2.S
 	$(MAKE) $(build)=$(@D) $(dot-target).2.o
 	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
+	      --gc-sections \
 	    $(orphan-handling-y) $(dot-target).2.o -o $@
 	$(NM) -pa --format=sysv $@ \
 		| $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 527872a6db..e3ad58f688 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -76,7 +76,7 @@ SECTIONS
   _start = .;
   DECL_SECTION(.text) {
         _stext = .;            /* Text and read-only data */
-       *(.text.header)
+       KEEP(*(.text.header))
 
        . = ALIGN(PAGE_SIZE);
        _stextentry = .;
@@ -98,7 +98,7 @@ SECTIONS
 #endif
        *(.text.__x86_indirect_thunk_*)
 
-       *(.fixup)
+       KEEP(*(.fixup))
        *(.gnu.warning)
        _etext = .;             /* End of text section */
   } PHDR(text) = 0x9090
@@ -116,12 +116,12 @@ SECTIONS
        . = ALIGN(8);
        /* Exception table */
        __start___ex_table = .;
-       *(.ex_table)
+       KEEP(*(.ex_table))
        __stop___ex_table = .;
 
        /* Pre-exception table */
        __start___pre_ex_table = .;
-       *(.ex_table.pre)
+       KEEP(*(.ex_table.pre))
        __stop___pre_ex_table = .;
 
        . = ALIGN(PAGE_SIZE);
@@ -212,7 +212,7 @@ SECTIONS
         * as binary blobs. The .altinstructions has enough data to get
         * the address and the length of them to patch the kernel safely.
         */
-       *(.altinstr_replacement)
+       KEEP(*(.altinstr_replacement))
 
 #ifdef EFI /* EFI wants to merge all of .init.*  ELF doesn't. */
        . = ALIGN(SMP_CACHE_BYTES);
@@ -225,8 +225,8 @@ SECTIONS
 
        . = ALIGN(POINTER_ALIGN);
        __initdata_cf_clobber_start = .;
-       *(.init.data.cf_clobber)
-       *(.init.rodata.cf_clobber)
+       KEEP(*(.init.data.cf_clobber))
+       KEEP(*(.init.rodata.cf_clobber))
        __initdata_cf_clobber_end = .;
 
        *(.init.rodata)
@@ -234,13 +234,13 @@ SECTIONS
 
        . = ALIGN(POINTER_ALIGN);
        __setup_start = .;
-       *(.init.setup)
+       KEEP(*(.init.setup))
        __setup_end = .;
 
        __initcall_start = .;
-       *(.initcallpresmp.init)
+       KEEP(*(.initcallpresmp.init))
        __presmp_initcall_end = .;
-       *(.initcall1.init)
+       KEEP(*(.initcall1.init))
        __initcall_end = .;
 
        *(.init.data)
@@ -248,10 +248,10 @@ SECTIONS
        *(.init.data.rel.*)
        . = ALIGN(4);
        __trampoline_rel_start = .;
-       *(.trampoline_rel)
+       KEEP(*(.trampoline_rel))
        __trampoline_rel_stop = .;
        __trampoline_seg_start = .;
-       *(.trampoline_seg)
+       KEEP(*(.trampoline_seg))
        __trampoline_seg_stop = .;
        /*
         * struct alt_inst entries. From the header (alternative.h):
@@ -260,21 +260,21 @@ SECTIONS
         */
        . = ALIGN(8);
         __alt_instructions = .;
-        *(.altinstructions)
+        KEEP(*(.altinstructions))
         __alt_instructions_end = .;
         . = ALIGN(4);
         __alt_call_sites_start = .;
-        *(.alt_call_sites)
+        KEEP(*(.alt_call_sites))
         __alt_call_sites_end = .;
 
        LOCK_PROFILE_DATA
 
        . = ALIGN(8);
        __ctors_start = .;
-       *(SORT_BY_INIT_PRIORITY(.init_array.*))
-       *(SORT_BY_INIT_PRIORITY(.ctors.*))
-       *(.init_array)
-       *(.ctors)
+       KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)))
+       KEEP(*(SORT_BY_INIT_PRIORITY(.ctors.*)))
+       KEEP(*(.init_array))
+       KEEP(*(.ctors))
        __ctors_end = .;
   } PHDR(text)
 
@@ -316,7 +316,7 @@ SECTIONS
        *(.data.read_mostly)
        . = ALIGN(8);
        __start_schedulers_array = .;
-       *(.data.schedulers)
+       KEEP(*(.data.schedulers))
        __end_schedulers_array = .;
 
        HYPFS_PARAM
diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h
index f54fb2d152..9a1eb23c73 100644
--- a/xen/include/xen/xen.lds.h
+++ b/xen/include/xen/xen.lds.h
@@ -144,32 +144,32 @@
   . = ALIGN(POINTER_ALIGN);  \
   DECL_SECTION(.adev.info) { \
       _asdevice = .;         \
-      *(.adev.info)          \
+      KEEP(*(.adev.info))    \
       _aedevice = .;         \
   } :text
 
 #define BUGFRAMES                               \
     __start_bug_frames_0 = .;                   \
-    *(.bug_frames.0)                            \
+    KEEP(*(.bug_frames.0))                      \
     __stop_bug_frames_0 = .;                    \
                                                 \
     __start_bug_frames_1 = .;                   \
-    *(.bug_frames.1)                            \
+    KEEP(*(.bug_frames.1))                      \
     __stop_bug_frames_1 = .;                    \
                                                 \
     __start_bug_frames_2 = .;                   \
-    *(.bug_frames.2)                            \
+    KEEP(*(.bug_frames.2))                      \
     __stop_bug_frames_2 = .;                    \
                                                 \
     __start_bug_frames_3 = .;                   \
-    *(.bug_frames.3)                            \
+    KEEP(*(.bug_frames.3))                      \
     __stop_bug_frames_3 = .;
 
 #define DT_DEV_INFO         \
   . = ALIGN(POINTER_ALIGN); \
   DECL_SECTION(.dev.info) { \
        _sdevice = .;        \
-       *(.dev.info)         \
+       KEEP(*(.dev.info))   \
        _edevice = .;        \
   } :text
 
@@ -177,7 +177,7 @@
 #define HYPFS_PARAM              \
        . = ALIGN(POINTER_ALIGN); \
        __paramhypfs_start = .;   \
-       *(.data.paramhypfs)       \
+       KEEP(*(.data.paramhypfs)) \
        __paramhypfs_end = .;
 #else
 #define HYPFS_PARAM
@@ -187,7 +187,7 @@
 #define LOCK_PROFILE_DATA        \
        . = ALIGN(POINTER_ALIGN); \
        __lock_profile_start = .; \
-       *(.lockprofile.data)      \
+       KEEP(*(.lockprofile.data))\
        __lock_profile_end = .;
 #else
 #define LOCK_PROFILE_DATA
@@ -207,7 +207,7 @@
 #define VPCI_ARRAY               \
        . = ALIGN(POINTER_ALIGN); \
        __start_vpci_array = .;   \
-       *(.data.rel.ro.vpci)      \
+       KEEP(*(.data.rel.ro.vpci))\
        __end_vpci_array = .;
 #else
 #define VPCI_ARRAY
-- 
2.51.1
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jan Beulich 21 hours ago
On 05.12.2025 23:28, Jason Andryuk wrote:
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -76,7 +76,7 @@ SECTIONS
>    _start = .;
>    DECL_SECTION(.text) {
>          _stext = .;            /* Text and read-only data */
> -       *(.text.header)
> +       KEEP(*(.text.header))

Andrew already commented on the KEEP()s, yet I'd like to extend on that. The
one above looks to be necessary (from an abstract pov; in practice it shouldn't
be necessary due the entry point being there), but ...

> @@ -98,7 +98,7 @@ SECTIONS
>  #endif
>         *(.text.__x86_indirect_thunk_*)
>  
> -       *(.fixup)
> +       KEEP(*(.fixup))
>         *(.gnu.warning)
>         _etext = .;             /* End of text section */
>    } PHDR(text) = 0x9090
> @@ -116,12 +116,12 @@ SECTIONS
>         . = ALIGN(8);
>         /* Exception table */
>         __start___ex_table = .;
> -       *(.ex_table)
> +       KEEP(*(.ex_table))

... these two for example should be strictly be omitted (as Andrew also hinted
at). I think more preparatory work is necessary here: We may need to use
section groups to associate auxiliary sections with their main ones. Otherwise,
by pulling in full .fixup or .ex_table from an object file, technically unused
.text.* would also need to be retained (due to .fixup / .ex_table having
references into there).

Jan
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Grygorii Strashko 2 days, 10 hours ago

On 06.12.25 00:28, Jason Andryuk wrote:
> When linking to create xen-syms, add --gc-sections to garbage collect
> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
> 
> We need to add KEEP() to the linker script in assorted places to retain
> appropriate data - especially the arrays created therein.
> 
> Something is off though.  In a test where memory_add() is unreachable,
> it is still included.  I'm not sure, but I am wondering if it's the
> alternatives somehow keeping a reference to it.
> 
> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
> ---
> With --print-gc-sections on defconfig:
> ld: removing unused section '.text.__bitmap_full' in file 'prelink.o'
> ld: removing unused section '.text.__bitmap_xor' in file 'prelink.o'
> ld: removing unused section '.text.__bitmap_set' in file 'prelink.o'
> ld: removing unused section '.text.__bitmap_clear' in file 'prelink.o'
> ld: removing unused section '.text.bitmap_find_free_region' in file 'prelink.o'
> ld: removing unused section '.text.bitmap_release_region' in file 'prelink.o'
> ld: removing unused section '.text.domain_has_ioreq_server' in file 'prelink.o'
> ld: removing unused section '.text.compat_kexec_op' in file 'prelink.o'
> ld: removing unused section '.text.in_atomic' in file 'prelink.o'
> ld: removing unused section '.text.radix_tree_next_hole' in file 'prelink.o'
> ld: removing unused section '.text.radix_tree_prev_hole' in file 'prelink.o'
> ld: removing unused section '.text.radix_tree_gang_lookup_slot' in file 'prelink.o'
> ld: removing unused section '.text._nrspin_trylock' in file 'prelink.o'
> ld: removing unused section '.text.xen_compile_host' in file 'prelink.o'
> ld: removing unused section '.text.vscnprintf' in file 'prelink.o'
> ld: removing unused section '.text.wake_up_one' in file 'prelink.o'
> ld: removing unused section '.text.xmem_pool_get_used_size' in file 'prelink.o'
> ld: removing unused section '.text.xmem_pool_get_total_size' in file 'prelink.o'
> ld: removing unused section '.text.xmem_pool_maxalloc' in file 'prelink.o'
> ld: removing unused section '.text.xlat_start_info' in file 'prelink.o'
> ld: removing unused section '.text.elf_sym_by_name' in file 'prelink.o'
> ld: removing unused section '.text.elf_sym_by_index' in file 'prelink.o'
> ld: removing unused section '.text.elf_get_ptr' in file 'prelink.o'
> ld: removing unused section '.text.elf_lookup_addr' in file 'prelink.o'
> ld: removing unused section '.text.serial_vuart_info' in file 'prelink.o'
> ld: removing unused section '.text.pci_find_next_cap' in file 'prelink.o'
> ld: removing unused section '.text.free_hvm_irq_dpci' in file 'prelink.o'
> ld: removing unused section '.text.mce_barrier_init' in file 'prelink.o'
> ld: removing unused section '.text.mce_barrier_dec' in file 'prelink.o'
> ld: removing unused section '.text.mce_barrier' in file 'prelink.o'
> ld: removing unused section '.text.apei_read_mce' in file 'prelink.o'
> ld: removing unused section '.text.apei_check_mce' in file 'prelink.o'
> ld: removing unused section '.text.apei_clear_mce' in file 'prelink.o'
> ld: removing unused section '.text.efi_halt_system' in file 'prelink.o'
> ld: removing unused section '.text.get_vvmcs_virtual_safe' in file 'prelink.o'
> ld: removing unused section '.text.get_vvmcs_real_safe' in file 'prelink.o'
> ld: removing unused section '.text.set_vvmcs_real' in file 'prelink.o'
> ld: removing unused section '.text.set_vvmcs_virtual_safe' in file 'prelink.o'
> ld: removing unused section '.text.set_vvmcs_real_safe' in file 'prelink.o'
> ld: removing unused section '.text.domain_set_alloc_bitsize' in file 'prelink.o'
> ld: removing unused section '.text.watchdog_enabled' in file 'prelink.o'
> ld: removing unused section '.text.unset_nmi_callback' in file 'prelink.o'
> ld: removing unused section '.text.sha2_256_init' in file 'prelink.o'
> ld: removing unused section '.text.xxh64_copy_state' in file 'prelink.o'
> ld: removing unused section '.text.xxh64' in file 'prelink.o'
> ld: removing unused section '.discard' in file 'prelink.o'
> ld: removing unused section '.rodata.xen_compile_host.str1.1' in file 'prelink.o'
> ld: removing unused section '.rodata.elf_lookup_addr.str1.1' in file 'prelink.o'
> ld: removing unused section '.rodata.apei_read_mce.str1.8' in file 'prelink.o'
> ld: removing unused section '.rodata.efi_halt_system.str1.8' in file 'prelink.o'
> ld: removing unused section '.rodata.play_dead.str1.1' in file 'prelink.o'
> ld: removing unused section '.data.rel.ro.local.fetch_type_names' in file 'prelink.o'
> ---
>   xen/arch/x86/Makefile     |  3 +++
>   xen/arch/x86/xen.lds.S    | 38 +++++++++++++++++++-------------------
>   xen/include/xen/xen.lds.h | 18 +++++++++---------
>   3 files changed, 31 insertions(+), 28 deletions(-)
> 
> diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
> index 300cc67407..934c79411a 100644
> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -137,18 +137,21 @@ $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
>   	$(objtree)/tools/symbols $(all_symbols) --empty > $(dot-target).0.S
>   	$(MAKE) $(build)=$(@D) $(dot-target).0.o
>   	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
> +	      --gc-sections \
>   	      $(dot-target).0.o -o $(dot-target).0
>   	$(NM) -pa --format=sysv $(dot-target).0 \
>   		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
>   		> $(dot-target).1.S
>   	$(MAKE) $(build)=$(@D) $(dot-target).1.o
>   	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
> +	      --gc-sections \
>   	    $(dot-target).1.o -o $(dot-target).1
>   	$(NM) -pa --format=sysv $(dot-target).1 \
>   		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort $(syms-warn-dup-y) \
>   		> $(dot-target).2.S
>   	$(MAKE) $(build)=$(@D) $(dot-target).2.o
>   	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
> +	      --gc-sections \

It should work if --gc-sections is used only here - last LD statement.

>   	    $(orphan-handling-y) $(dot-target).2.o -o $@
>   	$(NM) -pa --format=sysv $@ \
>   		| $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \


-- 
Best regards,
-grygorii
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jason Andryuk 2 days, 6 hours ago
On 2025-12-08 13:45, Grygorii Strashko wrote:
> 
> 
> On 06.12.25 00:28, Jason Andryuk wrote:
>> When linking to create xen-syms, add --gc-sections to garbage collect
>> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
>>
>> We need to add KEEP() to the linker script in assorted places to retain
>> appropriate data - especially the arrays created therein.
>>
>> Something is off though.  In a test where memory_add() is unreachable,
>> it is still included.  I'm not sure, but I am wondering if it's the
>> alternatives somehow keeping a reference to it.
>>
>> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
>> ---
>> With --print-gc-sections on defconfig:
>> ld: removing unused section '.text.__bitmap_full' in file 'prelink.o'
>> ld: removing unused section '.text.__bitmap_xor' in file 'prelink.o'
>> ld: removing unused section '.text.__bitmap_set' in file 'prelink.o'
>> ld: removing unused section '.text.__bitmap_clear' in file 'prelink.o'
>> ld: removing unused section '.text.bitmap_find_free_region' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.bitmap_release_region' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.domain_has_ioreq_server' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.compat_kexec_op' in file 'prelink.o'
>> ld: removing unused section '.text.in_atomic' in file 'prelink.o'
>> ld: removing unused section '.text.radix_tree_next_hole' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.radix_tree_prev_hole' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.radix_tree_gang_lookup_slot' in 
>> file 'prelink.o'
>> ld: removing unused section '.text._nrspin_trylock' in file 'prelink.o'
>> ld: removing unused section '.text.xen_compile_host' in file 'prelink.o'
>> ld: removing unused section '.text.vscnprintf' in file 'prelink.o'
>> ld: removing unused section '.text.wake_up_one' in file 'prelink.o'
>> ld: removing unused section '.text.xmem_pool_get_used_size' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.xmem_pool_get_total_size' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.xmem_pool_maxalloc' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.xlat_start_info' in file 'prelink.o'
>> ld: removing unused section '.text.elf_sym_by_name' in file 'prelink.o'
>> ld: removing unused section '.text.elf_sym_by_index' in file 'prelink.o'
>> ld: removing unused section '.text.elf_get_ptr' in file 'prelink.o'
>> ld: removing unused section '.text.elf_lookup_addr' in file 'prelink.o'
>> ld: removing unused section '.text.serial_vuart_info' in file 'prelink.o'
>> ld: removing unused section '.text.pci_find_next_cap' in file 'prelink.o'
>> ld: removing unused section '.text.free_hvm_irq_dpci' in file 'prelink.o'
>> ld: removing unused section '.text.mce_barrier_init' in file 'prelink.o'
>> ld: removing unused section '.text.mce_barrier_dec' in file 'prelink.o'
>> ld: removing unused section '.text.mce_barrier' in file 'prelink.o'
>> ld: removing unused section '.text.apei_read_mce' in file 'prelink.o'
>> ld: removing unused section '.text.apei_check_mce' in file 'prelink.o'
>> ld: removing unused section '.text.apei_clear_mce' in file 'prelink.o'
>> ld: removing unused section '.text.efi_halt_system' in file 'prelink.o'
>> ld: removing unused section '.text.get_vvmcs_virtual_safe' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.get_vvmcs_real_safe' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.set_vvmcs_real' in file 'prelink.o'
>> ld: removing unused section '.text.set_vvmcs_virtual_safe' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.set_vvmcs_real_safe' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.domain_set_alloc_bitsize' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.watchdog_enabled' in file 'prelink.o'
>> ld: removing unused section '.text.unset_nmi_callback' in file 
>> 'prelink.o'
>> ld: removing unused section '.text.sha2_256_init' in file 'prelink.o'
>> ld: removing unused section '.text.xxh64_copy_state' in file 'prelink.o'
>> ld: removing unused section '.text.xxh64' in file 'prelink.o'
>> ld: removing unused section '.discard' in file 'prelink.o'
>> ld: removing unused section '.rodata.xen_compile_host.str1.1' in file 
>> 'prelink.o'
>> ld: removing unused section '.rodata.elf_lookup_addr.str1.1' in file 
>> 'prelink.o'
>> ld: removing unused section '.rodata.apei_read_mce.str1.8' in file 
>> 'prelink.o'
>> ld: removing unused section '.rodata.efi_halt_system.str1.8' in file 
>> 'prelink.o'
>> ld: removing unused section '.rodata.play_dead.str1.1' in file 
>> 'prelink.o'
>> ld: removing unused section '.data.rel.ro.local.fetch_type_names' in 
>> file 'prelink.o'
>> ---
>>   xen/arch/x86/Makefile     |  3 +++
>>   xen/arch/x86/xen.lds.S    | 38 +++++++++++++++++++-------------------
>>   xen/include/xen/xen.lds.h | 18 +++++++++---------
>>   3 files changed, 31 insertions(+), 28 deletions(-)
>>
>> diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
>> index 300cc67407..934c79411a 100644
>> --- a/xen/arch/x86/Makefile
>> +++ b/xen/arch/x86/Makefile
>> @@ -137,18 +137,21 @@ $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
>>       $(objtree)/tools/symbols $(all_symbols) --empty > $(dot-target).0.S
>>       $(MAKE) $(build)=$(@D) $(dot-target).0.o
>>       $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
>> +          --gc-sections \
>>             $(dot-target).0.o -o $(dot-target).0
>>       $(NM) -pa --format=sysv $(dot-target).0 \
>>           | $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
>>           > $(dot-target).1.S
>>       $(MAKE) $(build)=$(@D) $(dot-target).1.o
>>       $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
>> +          --gc-sections \
>>           $(dot-target).1.o -o $(dot-target).1
>>       $(NM) -pa --format=sysv $(dot-target).1 \
>>           | $(objtree)/tools/symbols $(all_symbols) --sysv --sort 
>> $(syms-warn-dup-y) \
>>           > $(dot-target).2.S
>>       $(MAKE) $(build)=$(@D) $(dot-target).2.o
>>       $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
>> +          --gc-sections \
> 
> It should work if --gc-sections is used only here - last LD statement.

I think we want to add it to all three.  That way the same operations 
are performed when generating the symbols in the first two rounds of 
linking.  I think that would omit symbols that may get dropped.

Regards,
Jason

Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jan Beulich 2 days, 20 hours ago
On 05.12.2025 23:28, Jason Andryuk wrote:
> When linking to create xen-syms, add --gc-sections to garbage collect
> unused stuff.

What about xen.efi?

>  Relies on CONFIG_CC_SPLIT_SECTIONS

Yet still ...

> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -137,18 +137,21 @@ $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
>  	$(objtree)/tools/symbols $(all_symbols) --empty > $(dot-target).0.S
>  	$(MAKE) $(build)=$(@D) $(dot-target).0.o
>  	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
> +	      --gc-sections \

... you pass the option unconditionally. Which may be fine from a functional
perspective (little if anything will be saved), but besides being a little
inconsistent with the description I also wonder whether the option won't have
unwanted side effects (longer linking time, bigger working set).

>  	      $(dot-target).0.o -o $(dot-target).0
>  	$(NM) -pa --format=sysv $(dot-target).0 \
>  		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
>  		> $(dot-target).1.S
>  	$(MAKE) $(build)=$(@D) $(dot-target).1.o
>  	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
> +	      --gc-sections \
>  	    $(dot-target).1.o -o $(dot-target).1
>  	$(NM) -pa --format=sysv $(dot-target).1 \
>  		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort $(syms-warn-dup-y) \
>  		> $(dot-target).2.S
>  	$(MAKE) $(build)=$(@D) $(dot-target).2.o
>  	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
> +	      --gc-sections \
>  	    $(orphan-handling-y) $(dot-target).2.o -o $@
>  	$(NM) -pa --format=sysv $@ \

Rather than having to alter three locations (plus another three for xen.efi,
plus another three for every other architecture that would want to follow
suit), should we perhaps introduce $(XEN_FINAL_LDFLAGS) or some such? That
could then have --gc-sections conditionally upon CONFIG_CC_SPLIT_SECTIONS.

I further wonder whether the use of the option wouldn't want gating by its
own Kconfig control (dependent upon CC_SPLIT_SECTIONS). If nothing else than
to have an easy workaround if either we had a usage bug (e.g. a missing
KEEP() somewhere in a linker script) or there was a related bug in the
linker that we end up being affected by.

Jan
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jason Andryuk 2 days, 6 hours ago
On 2025-12-08 03:56, Jan Beulich wrote:
> On 05.12.2025 23:28, Jason Andryuk wrote:
>> When linking to create xen-syms, add --gc-sections to garbage collect
>> unused stuff.
> 
> What about xen.efi?

I tried briefly and it fails to link.  The GCC manual says it is 
considered experimental for PE and COFF.

I just added into EFI_LDFLAGS:
   CC      .xen.efi.0s.o
ld -mi386pep --no-warn-rwx-segments --subsystem=10 
--enable-long-section-names --disable-high-entropy-va --dynamicbase 
--image-base=0xffff82d040000000 --stack=0,0 --heap=0,0 
--section-alignment=0x200000 --file-alignment=0x20 
--major-image-version=4 --minor-image-version=22 --major-os-version=2 
--minor-os-version=0 --major-subsystem-version=2 
--minor-subsystem-version=0 --gc-sections --print-gc-sections 
--build-id=sha1 -T arch/x86/efi.lds prelink.o  ./.xen.efi.0s.o -b 
pe-x86-64 arch/x86/efi/buildid.o -o ./.xen.efi.0xffff82d040000000.0 && :
ld: kexec_reloc is too large
ld: kexec_reloc is too large
ld: 
prelink.o:/home/jandryuk/xen/xen/arch/x86/boot/head.S:60:(.text.header+0x48): 
undefined reference to `start'


>>   Relies on CONFIG_CC_SPLIT_SECTIONS
> 
> Yet still ...
> 
>> --- a/xen/arch/x86/Makefile
>> +++ b/xen/arch/x86/Makefile
>> @@ -137,18 +137,21 @@ $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
>>   	$(objtree)/tools/symbols $(all_symbols) --empty > $(dot-target).0.S
>>   	$(MAKE) $(build)=$(@D) $(dot-target).0.o
>>   	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
>> +	      --gc-sections \
> 
> ... you pass the option unconditionally. Which may be fine from a functional
> perspective (little if anything will be saved), but besides being a little
> inconsistent with the description I also wonder whether the option won't have
> unwanted side effects (longer linking time, bigger working set).
> 
>>   	      $(dot-target).0.o -o $(dot-target).0
>>   	$(NM) -pa --format=sysv $(dot-target).0 \
>>   		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
>>   		> $(dot-target).1.S
>>   	$(MAKE) $(build)=$(@D) $(dot-target).1.o
>>   	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
>> +	      --gc-sections \
>>   	    $(dot-target).1.o -o $(dot-target).1
>>   	$(NM) -pa --format=sysv $(dot-target).1 \
>>   		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort $(syms-warn-dup-y) \
>>   		> $(dot-target).2.S
>>   	$(MAKE) $(build)=$(@D) $(dot-target).2.o
>>   	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \
>> +	      --gc-sections \
>>   	    $(orphan-handling-y) $(dot-target).2.o -o $@
>>   	$(NM) -pa --format=sysv $@ \
> 
> Rather than having to alter three locations (plus another three for xen.efi,
> plus another three for every other architecture that would want to follow
> suit), should we perhaps introduce $(XEN_FINAL_LDFLAGS) or some such? That
> could then have --gc-sections conditionally upon CONFIG_CC_SPLIT_SECTIONS.

Yes, I thought something like thiat would be better after posting.

> I further wonder whether the use of the option wouldn't want gating by its
> own Kconfig control (dependent upon CC_SPLIT_SECTIONS). If nothing else than
> to have an easy workaround if either we had a usage bug (e.g. a missing
> KEEP() somewhere in a linker script) or there was a related bug in the
> linker that we end up being affected by.
Makes sense.

Thanks,
Jason
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jan Beulich 1 day, 21 hours ago
On 09.12.2025 00:00, Jason Andryuk wrote:
> On 2025-12-08 03:56, Jan Beulich wrote:
>> On 05.12.2025 23:28, Jason Andryuk wrote:
>>> When linking to create xen-syms, add --gc-sections to garbage collect
>>> unused stuff.
>>
>> What about xen.efi?
> 
> I tried briefly and it fails to link.  The GCC manual says it is 
> considered experimental for PE and COFF.

The gcc manual documents linker behavior? Do you have a more concrete pointer?

> I just added into EFI_LDFLAGS:
>    CC      .xen.efi.0s.o
> ld -mi386pep --no-warn-rwx-segments --subsystem=10 
> --enable-long-section-names --disable-high-entropy-va --dynamicbase 
> --image-base=0xffff82d040000000 --stack=0,0 --heap=0,0 
> --section-alignment=0x200000 --file-alignment=0x20 
> --major-image-version=4 --minor-image-version=22 --major-os-version=2 
> --minor-os-version=0 --major-subsystem-version=2 
> --minor-subsystem-version=0 --gc-sections --print-gc-sections 
> --build-id=sha1 -T arch/x86/efi.lds prelink.o  ./.xen.efi.0s.o -b 
> pe-x86-64 arch/x86/efi/buildid.o -o ./.xen.efi.0xffff82d040000000.0 && :
> ld: kexec_reloc is too large
> ld: kexec_reloc is too large
> ld: 
> prelink.o:/home/jandryuk/xen/xen/arch/x86/boot/head.S:60:(.text.header+0x48): 
> undefined reference to `start'

I see. This then would want mentioning in the patch description. And I've added
it to my binutils side todo list.

Jan
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jason Andryuk 1 day, 14 hours ago
On 2025-12-09 02:36, Jan Beulich wrote:
> On 09.12.2025 00:00, Jason Andryuk wrote:
>> On 2025-12-08 03:56, Jan Beulich wrote:
>>> On 05.12.2025 23:28, Jason Andryuk wrote:
>>>> When linking to create xen-syms, add --gc-sections to garbage collect
>>>> unused stuff.
>>>
>>> What about xen.efi?
>>
>> I tried briefly and it fails to link.  The GCC manual says it is
>> considered experimental for PE and COFF.
> 
> The gcc manual documents linker behavior? Do you have a more concrete pointer?

My bad - it's binutils.  https://sourceware.org/binutils/docs/ld.html 
down at --gc-sections:
"Note that garbage collection for COFF and PE format targets is 
supported, but the implementation is currently considered to be 
experimental."

>> I just added into EFI_LDFLAGS:
>>     CC      .xen.efi.0s.o
>> ld -mi386pep --no-warn-rwx-segments --subsystem=10
>> --enable-long-section-names --disable-high-entropy-va --dynamicbase
>> --image-base=0xffff82d040000000 --stack=0,0 --heap=0,0
>> --section-alignment=0x200000 --file-alignment=0x20
>> --major-image-version=4 --minor-image-version=22 --major-os-version=2
>> --minor-os-version=0 --major-subsystem-version=2
>> --minor-subsystem-version=0 --gc-sections --print-gc-sections
>> --build-id=sha1 -T arch/x86/efi.lds prelink.o  ./.xen.efi.0s.o -b
>> pe-x86-64 arch/x86/efi/buildid.o -o ./.xen.efi.0xffff82d040000000.0 && :
>> ld: kexec_reloc is too large
>> ld: kexec_reloc is too large
>> ld:
>> prelink.o:/home/jandryuk/xen/xen/arch/x86/boot/head.S:60:(.text.header+0x48):
>> undefined reference to `start'
> 
> I see. This then would want mentioning in the patch description. And I've added
> it to my binutils side todo list.

I trimmed, but the output continues for a long time.

Thanks,
Jason
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Andrew Cooper 5 days, 6 hours ago
On 05/12/2025 10:28 pm, Jason Andryuk wrote:
> When linking to create xen-syms, add --gc-sections to garbage collect
> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
>
> We need to add KEEP() to the linker script in assorted places to retain
> appropriate data - especially the arrays created therein.
>
> Something is off though.  In a test where memory_add() is unreachable,
> it is still included.  I'm not sure, but I am wondering if it's the
> alternatives somehow keeping a reference to it.

Yes, .altinstructions contains relocations against the origin patch
site, which will cause it to appear to be referenced. The same will be
happening with a bunch of other sections.

Hmm.  We are surely not the first people to encounter this.

> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
> ---
> With --print-gc-sections on defconfig:
> ld: removing unused section '.text.__bitmap_full' in file 'prelink.o'
> ld: removing unused section '.text.__bitmap_xor' in file 'prelink.o'
> ld: removing unused section '.text.__bitmap_set' in file 'prelink.o'
> ld: removing unused section '.text.__bitmap_clear' in file 'prelink.o'
> ld: removing unused section '.text.bitmap_find_free_region' in file 'prelink.o'
> ld: removing unused section '.text.bitmap_release_region' in file 'prelink.o'
> ld: removing unused section '.text.domain_has_ioreq_server' in file 'prelink.o'
> ld: removing unused section '.text.compat_kexec_op' in file 'prelink.o'
> ld: removing unused section '.text.in_atomic' in file 'prelink.o'
> ld: removing unused section '.text.radix_tree_next_hole' in file 'prelink.o'
> ld: removing unused section '.text.radix_tree_prev_hole' in file 'prelink.o'
> ld: removing unused section '.text.radix_tree_gang_lookup_slot' in file 'prelink.o'
> ld: removing unused section '.text._nrspin_trylock' in file 'prelink.o'
> ld: removing unused section '.text.xen_compile_host' in file 'prelink.o'
> ld: removing unused section '.text.vscnprintf' in file 'prelink.o'
> ld: removing unused section '.text.wake_up_one' in file 'prelink.o'
> ld: removing unused section '.text.xmem_pool_get_used_size' in file 'prelink.o'
> ld: removing unused section '.text.xmem_pool_get_total_size' in file 'prelink.o'
> ld: removing unused section '.text.xmem_pool_maxalloc' in file 'prelink.o'
> ld: removing unused section '.text.xlat_start_info' in file 'prelink.o'
> ld: removing unused section '.text.elf_sym_by_name' in file 'prelink.o'
> ld: removing unused section '.text.elf_sym_by_index' in file 'prelink.o'
> ld: removing unused section '.text.elf_get_ptr' in file 'prelink.o'
> ld: removing unused section '.text.elf_lookup_addr' in file 'prelink.o'
> ld: removing unused section '.text.serial_vuart_info' in file 'prelink.o'
> ld: removing unused section '.text.pci_find_next_cap' in file 'prelink.o'
> ld: removing unused section '.text.free_hvm_irq_dpci' in file 'prelink.o'
> ld: removing unused section '.text.mce_barrier_init' in file 'prelink.o'
> ld: removing unused section '.text.mce_barrier_dec' in file 'prelink.o'
> ld: removing unused section '.text.mce_barrier' in file 'prelink.o'
> ld: removing unused section '.text.apei_read_mce' in file 'prelink.o'
> ld: removing unused section '.text.apei_check_mce' in file 'prelink.o'
> ld: removing unused section '.text.apei_clear_mce' in file 'prelink.o'
> ld: removing unused section '.text.efi_halt_system' in file 'prelink.o'
> ld: removing unused section '.text.get_vvmcs_virtual_safe' in file 'prelink.o'
> ld: removing unused section '.text.get_vvmcs_real_safe' in file 'prelink.o'
> ld: removing unused section '.text.set_vvmcs_real' in file 'prelink.o'
> ld: removing unused section '.text.set_vvmcs_virtual_safe' in file 'prelink.o'
> ld: removing unused section '.text.set_vvmcs_real_safe' in file 'prelink.o'
> ld: removing unused section '.text.domain_set_alloc_bitsize' in file 'prelink.o'
> ld: removing unused section '.text.watchdog_enabled' in file 'prelink.o'
> ld: removing unused section '.text.unset_nmi_callback' in file 'prelink.o'
> ld: removing unused section '.text.sha2_256_init' in file 'prelink.o'
> ld: removing unused section '.text.xxh64_copy_state' in file 'prelink.o'
> ld: removing unused section '.text.xxh64' in file 'prelink.o'
> ld: removing unused section '.discard' in file 'prelink.o'
> ld: removing unused section '.rodata.xen_compile_host.str1.1' in file 'prelink.o'
> ld: removing unused section '.rodata.elf_lookup_addr.str1.1' in file 'prelink.o'
> ld: removing unused section '.rodata.apei_read_mce.str1.8' in file 'prelink.o'
> ld: removing unused section '.rodata.efi_halt_system.str1.8' in file 'prelink.o'
> ld: removing unused section '.rodata.play_dead.str1.1' in file 'prelink.o'
> ld: removing unused section '.data.rel.ro.local.fetch_type_names' in file 'prelink.o'

This is for your safety stripped-down build, I'm guessing?

It's certainly a good start.

> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
> index 527872a6db..e3ad58f688 100644
> --- a/xen/arch/x86/xen.lds.S
> +++ b/xen/arch/x86/xen.lds.S
> @@ -98,7 +98,7 @@ SECTIONS
>  #endif
>         *(.text.__x86_indirect_thunk_*)
>  
> -       *(.fixup)
> +       KEEP(*(.fixup))

Why do we need to KEEP() this?  The references here are the other way
around to most examples.

Although I note that removing .fixup is on the cleanup list, and would
this problem too.

~Andrew

Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jan Beulich 2 days, 20 hours ago
On 05.12.2025 23:40, Andrew Cooper wrote:
> On 05/12/2025 10:28 pm, Jason Andryuk wrote:
>> When linking to create xen-syms, add --gc-sections to garbage collect
>> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
>>
>> We need to add KEEP() to the linker script in assorted places to retain
>> appropriate data - especially the arrays created therein.
>>
>> Something is off though.  In a test where memory_add() is unreachable,
>> it is still included.  I'm not sure, but I am wondering if it's the
>> alternatives somehow keeping a reference to it.
> 
> Yes, .altinstructions contains relocations against the origin patch
> site, which will cause it to appear to be referenced. The same will be
> happening with a bunch of other sections.

We will need to derive helper section names from base section ones. See
e.g. HAVE_AS_SECTNAME_SUBST as introduced by "common: honor
CONFIG_CC_SPLIT_SECTIONS also for assembly functions", controlling the
use of the --sectname-subst asssembler option, to in turn be able to use
%S in section names (available from gas 2.26 onwards).

I'd like to point out though that for the purpose of "x86/alternatives:
allow replacement code snippets to be merged" we may want to avoid
extending this to .altinstr_replacement.

Jan
Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jason Andryuk 1 day, 7 hours ago
On 2025-12-08 03:46, Jan Beulich wrote:
> On 05.12.2025 23:40, Andrew Cooper wrote:
>> On 05/12/2025 10:28 pm, Jason Andryuk wrote:
>>> When linking to create xen-syms, add --gc-sections to garbage collect
>>> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
>>>
>>> We need to add KEEP() to the linker script in assorted places to retain
>>> appropriate data - especially the arrays created therein.
>>>
>>> Something is off though.  In a test where memory_add() is unreachable,
>>> it is still included.  I'm not sure, but I am wondering if it's the
>>> alternatives somehow keeping a reference to it.
>>
>> Yes, .altinstructions contains relocations against the origin patch
>> site, which will cause it to appear to be referenced. The same will be
>> happening with a bunch of other sections.
> 
> We will need to derive helper section names from base section ones. See
> e.g. HAVE_AS_SECTNAME_SUBST as introduced by "common: honor
> CONFIG_CC_SPLIT_SECTIONS also for assembly functions", controlling the
> use of the --sectname-subst asssembler option, to in turn be able to use
> %S in section names (available from gas 2.26 onwards).

I tried to add your patch and change ALTERNATIVE to:
".pushsection .altinstructions.%S, \"a\", @progbits\n"
but it fails to build.  One example:
./include/xen/compiler.h:62:21: error: invalid 'asm': operand number 
missing after %-letter
    62 | # define asm_inline asm __inline
       |                     ^~~
./arch/x86/include/asm/pdx.h:13:5: note: in expansion of macro ‘asm_inline’
    13 |     asm_inline goto (                               \
       |     ^~~~~~~~~~
./arch/x86/include/asm/pdx.h:22:5: note: in expansion of macro 
‘PDX_ASM_GOTO’
    22 |     PDX_ASM_GOTO(skip);
       |     ^~~~~~~~~~~~

".pushsection .altinstructions.%%S, \"a\", @progbits\n" ends up creating 
section ".altinstructions.%S" which doesn't helpful.

Is %S expected to work with inline asm, or only standalone?

Regards,
Jason

Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jan Beulich 22 hours ago
On 09.12.2025 22:55, Jason Andryuk wrote:
> On 2025-12-08 03:46, Jan Beulich wrote:
>> On 05.12.2025 23:40, Andrew Cooper wrote:
>>> On 05/12/2025 10:28 pm, Jason Andryuk wrote:
>>>> When linking to create xen-syms, add --gc-sections to garbage collect
>>>> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
>>>>
>>>> We need to add KEEP() to the linker script in assorted places to retain
>>>> appropriate data - especially the arrays created therein.
>>>>
>>>> Something is off though.  In a test where memory_add() is unreachable,
>>>> it is still included.  I'm not sure, but I am wondering if it's the
>>>> alternatives somehow keeping a reference to it.
>>>
>>> Yes, .altinstructions contains relocations against the origin patch
>>> site, which will cause it to appear to be referenced. The same will be
>>> happening with a bunch of other sections.
>>
>> We will need to derive helper section names from base section ones. See
>> e.g. HAVE_AS_SECTNAME_SUBST as introduced by "common: honor
>> CONFIG_CC_SPLIT_SECTIONS also for assembly functions", controlling the
>> use of the --sectname-subst asssembler option, to in turn be able to use
>> %S in section names (available from gas 2.26 onwards).
> 
> I tried to add your patch and change ALTERNATIVE to:
> ".pushsection .altinstructions.%S, \"a\", @progbits\n"
> but it fails to build.  One example:
> ./include/xen/compiler.h:62:21: error: invalid 'asm': operand number 
> missing after %-letter
>     62 | # define asm_inline asm __inline
>        |                     ^~~
> ./arch/x86/include/asm/pdx.h:13:5: note: in expansion of macro ‘asm_inline’
>     13 |     asm_inline goto (                               \
>        |     ^~~~~~~~~~
> ./arch/x86/include/asm/pdx.h:22:5: note: in expansion of macro 
> ‘PDX_ASM_GOTO’
>     22 |     PDX_ASM_GOTO(skip);
>        |     ^~~~~~~~~~~~
> 
> ".pushsection .altinstructions.%%S, \"a\", @progbits\n" ends up creating 
> section ".altinstructions.%S" which doesn't helpful.
> 
> Is %S expected to work with inline asm, or only standalone?

Both, as long as --sectname-subst is passed to the assembler. My patch adds
that option to AFLAGS only, whereas for inline assembly it would need adding
to CFLAGS. Did you perhaps overlook that?

Jan

Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jason Andryuk 14 hours ago
On 2025-12-10 02:09, Jan Beulich wrote:
> On 09.12.2025 22:55, Jason Andryuk wrote:
>> On 2025-12-08 03:46, Jan Beulich wrote:
>>> On 05.12.2025 23:40, Andrew Cooper wrote:
>>>> On 05/12/2025 10:28 pm, Jason Andryuk wrote:
>>>>> When linking to create xen-syms, add --gc-sections to garbage collect
>>>>> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
>>>>>
>>>>> We need to add KEEP() to the linker script in assorted places to retain
>>>>> appropriate data - especially the arrays created therein.
>>>>>
>>>>> Something is off though.  In a test where memory_add() is unreachable,
>>>>> it is still included.  I'm not sure, but I am wondering if it's the
>>>>> alternatives somehow keeping a reference to it.
>>>>
>>>> Yes, .altinstructions contains relocations against the origin patch
>>>> site, which will cause it to appear to be referenced. The same will be
>>>> happening with a bunch of other sections.
>>>
>>> We will need to derive helper section names from base section ones. See
>>> e.g. HAVE_AS_SECTNAME_SUBST as introduced by "common: honor
>>> CONFIG_CC_SPLIT_SECTIONS also for assembly functions", controlling the
>>> use of the --sectname-subst asssembler option, to in turn be able to use
>>> %S in section names (available from gas 2.26 onwards).
>>
>> I tried to add your patch and change ALTERNATIVE to:
>> ".pushsection .altinstructions.%S, \"a\", @progbits\n"
>> but it fails to build.  One example:
>> ./include/xen/compiler.h:62:21: error: invalid 'asm': operand number
>> missing after %-letter
>>      62 | # define asm_inline asm __inline
>>         |                     ^~~
>> ./arch/x86/include/asm/pdx.h:13:5: note: in expansion of macro ‘asm_inline’
>>      13 |     asm_inline goto (                               \
>>         |     ^~~~~~~~~~
>> ./arch/x86/include/asm/pdx.h:22:5: note: in expansion of macro
>> ‘PDX_ASM_GOTO’
>>      22 |     PDX_ASM_GOTO(skip);
>>         |     ^~~~~~~~~~~~
>>
>> ".pushsection .altinstructions.%%S, \"a\", @progbits\n" ends up creating
>> section ".altinstructions.%S" which doesn't helpful.
>>
>> Is %S expected to work with inline asm, or only standalone?
> 
> Both, as long as --sectname-subst is passed to the assembler. My patch adds
> that option to AFLAGS only, whereas for inline assembly it would need adding
> to CFLAGS. Did you perhaps overlook that?

Yes, you are correct - I had not changed CFLAGS.  With that updated, the 
%%S form creates sections:
.altinstructions..text.set_domain_state_info

Thanks,
Jason

Re: [PATCH] RFC: xen/x86: Enable --gc-sections
Posted by Jason Andryuk 5 days, 6 hours ago
On 2025-12-05 17:40, Andrew Cooper wrote:
> On 05/12/2025 10:28 pm, Jason Andryuk wrote:
>> When linking to create xen-syms, add --gc-sections to garbage collect
>> unused stuff.  Relies on CONFIG_CC_SPLIT_SECTIONS
>>
>> We need to add KEEP() to the linker script in assorted places to retain
>> appropriate data - especially the arrays created therein.
>>
>> Something is off though.  In a test where memory_add() is unreachable,
>> it is still included.  I'm not sure, but I am wondering if it's the
>> alternatives somehow keeping a reference to it.
> 
> Yes, .altinstructions contains relocations against the origin patch
> site, which will cause it to appear to be referenced. The same will be
> happening with a bunch of other sections.
> 
> Hmm.  We are surely not the first people to encounter this.

I didn't find any magic in Linux, but I didn't look too hard.

>> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
>> ---
>> With --print-gc-sections on defconfig:
>> ld: removing unused section '.text.__bitmap_full' in file 'prelink.o'
>> ld: removing unused section '.text.__bitmap_xor' in file 'prelink.o'
>> ld: removing unused section '.text.__bitmap_set' in file 'prelink.o'
>> ld: removing unused section '.text.__bitmap_clear' in file 'prelink.o'
>> ld: removing unused section '.text.bitmap_find_free_region' in file 'prelink.o'
>> ld: removing unused section '.text.bitmap_release_region' in file 'prelink.o'
>> ld: removing unused section '.text.domain_has_ioreq_server' in file 'prelink.o'
>> ld: removing unused section '.text.compat_kexec_op' in file 'prelink.o'
>> ld: removing unused section '.text.in_atomic' in file 'prelink.o'
>> ld: removing unused section '.text.radix_tree_next_hole' in file 'prelink.o'
>> ld: removing unused section '.text.radix_tree_prev_hole' in file 'prelink.o'
>> ld: removing unused section '.text.radix_tree_gang_lookup_slot' in file 'prelink.o'
>> ld: removing unused section '.text._nrspin_trylock' in file 'prelink.o'
>> ld: removing unused section '.text.xen_compile_host' in file 'prelink.o'
>> ld: removing unused section '.text.vscnprintf' in file 'prelink.o'
>> ld: removing unused section '.text.wake_up_one' in file 'prelink.o'
>> ld: removing unused section '.text.xmem_pool_get_used_size' in file 'prelink.o'
>> ld: removing unused section '.text.xmem_pool_get_total_size' in file 'prelink.o'
>> ld: removing unused section '.text.xmem_pool_maxalloc' in file 'prelink.o'
>> ld: removing unused section '.text.xlat_start_info' in file 'prelink.o'
>> ld: removing unused section '.text.elf_sym_by_name' in file 'prelink.o'
>> ld: removing unused section '.text.elf_sym_by_index' in file 'prelink.o'
>> ld: removing unused section '.text.elf_get_ptr' in file 'prelink.o'
>> ld: removing unused section '.text.elf_lookup_addr' in file 'prelink.o'
>> ld: removing unused section '.text.serial_vuart_info' in file 'prelink.o'
>> ld: removing unused section '.text.pci_find_next_cap' in file 'prelink.o'
>> ld: removing unused section '.text.free_hvm_irq_dpci' in file 'prelink.o'
>> ld: removing unused section '.text.mce_barrier_init' in file 'prelink.o'
>> ld: removing unused section '.text.mce_barrier_dec' in file 'prelink.o'
>> ld: removing unused section '.text.mce_barrier' in file 'prelink.o'
>> ld: removing unused section '.text.apei_read_mce' in file 'prelink.o'
>> ld: removing unused section '.text.apei_check_mce' in file 'prelink.o'
>> ld: removing unused section '.text.apei_clear_mce' in file 'prelink.o'
>> ld: removing unused section '.text.efi_halt_system' in file 'prelink.o'
>> ld: removing unused section '.text.get_vvmcs_virtual_safe' in file 'prelink.o'
>> ld: removing unused section '.text.get_vvmcs_real_safe' in file 'prelink.o'
>> ld: removing unused section '.text.set_vvmcs_real' in file 'prelink.o'
>> ld: removing unused section '.text.set_vvmcs_virtual_safe' in file 'prelink.o'
>> ld: removing unused section '.text.set_vvmcs_real_safe' in file 'prelink.o'
>> ld: removing unused section '.text.domain_set_alloc_bitsize' in file 'prelink.o'
>> ld: removing unused section '.text.watchdog_enabled' in file 'prelink.o'
>> ld: removing unused section '.text.unset_nmi_callback' in file 'prelink.o'
>> ld: removing unused section '.text.sha2_256_init' in file 'prelink.o'
>> ld: removing unused section '.text.xxh64_copy_state' in file 'prelink.o'
>> ld: removing unused section '.text.xxh64' in file 'prelink.o'
>> ld: removing unused section '.discard' in file 'prelink.o'
>> ld: removing unused section '.rodata.xen_compile_host.str1.1' in file 'prelink.o'
>> ld: removing unused section '.rodata.elf_lookup_addr.str1.1' in file 'prelink.o'
>> ld: removing unused section '.rodata.apei_read_mce.str1.8' in file 'prelink.o'
>> ld: removing unused section '.rodata.efi_halt_system.str1.8' in file 'prelink.o'
>> ld: removing unused section '.rodata.play_dead.str1.1' in file 'prelink.o'
>> ld: removing unused section '.data.rel.ro.local.fetch_type_names' in file 'prelink.o'
> 
> This is for your safety stripped-down build, I'm guessing?

This is actually Xen staging.

> It's certainly a good start.
> 
>> diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
>> index 527872a6db..e3ad58f688 100644
>> --- a/xen/arch/x86/xen.lds.S
>> +++ b/xen/arch/x86/xen.lds.S
>> @@ -98,7 +98,7 @@ SECTIONS
>>   #endif
>>          *(.text.__x86_indirect_thunk_*)
>>   
>> -       *(.fixup)
>> +       KEEP(*(.fixup))
> 
> Why do we need to KEEP() this?  The references here are the other way
> around to most examples.

I thought I saw it dropped when trying to get this working, but it does 
seem to work by removing the KEEP().

Thanks for taking a look.

This implicitly relies on LIVEPATCH to select CC_SPLIT_SECTIONS.  To be 
standalone, X86 can just select CC_SPLIT_SECTIONS unless we want to make 
it optional.

Regards,
Jason