<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 26 Apr 2024 at 16:48, Julian Andres Klode <<a href="mailto:julian.klode@canonical.com">julian.klode@canonical.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Thu, Apr 25, 2024 at 09:10:08PM +0100, Alex Bennée wrote:<br>
> Alex Bennée <<a href="mailto:alex.bennee@linaro.org" target="_blank">alex.bennee@linaro.org</a>> writes:<br>
> <br>
> > Julian Andres Klode <<a href="mailto:julian.klode@canonical.com" target="_blank">julian.klode@canonical.com</a>> writes:<br>
> ><br>
> >> On Thu, Apr 25, 2024 at 06:30:52PM +0100, Alex Bennée wrote:<br>
> >>> <br>
> >>> Continuing to debug on QEMU it seems there is an incompatibility with<br>
> >>> the images and the peloader (which overrides the normal efi loader):<br>
> >>> <br>
> <snip><br>
> ><br>
> >> In the error case you can see though, that one of the section<br>
> >> addresses in the Xen binary to be relocated points into the (PE)<br>
> >> header of the binary, which obviously seems wrong.<br>
> >><br>
> >> So go check your PE sections and check which one is wrong?<br>
> ><br>
> > Is there any tooling for examining PE sections?<br>
> <br>
> Nothing really jumps out from objdump:<br>
> <br>
> 1:08:50 [root@debian-arm64:~] # objdump -h /boot/xen<br>
> <br>
> /boot/xen: file format pei-aarch64-little<br>
> <br>
> Sections:<br>
> Idx Name Size VMA LMA File off Algn<br>
> 0 .reloc 00000000 0000000000000000 0000000000000000 00000000 2**0<br>
> ALLOC, LOAD, READONLY, DATA<br>
<br>
<br>
This looks suspicious. Yes it's 0 size but it's address is 0 which<br>
clearly points into the header, and we don't skip 0 size sections when<br>
loading the PE binary for later relocation, and we don't use any .reloc<br>
section.<br></blockquote><div><br></div><div>It does get skipped in the reloc code:</div><div><br></div><div> if (!info->reloc || !(info->reloc->size))<br> {<br> grub_dprintf ("linux", "no relocations\n");<br> return GRUB_EFI_SUCCESS;<br> }<br></div><div><br></div><div>Although the x86_64 build of Xen uses reloc sections (which Xen itself deals with) we don't actually need them for Arm. However the way the PE binary is built is a little funky:</div><div><br></div><div>make <br> UPD include/xen/compile.h <br> Xen 4.19-unstable <br>make[1]: Nothing to be done for 'include'. <br>make[1]: 'arch/arm/include/asm/asm-offsets.h' is up to date. <br> CC common/version.o <br> LD common/built_in.o <br> CC arch/arm/acpi/domain_build.o <br> INIT_O arch/arm/acpi/domain_build.init.o <br> LD arch/arm/acpi/built_in.o <br> CC arch/arm/domain_build.o <br> INIT_O arch/arm/domain_build.init.o <br> CC arch/arm/efi/boot.o <br> INIT_O arch/arm/efi/boot.init.o <br> LD arch/arm/efi/built_in.o <br> CC arch/arm/setup.o <br> LD arch/arm/built_in.o <br> LD prelink.o <br>ld -EL --no-warn-rwx-segments --fix-cortex-a53-843419 -T arch/arm/xen.lds -N prelink.o \ <br> ./common/symbols-dummy.o -o ./.xen-syms.0 <br>nm -pa --format=sysv ./.xen-syms.0 \ <br> | ./tools/symbols --sysv --sort \ <br> > ./.xen-syms.0.S <br>make -f ./Rules.mk obj=. ./.xen-syms.0.o <br> CC .xen-syms.0.o <br>ld -EL --no-warn-rwx-segments --fix-cortex-a53-843419 -T arch/arm/xen.lds -N prelink.o \<br> ./.xen-syms.0.o -o ./.xen-syms.1 <br>nm -pa --format=sysv ./.xen-syms.1 \ <br> | ./tools/symbols --sysv --sort \ <br> > ./.xen-syms.1.S <br>make -f ./Rules.mk obj=. ./.xen-syms.1.o <br> CC .xen-syms.1.o <br>ld -EL --no-warn-rwx-segments --fix-cortex-a53-843419 -T arch/arm/xen.lds -N prelink.o --build-id=sha1 \<br> ./.xen-syms.1.o -o xen-syms <br>nm -pa --format=sysv xen-syms \ <br> | ./tools/symbols --all-symbols --xensyms --sysv --sort \ <br> > xen-syms.map <br>rm -f ./.xen-syms.[0-9]* <br>objcopy -O binary -S xen-syms xen <br>ln -sf xen xen.efi </div><div> </div><div>I can't work out how to build without the reloc section and trying to remove the .reloc section after the fact results in something where the file-offset is ahead of the VMA position:</div><div><br></div><div>➜ objcopy --remove-section=.reloc -O binary -S xen-syms xen-test <br>🕙17:03:23 alex@gwenyn:xen.git/xen on testing/new-attempt:new-attempt [!?] <br>➜ objdump -h xen-test <br> <br>xen-test: file format pei-aarch64-little <br> <br>Sections: <br>Idx Name Size VMA LMA File off Algn <br> 0 .reloc 00000000 0000000000000000 0000000000000000 00000000 2**0 <br> ALLOC, LOAD, READONLY, DATA <br> 1 .text 00127ea8 0000000000000160 0000000000000160 00000160 2**4 <br> CONTENTS, ALLOC, LOAD, CODE <br>🕙17:03:25 alex@gwenyn:xen.git/xen on testing/new-attempt:new-attempt [!?] <br>➜ objcopy --remove-section=.reloc xen-test <br>🕙17:03:37 alex@gwenyn:xen.git/xen on testing/new-attempt:new-attempt [!?] <br>➜ objdump -h xen-test <br> <br>xen-test: file format pei-aarch64-little <br> <br>Sections: <br>Idx Name Size VMA LMA File off Algn <br> 0 .text 00127ea8 0000000000000160 0000000000000160 000001b0 2**2 <br> CONTENTS, ALLOC, LOAD, CODE </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
> 1 .text 00107ea8 0000000000000160 0000000000000160 00000160 2**4<br>
> CONTENTS, ALLOC, LOAD, CODE<br>
> 21:08:53 [root@debian-arm64:~] # objdump -h /boot/vmlinuz<br>
<br>
<br>
I suppose the header is smaller than 0x160 bytes and this is ok.<br>
<br>
My colleague Heinrich has written a nice PE analyser tool too:<br>
<br>
<a href="https://github.com/xypron/efi_analyzer" rel="noreferrer" target="_blank">https://github.com/xypron/efi_analyzer</a></blockquote><div><br></div><div>That seems pretty happy with the binary:</div><div><br></div><div>/home/alex/lsrc/xen.git/xen/xen.efi<br>Offset to PE: 0x40<br>Machine type: 0xaa64, ARM64 little endian<br>NumberOfSymbols should be 0.<br>Characteristics: 0x0206<br> * The file is executable.<br> * COFF line numbers were stripped from the file.<br> * Debugging information was removed.<br>LinkerVersion 2.20<br>BaseOfCode: 0x160<br>AddressOfEntryPoint: 0xe8c20<br>Image type: PE32+<br>Subsystem: EFI application<br>DLL Characteristics: 0x0000<br>ImageBase: 0x0<br>SectionAlignment: 0x1000<br>FileAlignment: 0x8<br>SizeOfImage: 0x175000<br>.reloc.address: 0x0<br>.reloc.size: 0x0<br>Number data tables: 6<br> Exports : 0x00000000 - 0x00000000<br> Imports : 0x00000000 - 0x00000000<br> Resources : 0x00000000 - 0x00000000<br> Exceptions : 0x00000000 - 0x00000000<br> Certificates : 0x00000000 - 0x00000000<br> Base Relocations : 0x00000000 - 0x00000000<br>Number of sections: 2<br>Section[0]: .reloc<br> Virtual size: 0x0<br> Virtual address: 0x0<br> Size of raw data: 0x0<br> Pointer to raw data: 0x0<br> End of raw data: 0x0<br> Characteristics: 0x42000040<br> * The section contains initialized data.<br> * The section can be discarded as needed.<br> * The section can be read.<br> * Align data on a 1 byte boundary.<br>Section[1]: .text<br> Virtual size: 0x174ea0<br> Virtual address: 0x160<br> Size of raw data: 0x127ea8<br> Pointer to raw data: 0x160<br> End of raw data: 0x128008<br> Characteristics: 0xe0000020<br> * The section contains executable code.<br> * The section can be executed as code.<br> * The section can be read.<br> * The section can be written to.<br> * Align data on a 16 byte boundary.</div><div><br></div><div>I'm going to continue to see if I can improve the way Xen builds its EFI blob but I think the validation code should just skip zero length sections.<br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
<br>
-- <br>
debian developer - <a href="http://deb.li/jak" rel="noreferrer" target="_blank">deb.li/jak</a> | <a href="http://jak-linux.org" rel="noreferrer" target="_blank">jak-linux.org</a> - free software dev<br>
ubuntu core developer i speak de, en<br>
</blockquote></div><br clear="all"><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">Alex Bennée<br>Emulation and Virtualisation Tech Lead @ Linaro</div></div></div>