0

i will try to keep this as short as possible.

I created an UEFI application which uses just a simple malloc but it never returns from the call:

main.c:

#include <efi.h>
#include <efilib.h>
#include <stdlib.h>

EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) 
{
    InitializeLib(ImageHandle, SystemTable);

    Print(L"trying to allocate memory\n");
    malloc(16);
    Print(L"allocated successfully\n");

    return EFI_SUCCESS;
}

output:

trying to allocate memory

The system is a QEMU virtual machine under linux-ubuntu:

"qemu-system-x86_64 -cpu qemu64 -bios Bios/bios.bin -drive file=Bios/app.disk,format=raw -global isa-debugcon.iobase=0x402 -debugcon file:app.ovmf.log"

bios.bin is the UEFI firmware https://wiki.ubuntu.com/UEFI/OVMF.

main.efi is written to app.disk with

dd if=/dev/zero of=Bios/app.disk bs=1 count=1 seek=$(( (128 * 1024) - 1))
sudo mkfs.vfat Bios/app.disk
mkdir Bios/mnt_app
cp Bios/app.disk Bios/mnt_app
sudo mount Bios/app.disk Bios/mnt_app
sudo cp kernel/main.efi Bios/mnt_app

build process of main.c is almost complete copy paste from https://www.rodsbooks.com/efi-programming/hello.html:

ARCH            = $(shell uname -m | sed s,i[3456789]86,ia32,)

OBJS            = main.o
TARGET          = main.efi

EFIINC          = /usr/include/efi
EFIINCS         = -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
EFILIB          = /usr/lib
EFI_CRT_OBJS    = $(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS         = $(EFILIB)/elf_$(ARCH)_efi.lds

CFLAGS          = $(EFIINCS) -fno-stack-protector -fpic \
          -fshort-wchar -mno-red-zone -Wall 

ifeq ($(ARCH),x86_64)
  CFLAGS += -DEFI_FUNCTION_WRAPPER
endif

LDFLAGS         = -nostdlib -znocombreloc -T $(EFI_LDS) -shared \
          -Bsymbolic -L $(EFILIB) $(EFI_CRT_OBJS) 

all: $(TARGET)

main.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) $^ $@

    @echo   done building target
Oachkatzl
  • 307
  • 1
  • 11
  • 2
    Please pay attention to the very first bullet of the hello page you've linked. The bottom line, C library is not available to efi. – user58697 Jul 28 '18 at 20:10
  • well, some are and some are not, it just happens to be that this one is not. – Oachkatzl Jul 30 '18 at 16:17
  • 1
    No, the standard C library is not available, period. The "specialness" of gnu-efi, or even normal toolchains, means that you may accidentally get libraries meant to run in an operating system context pulled in. If you're really lucky, they may even not crash. That does not mean they should be used because they appear to work. – unixsmurf Aug 02 '18 at 08:17

1 Answers1

4

for reasons i don't know, malloc is just not working and is probably not intended to be used - at least it seems like that. if you need dynamic memory allocation, create your own malloc with memory pools:

void * malloc(UINTN poolSize)
{
    EFI_STATUS status;
    void * handle;
    Print(L"allocating memory pool\n");
    status = uefi_call_wrapper(BS->AllocatePool, 3, EfiLoaderData, poolSize, &handle);

    if(status == EFI_OUT_OF_RESOURCES)
    {
        Print(L"out of resources for pool\n");
        return 0;
    }
    else if(status == EFI_INVALID_PARAMETER)
    {
        Print(L"invalid pool type\n");
        return 0;
    }
    else
    {
        Print(L"memory pool successfully allocated\n");
        return handle;
    }
}

free equivalent:

void free(void * pool)
{
    EFI_STATUS status;
    Print(L"freeing memory pool\n");
    status = uefi_call_wrapper(BS->FreePool, 1, pool);

    if(status == EFI_INVALID_PARAMETER)
    {
        Print(L"invalid pool pointer\n");
    }
    else
    {
        Print(L"memory pool successfully freed\n");
    }
}

use it like you would usually use malloc and free:

EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) 
{
    InitializeLib(ImageHandle, SystemTable);

    void * memoryPointer = malloc(1024);
    free(memoryPointer);

    return EFI_SUCCESS;
}

output:

allocating memory pool
memory pool successfully allocated
freeing memory pool
memory pool successfully freed
Oachkatzl
  • 307
  • 1
  • 11