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(-)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
© 2016 - 2025 Red Hat, Inc.