[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 3/8] xen/x86: manually build xen.mb.efi binary
>>> On 19.06.18 at 16:35, <daniel.kiper@xxxxxxxxxx> wrote: > Not done: > - ASM PE header conversion to C; not feasible, Hmm. As long as you can convince Andrew to give you an ack, I won't veto it. But I continue to dislike it, and hence I don't currently foresee myself acking it. > - DOS stub code reduction; experiments showed that DOS stub code size > cannot be changed due to some bugs in applications playing with PE > files, e.g. objdump (more about the issue can be found in the patch > itself); so, I think that if it is not possible to reduce the size > of code then it does make sens change the code itself; hence, it > pays to leave common DOS stub code as is. Even more so here: I'm not sure I care about buggy tools. Did you at least enter a bug report (which you would want to reference in the code comment)? For all of my Win32 life I've been doing fine shrinking DLL/EXE file sizes by moving the PE header to offset 0x40. No tool has even complained. I've just tried objdump 2.25.0 on one of these DLLs - no problem afaics. Did the tool perhaps choke on something other than the non-"standard" offset of the PE header? As to leaving the code as is - if there's anything to be left as is, then the code live binutils would produce, i.e. I'd then ask you to obtain the code at build time, rather than inserting a series of magic hex values in the sources. But as said - even better would be to omit this altogether. > --- a/xen/Makefile > +++ b/xen/Makefile > @@ -61,6 +61,10 @@ _install: $(TARGET)$(CONFIG_XEN_INSTALL_SUFFIX) > ln -f -s $(T)-$(XEN_FULLVERSION)$(Z) > $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION).$(XEN_SUBVERSION)$(Z) > ln -f -s $(T)-$(XEN_FULLVERSION)$(Z) > $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION)$(Z) > ln -f -s $(T)-$(XEN_FULLVERSION)$(Z) $(D)$(BOOT_DIR)/$(T)$(Z) > + $(INSTALL_DATA) $(TARGET).mb.efi > $(D)$(BOOT_DIR)/$(T)-$(XEN_FULLVERSION).mb.efi > + ln -f -s $(T)-$(XEN_FULLVERSION).mb.efi > $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION).$(XEN_SUBVERSION).mb.efi > + ln -f -s $(T)-$(XEN_FULLVERSION).mb.efi > $(D)$(BOOT_DIR)/$(T)-$(XEN_VERSION).mb.efi > + ln -f -s $(T)-$(XEN_FULLVERSION).mb.efi $(D)$(BOOT_DIR)/$(T).mb.efi This suggests something wants to be macro-ized here, I think. > $(D)$(DEBUG_DIR)/$(T)-syms-$(XEN_FULLVERSION).map > @@ -121,7 +125,7 @@ _clean: delete-unfresh-files > $(MAKE) -f $(BASEDIR)/Rules.mk -C test clean > $(MAKE) -f $(BASEDIR)/tools/kconfig/Makefile.kconfig ARCH=$(ARCH) > SRCARCH=$(SRCARCH) clean > find . \( -name "*.o" -o -name ".*.d" -o -name "*.gcno" \) -exec rm -f > {} \; > - rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET).efi > $(TARGET).efi.map $(TARGET)-syms $(TARGET)-syms.map *~ core > + rm -f include/asm $(TARGET) $(TARGET).gz $(TARGET).efi $(TARGET).mb.efi > $(TARGET).efi.map $(TARGET)-syms $(TARGET)-syms.map *~ core Perhaps simply $(TARGET)*.efi? I don't think we're at risk deleting something precious that way. > --- a/xen/arch/x86/Makefile > +++ b/xen/arch/x86/Makefile > @@ -101,6 +101,9 @@ > syms-warn-dup-$(CONFIG_SUPPRESS_DUPLICATE_SYMBOL_WARNINGS) := > $(TARGET): $(TARGET)-syms $(efi-y) boot/mkelf32 > ./boot/mkelf32 $(notes_phdrs) $(TARGET)-syms $(TARGET) > $(XEN_IMG_OFFSET) \ > `$(NM) $(TARGET)-syms | sed -ne 's/^\([^ ]*\) . > __2M_rwdata_end$$/0x\1/p'` > + $(OBJCOPY) -O binary -S --change-section-address \ > + ".efi.pe.header-`$(NM) $(TARGET)-syms | sed -ne 's/^\([^ ]*\) . > __image_base__$$/0x\1/p'`" \ > + $(TARGET)-syms $(TARGET).mb.efi This wants to be a separate rule of a separate $(TARGET).mb.efi target. > +GLOBAL(efi_pe_head) > + /* > + * Legacy EXE header. > + * > + * Most of it is copied from binutils package, version 2.30, > + * include/coff/pe.h:struct external_PEI_filehdr and > + * bfd/peXXigen.c:_bfd_XXi_only_swap_filehdr_out(). > + * > + * Page is equal 512 bytes here. > + * Paragraph is equal 16 bytes here. > + */ > + .short 0x5a4d /* EXE magic number. */ > + .short 0x90 /* Bytes on last page > of file. */ > + .short 0x3 /* Pages in file. */ > + .short 0 /* Relocations. */ > + .short 0x4 /* Size of header in > paragraphs. */ > + .short 0 /* Minimum extra > paragraphs needed. */ > + .short 0xffff /* Maximum extra > paragraphs needed. */ > + .short 0 /* Initial (relative) > SS value. */ > + .short 0xb8 /* Initial SP value. */ > + .short 0 /* Checksum. */ > + .short 0 /* Initial IP value. */ > + .short 0 /* Initial (relative) > CS value. */ > + .short 0x40 /* File address of > relocation table. */ This is just the most prominent example: Why is this a hard coded number, while ... > + .short 0 /* Overlay number. */ > + .fill 4, 2, 0 /* Reserved words. */ > + .short 0 /* OEM identifier. */ > + .short 0 /* OEM information. */ > + .fill 10, 2, 0 /* Reserved words. */ > + .long pe_header - efi_pe_head /* File address of the > PE header. */ ... this isn't? > + /* > + * PE/COFF header. > + * > + * The PE/COFF format is defined by Microsoft, and is available from > + * > http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx > + * > + * Some ideas are taken from Linux kernel and Xen ARM64. > + */ > + > +pe_header: Does this and ones further down really need to be a non-local labels? > + .ascii "PE\0\0" /* PE signature. */ > + .short 0x8664 /* Machine: > IMAGE_FILE_MACHINE_AMD64 */ > + .short 1 /* NumberOfSections. */ > + .long XEN_COMPILE_POSIX_TIME /* TimeDateStamp. */ > + .long 0 /* > PointerToSymbolTable. */ > + .long 0 /* NumberOfSymbols. */ > + .short section_table - optional_header /* > SizeOfOptionalHeader. */ > + .short 0x226 /* Characteristics: > + * > IMAGE_FILE_EXECUTABLE_IMAGE | > + * > IMAGE_FILE_LARGE_ADDRESS_AWARE | > + * > IMAGE_FILE_DEBUG_STRIPPED | > + * > IMAGE_FILE_LINE_NUMS_STRIPPED > + */ > + > +optional_header: > + .short 0x20b /* PE format: PE32+ */ > + .byte 0x02 /* MajorLinkerVersion. > */ > + .byte 0x1e /* MinorLinkerVersion. > */ Let's not cheat more than needed: I'm pretty sure just zeros will do fine here. > + .long __2M_rwdata_end - efi_pe_head_end /* SizeOfCode. */ > + .long 0 /* > SizeOfInitializedData. */ > + .long 0 /* > SizeOfUninitializedData. */ > + .long sym_offs(efi_mb_start) /* AddressOfEntryPoint. > */ > + .long sym_offs(start) /* BaseOfCode. */ > + .quad sym_offs(__image_base__) /* ImageBase. */ The sym_offs() here is certainly different from what xen.efi currently has. With the plan being to have a drop-in replacement, such differences need to be explained to be benign (which here I doubt it is). > + .align XEN_FILE_ALIGN > +GLOBAL(efi_pe_head_end) > + > + .text > + .code32 Why the .code32 here? Perhaps this comes back to the question of whether this whole header should really be lumped into this file. > @@ -582,6 +587,12 @@ static void __init efi_arch_memory_setup(void) > if ( !efi_enabled(EFI_LOADER) ) > return; > > + if ( efi_enabled(EFI_MB_LOADER) ) > + for ( pte = __page_tables_start; pte < __page_tables_end; > + pte += ( pte != (intpte_t *)l2_identmap ) ? 1 : 4 * > L2_PAGETABLE_ENTRIES ) Please avoid explicit casts - &l2e_get_intpte(l2_identmap[0]) or something along those lines ought to work here. Same for 4 * L2_PAGETABLE_ENTRIES - you mean ARRAY_SIZE() there. Also this whole code block needs a comment, to explain what it does and also why l2_identmap needs skipping. Furthermore - isn't this off by one, and you process l2_identmap[0] this way, skipping the rest _plus_ the first following entry? I think you'd better use ++ here and have an if() inside the for() body. Then you can also attach the related part of the comment there instead of to the loop header. And I can avoid complaining about the stray spaces inside the parentheses. > @@ -674,6 +685,15 @@ static bool __init > efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable) > > static void __init efi_arch_flush_dcache_area(const void *vaddr, UINTN size) > { } > > +void EFIAPI efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable); > + > +void EFIAPI __init noreturn > +efi_mb_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) > +{ > + __set_bit(EFI_MB_LOADER, &efi_flags); > + efi_start(ImageHandle, SystemTable); > +} Why yet another entry point? This again speaks against the image being a drop-in replacement for xen.efi. > --- a/xen/arch/x86/xen.lds.S > +++ b/xen/arch/x86/xen.lds.S > @@ -60,7 +60,20 @@ SECTIONS > > start_pa = ABSOLUTE(start - __XEN_VIRT_START); > > +#ifdef EFI > . = __XEN_VIRT_START + XEN_IMG_OFFSET; > +#else > + /* > + * The PE header must be followed by .text section which > + * starts at __XEN_VIRT_START + XEN_IMG_OFFSET address. > + */ > + . = __XEN_VIRT_START + XEN_IMG_OFFSET - efi_pe_head_end + efi_pe_head; > + > + DECL_SECTION(.efi.pe.header) { > + *(.efi.pe.header) > + } :NONE > +#endif The #ifdef wants a brief comment attached I think, since it's quite odd to see the #else side deal with EFI as well. > @@ -271,6 +284,9 @@ SECTIONS > *(.data.rel) > *(.data.rel.*) > CONSTRUCTORS > + /* PE file must end at XEN_FILE_ALIGN boundary. */ > + . = ALIGN(XEN_FILE_ALIGN); > + __pe_text_raw_end = .; Is this really a requirement on the file, or just on the label? > @@ -292,6 +308,8 @@ SECTIONS > . = ALIGN(SECTION_ALIGN); > __2M_rwdata_end = .; > > + __pe_SizeOfImage = ALIGN(. - __image_base__, MB(16)); > + > #ifdef EFI > . = ALIGN(4); > .reloc : { Considering the respective code and comment inside the #ifdef, does your addition really belong ahead of it? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |