[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 6/8] x86/EFI: avoid use of GNU ld's --disable-reloc-section when possible
On Thu, Apr 01, 2021 at 11:46:44AM +0200, Jan Beulich wrote: > As of commit 6fa7408d72b3 ("ld: don't generate base relocations in PE > output for absolute symbols") I'm feeling sufficiently confident in GNU > ld to use its logic for generating base relocations, which was enabled > for executables at some point last year (prior to that this would have > got done only for DLLs). > > GNU ld, seeing the original relocations coming from the ELF object files, > generates different relocation types for our page tables (64-bit ones, > while mkreloc produces 32-bit ones). This requires also permitting and > handling that type in efi_arch_relocate_image(). > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > > --- a/xen/arch/x86/Makefile > +++ b/xen/arch/x86/Makefile > @@ -120,18 +120,37 @@ $(TARGET): $(TARGET)-syms $(efi-y) boot/ > mv $(TMP) $(TARGET) > > ifneq ($(efi-y),) > + > # Check if the compiler supports the MS ABI. > export XEN_BUILD_EFI := $(shell $(CC) $(XEN_CFLAGS) -c efi/check.c -o > efi/check.o 2>/dev/null && echo y) > +CFLAGS-$(XEN_BUILD_EFI) += -DXEN_BUILD_EFI > + > # Check if the linker supports PE. > EFI_LDFLAGS = $(patsubst -m%,-mi386pep,$(XEN_LDFLAGS)) --subsystem=10 > --strip-debug > XEN_BUILD_PE := $(if $(XEN_BUILD_EFI),$(shell $(LD) $(EFI_LDFLAGS) -o > efi/check.efi efi/check.o 2>/dev/null && echo y)) > -CFLAGS-$(XEN_BUILD_EFI) += -DXEN_BUILD_EFI > -# Check if the linker produces fixups in PE by default (we need to disable > it doing so for now). > -XEN_NO_PE_FIXUPS := $(if $(XEN_BUILD_EFI), \ > - $(shell $(LD) $(EFI_LDFLAGS) > --disable-reloc-section -o efi/check.efi efi/check.o 2>/dev/null && \ > - echo --disable-reloc-section)) > + > +ifeq ($(XEN_BUILD_PE),y) > + > +# Check if the linker produces fixups in PE by default > +nr-fixups := $(shell $(OBJDUMP) -p efi/check.efi | grep > '^[[:blank:]]*reloc[[:blank:]]*[0-9][[:blank:]].*DIR64$$' | wc -l) > +ifeq ($(nr-fixups),2) > +MKRELOC := : > +relocs-dummy := > +else > +MKRELOC := efi/mkreloc > +relocs-dummy := efi/relocs-dummy.o > +# If the linker produced fixups but not precisely two of them, we need to > +# disable it doing so. But if it didn't produce any fixups, it also wouldn't > +# recognize the option. > +ifneq ($(nr-fixups),0) > +EFI_LDFLAGS += --disable-reloc-section > +endif > endif > > +endif # $(XEN_BUILD_PE) > + > +endif # $(efi-y) > + > ALL_OBJS := $(BASEDIR)/arch/x86/boot/built_in.o > $(BASEDIR)/arch/x86/efi/built_in.o $(ALL_OBJS) > > ifeq ($(CONFIG_LTO),y) > @@ -175,7 +194,7 @@ note.o: $(TARGET)-syms > --rename-section=.data=.note.gnu.build-id -S $@.bin $@ > rm -f $@.bin > > -EFI_LDFLAGS += --image-base=$(1) --stack=0,0 --heap=0,0 $(XEN_NO_PE_FIXUPS) > +EFI_LDFLAGS += --image-base=$(1) --stack=0,0 --heap=0,0 > EFI_LDFLAGS += --section-alignment=0x200000 --file-alignment=0x20 > EFI_LDFLAGS += --major-image-version=$(XEN_VERSION) > EFI_LDFLAGS += --minor-image-version=$(XEN_SUBVERSION) > @@ -189,7 +208,11 @@ EFI_LDFLAGS += --no-insert-timestamp > endif > > $(TARGET).efi: VIRT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A > VIRT_START$$,,p') > +ifeq ($(MKRELOC),:) > +$(TARGET).efi: ALT_BASE := > +else > $(TARGET).efi: ALT_BASE = 0x$(shell $(NM) efi/relocs-dummy.o | sed -n 's, A > ALT_START$$,,p') Could you maybe check whether $(relocs-dummy) is set as the condition here and use it here instead of efi/relocs-dummy.o? > +endif > > ifneq ($(build_id_linker),) > ifeq ($(call ld-ver-build-id,$(LD) $(filter -m%,$(EFI_LDFLAGS))),y) > @@ -210,16 +233,16 @@ note_file_option ?= $(note_file) > ifeq ($(XEN_BUILD_PE),y) > $(TARGET).efi: prelink.o $(note_file) efi.lds efi/relocs-dummy.o efi/mkreloc Do you need to also replace the target prerequisite to use $(relocs-dummy)? > $(foreach base, $(VIRT_BASE) $(ALT_BASE), \ > - $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< > efi/relocs-dummy.o \ > + $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< > $(relocs-dummy) \ > $(BASEDIR)/common/symbols-dummy.o $(note_file_option) > -o $(@D)/.$(@F).$(base).0 &&) : > - efi/mkreloc $(foreach base,$(VIRT_BASE) > $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S > + $(MKRELOC) $(foreach base,$(VIRT_BASE) > $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S > $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).0 \ > | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort > >$(@D)/.$(@F).0s.S > $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o > $(foreach base, $(VIRT_BASE) $(ALT_BASE), \ > $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \ > $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o $(note_file_option) > -o $(@D)/.$(@F).$(base).1 &&) : > - efi/mkreloc $(foreach base,$(VIRT_BASE) > $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S > + $(MKRELOC) $(foreach base,$(VIRT_BASE) > $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S > $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).1 \ > | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort > >$(@D)/.$(@F).1s.S > $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o > --- a/xen/arch/x86/efi/check.c > +++ b/xen/arch/x86/efi/check.c > @@ -2,3 +2,17 @@ int __attribute__((__ms_abi__)) test(int > { > return i; > } > + > +/* > + * Populate an array with "addresses" of relocatable and absolute values. > + * This is to probe ld for (a) emitting base relocations at all and (b) not > + * emitting base relocations for absolute symbols. > + */ > +extern const unsigned char __image_base__[], __file_alignment__[], > + __section_alignment__[]; > +const void *const data[] = { > + __image_base__, > + __file_alignment__, > + __section_alignment__, > + data, > +}; > --- a/xen/arch/x86/efi/efi-boot.h > +++ b/xen/arch/x86/efi/efi-boot.h > @@ -86,10 +86,12 @@ static void __init efi_arch_relocate_ima > } > break; > case PE_BASE_RELOC_DIR64: > - if ( in_page_tables(addr) ) > - blexit(L"Unexpected relocation type"); > if ( delta ) > + { > *(u64 *)addr += delta; > + if ( in_page_tables(addr) ) > + *(u64 *)addr += xen_phys_start; Doesn't the in_page_tables check and modification also apply when delta == 0? Maybe you could just break on !delta to reduce indentation if none of this applies then? Thanks, Roger.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |