[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] x86/build: use --orphan-handling linker option if available
commit dedb0aa42c6d1ee31805dfc61630db2c41117330 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Mon Mar 14 10:33:35 2022 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Mon Mar 14 10:33:35 2022 +0100 x86/build: use --orphan-handling linker option if available As was e.g. making necessary 4b7fd8153ddf ("x86: fold sections in final binaries"), arbitrary sections appearing without our linker script placing them explicitly can be a problem. Have the linker make us aware of such sections, so we would know that the script needs adjusting. To deal with the resulting warnings: - Retain .note.* explicitly for ELF, and discard all of them (except the earlier consumed .note.gnu.build-id) for PE/COFF. - Have explicit statements for .got, .plt, and alike and add assertions that they're empty. No output sections will be created for these as long as they remain empty (or else the assertions would cause early failure anyway). - Collect all .rela.* into a single section, with again an assertion added for the resulting section to be empty. - Extend the enumerating of .debug_* to ELF. Note that for Clang adding of .debug_macinfo is necessary. Amend this by its Dwarf5 counterpart, .debug_macro, then as well (albeit more may need adding for full coverage). - For LLVM ld also enumerate .symtab, .strtab, and .shstrtab. Suggested-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/arch/x86/Makefile | 6 +- xen/arch/x86/xen.lds.S | 168 +++++++++++++++++++++++++++++-------------------- 2 files changed, 105 insertions(+), 69 deletions(-) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 04065a7310..b6b082ee1d 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -119,6 +119,8 @@ syms-warn-dup-y := --warn-dup syms-warn-dup-$(CONFIG_SUPPRESS_DUPLICATE_SYMBOL_WARNINGS) := syms-warn-dup-$(CONFIG_ENFORCE_UNIQUE_SYMBOLS) := --error-dup +orphan-handling-$(call ld-option,--orphan-handling=warn) += --orphan-handling=warn + $(TARGET): TMP = $(@D)/.$(@F).elf32 $(TARGET): $(TARGET)-syms $(efi-y) $(obj)/boot/mkelf32 $(obj)/boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TMP) $(XEN_IMG_OFFSET) \ @@ -145,7 +147,7 @@ $(TARGET)-syms: $(BASEDIR)/prelink.o $(obj)/xen.lds >$(@D)/.$(@F).1.S $(MAKE) $(build)=$(@D) $(@D)/.$(@F).1.o $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< $(build_id_linker) \ - $(@D)/.$(@F).1.o -o $@ + $(orphan-handling-y) $(@D)/.$(@F).1.o -o $@ $(NM) -pa --format=sysv $(@D)/$(@F) \ | $(BASEDIR)/tools/symbols --all-symbols --xensyms --sysv --sort \ >$(@D)/$(@F).map @@ -219,7 +221,7 @@ endif | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).1s.S $(MAKE) $(build)=$(@D) .$(@F).1r.o .$(@F).1s.o $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T $(obj)/efi.lds -N $< \ - $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(note_file_option) -o $@ + $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(orphan-handling-y) $(note_file_option) -o $@ $(NM) -pa --format=sysv $(@D)/$(@F) \ | $(BASEDIR)/tools/symbols --all-symbols --xensyms --sysv --sort >$(@D)/$(@F).map rm -f $(@D)/.$(@F).[0-9]* $(@D)/..$(@F).[0-9]* diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 4103763f63..7aa1f82df9 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -12,6 +12,13 @@ #undef __XEN_VIRT_START #define __XEN_VIRT_START __image_base__ #define DECL_SECTION(x) x : +/* + * Use the NOLOAD directive, despite currently ignored by (at least) GNU ld + * for PE output, in order to record that we'd prefer these sections to not + * be loaded into memory. + */ +#define DECL_DEBUG(x, a) #x ALIGN(a) (NOLOAD) : { *(x) } +#define DECL_DEBUG2(x, y, a) #x ALIGN(a) (NOLOAD) : { *(x) *(y) } ENTRY(efi_start) @@ -19,6 +26,8 @@ ENTRY(efi_start) #define FORMAT "elf64-x86-64" #define DECL_SECTION(x) #x : AT(ADDR(#x) - __XEN_VIRT_START) +#define DECL_DEBUG(x, a) #x 0 : { *(x) } +#define DECL_DEBUG2(x, y, a) #x 0 : { *(x) *(y) } ENTRY(start_pa) @@ -158,6 +167,10 @@ SECTIONS } PHDR(text) #if defined(CONFIG_PVH_GUEST) && !defined(EFI) + /* + * In principle this should be fine to live in .note (below), but let's keep + * it separate in case anyone decided to find these notes by section name. + */ DECL_SECTION(.note.Xen) { *(.note.Xen) } PHDR(note) PHDR(text) @@ -185,6 +198,13 @@ SECTIONS #endif #endif +#ifndef EFI + /* Retain these just for the purpose of possible analysis tools. */ + DECL_SECTION(.note) { + *(.note.*) + } PHDR(note) PHDR(text) +#endif + _erodata = .; . = ALIGN(SECTION_ALIGN); @@ -272,6 +292,34 @@ SECTIONS __ctors_end = .; } PHDR(text) +#ifndef EFI + /* + * With --orphan-sections=warn (or =error) we need to handle certain linker + * generated sections. These are all expected to be empty; respective + * ASSERT()s can be found towards the end of this file. Put them in the + * text program header, just to be on the safe side against e.g. a linker + * otherwise chosing to put them in a separate one. + */ + DECL_SECTION(.got) { + *(.got) + } PHDR(text) + DECL_SECTION(.got.plt) { + *(.got.plt) + } PHDR(text) + DECL_SECTION(.igot.plt) { + *(.igot.plt) + } PHDR(text) + DECL_SECTION(.iplt) { + *(.iplt) + } PHDR(text) + DECL_SECTION(.plt) { + *(.plt) + } PHDR(text) + DECL_SECTION(.rela) { + *(.rela.*) + } PHDR(text) +#endif + . = ALIGN(SECTION_ALIGN); __init_end = .; __2M_init_end = .; @@ -324,71 +372,6 @@ SECTIONS *(.reloc) __base_relocs_end = .; } - /* - * Explicitly list debug section for the PE output so that they don't end - * up at VA 0 which is below image base and thus invalid. Also use the - * NOLOAD directive, despite currently ignored by ld for PE output, in - * order to record that we'd prefer these sections to not be loaded into - * memory. - * - * Note that we're past _end here, so if these sections get loaded they'll - * be discarded at runtime anyway. - */ - .debug_abbrev ALIGN(1) (NOLOAD) : { - *(.debug_abbrev) - } - .debug_info ALIGN(1) (NOLOAD) : { - *(.debug_info) - *(.gnu.linkonce.wi.*) - } - .debug_types ALIGN(1) (NOLOAD) : { - *(.debug_types) - } - .debug_str ALIGN(1) (NOLOAD) : { - *(.debug_str) - } - .debug_line ALIGN(1) (NOLOAD) : { - *(.debug_line) - *(.debug_line.*) - } - .debug_line_str ALIGN(1) (NOLOAD) : { - *(.debug_line_str) - } - .debug_names ALIGN(4) (NOLOAD) : { - *(.debug_names) - } - .debug_frame ALIGN(4) (NOLOAD) : { - *(.debug_frame) - } - .debug_loc ALIGN(1) (NOLOAD) : { - *(.debug_loc) - } - .debug_loclists ALIGN(4) (NOLOAD) : { - *(.debug_loclists) - } - .debug_ranges ALIGN(8) (NOLOAD) : { - *(.debug_ranges) - } - .debug_rnglists ALIGN(4) (NOLOAD) : { - *(.debug_rnglists) - } - .debug_addr ALIGN(8) (NOLOAD) : { - *(.debug_addr) - } - .debug_aranges ALIGN(1) (NOLOAD) : { - *(.debug_aranges) - } - .debug_pubnames ALIGN(1) (NOLOAD) : { - *(.debug_pubnames) - } - .debug_pubtypes ALIGN(1) (NOLOAD) : { - *(.debug_pubtypes) - } - /* Trick the linker into setting the image size to no less than 16Mb. */ - __image_end__ = .; - .pad ALIGN(__section_alignment__) : { - . = __image_end__ < __image_base__ + MB(16) ? ALIGN(MB(16)) : .; - } #elif defined(XEN_BUILD_EFI) /* * Due to the way EFI support is currently implemented, these two symbols @@ -403,6 +386,42 @@ SECTIONS efi = .; #endif + /* + * Explicitly list debug sections, first of all to avoid these sections being + * viewed as "orphan" by the linker. + * + * For the PE output this is further necessary so that they don't end up at + * VA 0, which is below image base and thus invalid. Note that we're past + * _end here, so if these sections get loaded they'll be discarded at runtime + * anyway. + */ + DECL_DEBUG(.debug_abbrev, 1) + DECL_DEBUG2(.debug_info, .gnu.linkonce.wi.*, 1) + DECL_DEBUG(.debug_types, 1) + DECL_DEBUG(.debug_str, 1) + DECL_DEBUG2(.debug_line, .debug_line.*, 1) + DECL_DEBUG(.debug_line_str, 1) + DECL_DEBUG(.debug_names, 4) + DECL_DEBUG(.debug_frame, 4) + DECL_DEBUG(.debug_loc, 1) + DECL_DEBUG(.debug_loclists, 4) + DECL_DEBUG(.debug_macinfo, 1) + DECL_DEBUG(.debug_macro, 1) + DECL_DEBUG(.debug_ranges, 8) + DECL_DEBUG(.debug_rnglists, 4) + DECL_DEBUG(.debug_addr, 8) + DECL_DEBUG(.debug_aranges, 1) + DECL_DEBUG(.debug_pubnames, 1) + DECL_DEBUG(.debug_pubtypes, 1) + +#ifdef EFI + /* Trick the linker into setting the image size to no less than 16Mb. */ + __image_end__ = .; + .pad ALIGN(__section_alignment__) : { + . = __image_end__ < __image_base__ + MB(16) ? ALIGN(MB(16)) : .; + } +#endif + #ifdef CONFIG_HYPERV_GUEST hv_hcall_page = ABSOLUTE(HV_HCALL_PAGE - XEN_VIRT_START + __XEN_VIRT_START); #endif @@ -423,8 +442,7 @@ SECTIONS #ifdef EFI *(.comment) *(.comment.*) - *(.note.Xen) - *(.note.gnu.*) + *(.note.*) #endif } @@ -437,6 +455,13 @@ SECTIONS .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } + /* + * LLVM ld also wants .symtab, .strtab, and .shstrtab placed. These look to + * be benign to GNU ld, so we can have them here unconditionally. + */ + .symtab 0 : { *(.symtab) } + .strtab 0 : { *(.strtab) } + .shstrtab 0 : { *(.shstrtab) } #endif } @@ -470,6 +495,15 @@ ASSERT(IS_ALIGNED(trampoline_end, 4), "trampoline_end misaligned") ASSERT(IS_ALIGNED(__bss_start, 8), "__bss_start misaligned") ASSERT(IS_ALIGNED(__bss_end, 8), "__bss_end misaligned") +#ifndef EFI +ASSERT(!SIZEOF(.got), ".got non-empty") +ASSERT(!SIZEOF(.got.plt), ".got.plt non-empty") +ASSERT(!SIZEOF(.igot.plt), ".igot.plt non-empty") +ASSERT(!SIZEOF(.iplt), ".iplt non-empty") +ASSERT(!SIZEOF(.plt), ".plt non-empty") +ASSERT(!SIZEOF(.rela), "leftover relocations") +#endif + ASSERT((trampoline_end - trampoline_start) < TRAMPOLINE_SPACE - MBI_SPACE_MIN, "not enough room for trampoline and mbi data") ASSERT((wakeup_stack - wakeup_stack_start) >= WAKEUP_STACK_MIN, -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |