I can't seem to make progress; my program won't run and the error message is nonseniscal. A hexdump shows a bad PE binary for no apparent reason:
I started from this tutorial
My Makefile:
ARCH=x86_64
OBJS=hello.o
TARGET=hello.efi
EFIINC=/usr/include/efi
EFIINCS=-I$(EFIINC) -I$(EIFFINC)/$(ARCH) -I$(EFIINC)/protocol
LIB=/usr/lib64
EFILIB=/usr/lib
EFI_CRT_OJBS=$(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS=$(EFILIB)/elf_$(ARCH)_efi.lds
CFLAGS=$(EFIINCS) -fno-stack-protector -fpic -fshort-wchar -mno-red-zone -Wall -DEFI_FUNCION_WRAPPER
LDFLAGS =-nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)
all: $(TARGET)
hello.so: $(OBJS)
ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi
%.efi: %.so
objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j rel -j rela -j reloc --target=efi-app-$(ARCH) $^ $@
My hello.c:
#include <efi.h>
#include <efilib.h>
EFI_STATUS EFIAPI efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
InitializeLib(ImageHandle, SystemTable);
Print(L"Hello, World\n");
return EFI_SUCCESS;
}
I build, copy hello.efi onto disk image, and start qemu with:
qemu-system-x86_64 -enable-kvm -bios /usr/share/qemu/OVMF.fd -nodefaults -display gtk -vga std -hda target
But on trying to run it:
FS0:\> dir
Directory of: FS0:\
12/31/2023 48,181 exit.efi
12/31/2023 41,494 hello.efi
FS0:\> hello.efi
Command Error Status: Unsupported
exit.efi is a stock demo application from efi library; it launches. I'm not sure if it's supposed to hang up qemu or not, but it does something. My application is hello.efi. It does not start.
Running objdump to make sure the file format is right:
$ objdump -f -h hello.efi
hello.efi: file format pei-x86-64
architecture: i386:x86-64, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x0000000000000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00005bf0 0000000000003000 0000000000003000 00000138 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00001d00 0000000000009000 0000000000009000 00005d38 2**5
CONTENTS, ALLOC, LOAD, DATA
2 .dynamic 00000110 000000000000b000 000000000000b000 00007b38 2**3
CONTENTS, ALLOC, LOAD, DATA
3 .dynsym 000000d8 000000000000d000 000000000000d000 00007d38 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
Build and host environment is debian 12.4 x86_64.
Something is very wrong with the compilation process. A hexdump of the top of the binary gives:
$ hexdump -C hello.efi | head -n 16
00000000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 |MZ..........ÿÿ..|
00000010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |¸.......@.......|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 |................|
00000040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 |..º..´.Í!¸.LÍ!Th|
00000050 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f |is program canno|
00000060 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 |t be run in DOS |
00000070 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 |mode....$.......|
00000080 50 45 00 00 64 86 04 00 00 00 00 00 38 7f 00 00 |PE..d.......8...|
00000090 12 01 00 00 00 00 05 02 2e 74 65 78 74 00 00 00 |.........text...|
000000a0 f0 5b 00 00 00 30 00 00 00 5c 00 00 38 01 00 00 |ð[...0...\..8...|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 20 00 50 60 |............ .P`|
000000c0 2e 64 61 74 61 00 00 00 00 1d 00 00 00 90 00 00 |.data...........|
000000d0 00 1e 00 00 38 5d 00 00 00 00 00 00 00 00 00 00 |....8]..........|
000000e0 00 00 00 00 40 00 60 c0 2e 64 79 6e 61 6d 69 63 |....@.`À.dynamic|
000000f0 10 01 00 00 00 b0 00 00 00 02 00 00 38 7b 00 00 |.....°......8{..|
The section headers start too close to the PE signature. That binary will be unloadable.
You have some typos in your Makefile:
EFIINCS=-I$(EFIINC) -I$(EIFFINC)/$(ARCH) -I$(EFIINC)/protocol
EFI_CRT_OJBS=$(EFILIB)/crt0-efi-$(ARCH).o
objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j rel -j rela -j reloc --target=efi-app-$(ARCH) $^ $@
I got your code running with this Makefile: