Find PE image (No PDB) error

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Find PE image (No PDB) error

Post by chris13524 »

I'm just getting started with UEFI, I followed the little "tutorial" on with wiki: http://wiki.osdev.org/UEFI

Code: Select all

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

extern "C" EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle,
		EFI_SYSTEM_TABLE *SystemTable) {

	InitializeLib(ImageHandle, SystemTable);

	Print((CHAR16*) "Hello world!");

	while (true) {
	}

	return EFI_SUCCESS;
}
To make this work for C++, I added the extern "C" thing to efi_main (and updated the extension). However, when I compiled it, I got this error:

Code: Select all

src/boot/uefi.cpp: In function ‘EFI_STATUS efi_main(EFI_HANDLE, EFI_SYSTEM_TABLE*)’:
src/boot/uefi.cpp:16:23: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
  Print(L"Hello world!");
                       ^
In file included from src/boot/uefi.cpp:9:0:
gnu-efi/headers/efilib.h:404:1: note:   initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’
 Print (
 ^
I made a blind attempt at fixing this and removed the "L" and casted my string to CHAR16*. This seemed to compile fine, but when I ran it, I got a crash:

Code: Select all

!!!! X64 Exception Type - 0000000000000006     CPU Apic ID - 00000000 !!!!
RIP  - 0000000006764030, CS  - 0000000000000028, RFLAGS - 0000000000000292
RAX  - 0000000006772E98, RCX - 0000000000000000, RDX - 0000000007F21F18
RBX  - 0000000007F21F18, RSP - 0000000007F94B40, RBP - 0000000007F94B60
RSI  - 0000000007F21F1C, RDI - 0000000006772E9A
R8   - 0000000000000000, R9  - 0000000007D4DF18, R10 - 0000000006EF3F60
R11  - 0000000006EFCE30, R12 - 0000000000000000, R13 - 0000000000000000
R14  - 0000000000000000, R15 - 0000000000000000
DS   - 0000000000000008, ES  - 0000000000000008, FS  - 0000000000000008
GS   - 0000000000000008, SS  - 0000000000000008
CR0  - 0000000080000033, CR2 - 0000000000000000, CR3 - 0000000007F33000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 0000000007F1CE98 000000000000003F, LDTR - 0000000000000000
IDTR - 0000000007C07018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007F947A0
!!!! Find PE image (No PDB)  (ImageBase=000000000675F000, EntryPoint=0000000006761038) !!!!
If I remove InitializeLib and Print (leaving the while(true){} loop), it hangs (as expected).

I try to distance myself from Microsoft, so I'm not familiar with the calling conventions. I'm assuming that's what the problem is.

To make sure it's not a problem with building, I directly copied the tutorial. It seems to work fine (printing "Hello, World!"), but as soon as I try to switch to C++, I get these errors.

Thanks!
My operating system:
https://github.com/neonorb/aura
heat
Member
Member
Posts: 103
Joined: Sat Mar 28, 2015 11:23 am
Libera.chat IRC: heat

Re: Find PE image (No PDB) error

Post by heat »

Compiler? Target? Command line options? Also I'm not sure that UEFI's API is compatible with C++.
If some of you people keep insisting on having backwards compatibitity with the stone age, we'll have stone tools forever.
My Hobby OS: https://github.com/heatd/Onyx
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Find PE image (No PDB) error

Post by chris13524 »

I'm not sure that UEFI's API is compatible with C++.
This guy appears to be using C++: http://forum.osdev.org/viewtopic.php?f=1&t=29720 https://github.com/kiznit/rainbow-os/bl ... fiboot.cpp

Here's my build script:

Code: Select all

build/boot/uefi.o: src/boot/uefi.cpp | build/boot/.dirstamp
	gcc src/boot/uefi.cpp           \
		-c                        \
		-fno-stack-protector      \
		-fpic                     \
		-fshort-wchar             \
		-mno-red-zone             \
		-I gnu-efi/headers        \
		-I gnu-efi/headers/x86_64 \
		-DEFI_FUNCTION_WRAPPER    \
		-o build/boot/uefi.o

build/uefi.so: build/boot/uefi.o | build/.dirstamp
	ld build/boot/uefi.o              \
		gnu-efi/crt0-efi-x86_64.o     \
		-nostdlib                     \
		-znocombreloc                 \
		-T gnu-efi/elf_x86_64_efi.lds \
		-shared                       \
		-Bsymbolic                    \
		-L gnu-efi/libs               \
		-l:libgnuefi.a                \
		-l:libefi.a                   \
		-o build/uefi.so

build/aura.efi: build/uefi.so | build/.dirstamp
	objcopy -j .text            \
		-j .sdata               \
		-j .data                \
		-j .dynamic             \
		-j .dynsym              \
		-j .rel                 \
		-j .rela                \
		-j .reloc               \
		--target=efi-app-x86_64 \
		build/uefi.so           \
		build/aura.efi
		
# ---- output files ----

.PHONY:
img: build/aura.img
build/aura.img: build/aura.efi | build/.dirstamp
	dd if=/dev/zero of=build/aura.img bs=512 count=93750 # allocate disk
	parted build/aura.img -s -a minimal mklabel gpt # make gpt table
	parted build/aura.img -s -a minimal mkpart EFI FAT16 2048s 93716s # make EFI partition
	parted build/aura.img -s -a minimal toggle 1 boot # make it bootable
	dd if=/dev/zero of=/tmp/part.img bs=512 count=91669 # allocate partition
	mformat -i /tmp/part.img -h 32 -t 32 -n 64 -c 1 # format partition
	
	if [ -d "build/img_root" ]; then rm -r build/img_root; fi
	
	# build FS structure
	mkdir build/img_root
	mkdir build/img_root/EFI
	mkdir build/img_root/EFI/BOOT
	cp build/aura.efi build/img_root/EFI/BOOT/BOOTX64.efi # hard coded file name and path
	
	mcopy -s -i /tmp/part.img build/img_root/* :: # copy FS to partition
	dd if=/tmp/part.img of=build/aura.img bs=512 count=91669 seek=2048 conv=notrunc # copy parition to disk
	rm /tmp/part.img # remove tmp partition file
My operating system:
https://github.com/neonorb/aura
heat
Member
Member
Posts: 103
Joined: Sat Mar 28, 2015 11:23 am
Libera.chat IRC: heat

Re: Find PE image (No PDB) error

Post by heat »

chris13524 wrote:
I'm not sure that UEFI's API is compatible with C++.
This guy appears to be using C++: http://forum.osdev.org/viewtopic.php?f=1&t=29720 https://github.com/kiznit/rainbow-os/bl ... fiboot.cpp

Here's my build script:

Code: Select all

build/boot/uefi.o: src/boot/uefi.cpp | build/boot/.dirstamp
	gcc src/boot/uefi.cpp           \
		-c                        \
		-fno-stack-protector      \
		-fpic                     \
		-fshort-wchar             \
		-mno-red-zone             \
		-I gnu-efi/headers        \
		-I gnu-efi/headers/x86_64 \
		-DEFI_FUNCTION_WRAPPER    \
		-o build/boot/uefi.o

build/uefi.so: build/boot/uefi.o | build/.dirstamp
	ld build/boot/uefi.o              \
		gnu-efi/crt0-efi-x86_64.o     \
		-nostdlib                     \
		-znocombreloc                 \
		-T gnu-efi/elf_x86_64_efi.lds \
		-shared                       \
		-Bsymbolic                    \
		-L gnu-efi/libs               \
		-l:libgnuefi.a                \
		-l:libefi.a                   \
		-o build/uefi.so

build/aura.efi: build/uefi.so | build/.dirstamp
	objcopy -j .text            \
		-j .sdata               \
		-j .data                \
		-j .dynamic             \
		-j .dynsym              \
		-j .rel                 \
		-j .rela                \
		-j .reloc               \
		--target=efi-app-x86_64 \
		build/uefi.so           \
		build/aura.efi
		
# ---- output files ----

.PHONY:
img: build/aura.img
build/aura.img: build/aura.efi | build/.dirstamp
	dd if=/dev/zero of=build/aura.img bs=512 count=93750 # allocate disk
	parted build/aura.img -s -a minimal mklabel gpt # make gpt table
	parted build/aura.img -s -a minimal mkpart EFI FAT16 2048s 93716s # make EFI partition
	parted build/aura.img -s -a minimal toggle 1 boot # make it bootable
	dd if=/dev/zero of=/tmp/part.img bs=512 count=91669 # allocate partition
	mformat -i /tmp/part.img -h 32 -t 32 -n 64 -c 1 # format partition
	
	if [ -d "build/img_root" ]; then rm -r build/img_root; fi
	
	# build FS structure
	mkdir build/img_root
	mkdir build/img_root/EFI
	mkdir build/img_root/EFI/BOOT
	cp build/aura.efi build/img_root/EFI/BOOT/BOOTX64.efi # hard coded file name and path
	
	mcopy -s -i /tmp/part.img build/img_root/* :: # copy FS to partition
	dd if=/tmp/part.img of=build/aura.img bs=512 count=91669 seek=2048 conv=notrunc # copy parition to disk
	rm /tmp/part.img # remove tmp partition file
I might be confused, but didn't gnuefi handle elf relocation? Try not running the objcopy and see how it goes.
If some of you people keep insisting on having backwards compatibitity with the stone age, we'll have stone tools forever.
My Hobby OS: https://github.com/heatd/Onyx
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Find PE image (No PDB) error

Post by chris13524 »

I might be confused, but didn't gnuefi handle elf relocation? Try not running the objcopy and see how it goes.
I think you need the objcopy. I removed that and executed the output of ld. I even revered back to C and tried it. It said it couldn't boot, like it didn't exist:

Code: Select all

Boot Failed. EFI DVD/CDROM
Boot Failed. EFI Floppy
Boot Failed. EFI Floppy 1
Boot Failed. EFI Hard Drive
My operating system:
https://github.com/neonorb/aura
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Find PE image (No PDB) error

Post by Octocontrabass »

You're including C headers as if they were C++ headers.

Maybe try doing this instead:

Code: Select all

extern "C" {
#include <efi.h>
#include <efilib.h>
}
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Find PE image (No PDB) error

Post by chris13524 »

Octocontrabass wrote:You're including C headers as if they were C++ headers.

Maybe try doing this instead:

Code: Select all

extern "C" {
#include <efi.h>
#include <efilib.h>
}
Ah, this fixed most of my problems. I had to re-enable objcopy as well.

Now it's printing "Hlowrd". I'm assuming that is because I'm casting to CHAR16* when it should be CHAR8* ? I'm guessing that's what the "L" did, make it a 16 bit literal? But again, my compiler is not understanding that "L".
My operating system:
https://github.com/neonorb/aura
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Find PE image (No PDB) error

Post by chris13524 »

Note: I'm not using the standard library.
My operating system:
https://github.com/neonorb/aura
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Find PE image (No PDB) error

Post by Octocontrabass »

That's probably something to do with const-correctness. If gnu-efi is wrong and Print() should be able to take a pointer to const as input, a const_cast will silence the warning.
heat
Member
Member
Posts: 103
Joined: Sat Mar 28, 2015 11:23 am
Libera.chat IRC: heat

Re: Find PE image (No PDB) error

Post by heat »

Is Print() supposed to take a CHAR16* or a CHAR8*? Stuff like that matters a lot, especially when CHAR16 is unicode and CHAR8 isn't.
If some of you people keep insisting on having backwards compatibitity with the stone age, we'll have stone tools forever.
My Hobby OS: https://github.com/heatd/Onyx
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Find PE image (No PDB) error

Post by chris13524 »

heat wrote:Is Print() supposed to take a CHAR16* or a CHAR8*? Stuff like that matters a lot, especially when CHAR16 is unicode and CHAR8 isn't.
This is exactly the issue, I'm not sure how to make 16-bit string literals though.
My operating system:
https://github.com/neonorb/aura
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Find PE image (No PDB) error

Post by ~ »

When you start writing a program, start by the skeleton. If it doesn't run with an empty main, then the problem is in the toolchain usage and stages earlier than compilation, or in the structure of the base skeleton.

To use wide chars that adjust automatically to the maximum width, use wchar_t

You can also use char8_t, uchar8_t, char16_t, uchar16_t, char32_t, uchar32_t or similar types for signed and unsigned 8, 16 and 32-bit characters selected in an explicit way.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Find PE image (No PDB) error

Post by Octocontrabass »

chris13524 wrote:Now it's printing "Hlowrd". I'm assuming that is because I'm casting to CHAR16* when it should be CHAR8* ? I'm guessing that's what the "L" did, make it a 16 bit literal? But again, my compiler is not understanding that "L".
The problem is that Print() is defined as taking a CHAR16*, but it should have been defined to take a const CHAR16*. This doesn't matter for C, but it causes the "invalid conversion" error in C++.

You can fix it like this:

Code: Select all

Print(const_cast<CHAR16*>(L"Hello world!"));
(...But why isn't there an error when you convert from const char*?)
Post Reply