OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Feb 24, 2021 11:20 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: reference to `___chkstk_ms'
PostPosted: Sat Jul 26, 2014 3:16 am 
Offline
Member
Member

Joined: Fri May 16, 2014 2:40 pm
Posts: 36
Recently I started developing for UEFI. So far, everything has been going great. The setup of the development environment is a bit weird and it was hard to find a right one, but once you have it running, it works fine (Except for debugging, which is still shitty since you have to tell gdb each time where the code is executed...).

My setup consists of the default mingw64 package in arch linux, which I use to output an subsystem 10 application (EFI application). Since the uefi environment does not have the standard libraries, I compile it as freestanding.

At the moment, I'm having a linking error though. For easyness I currently simply allocated a big buffer (well, not too big) on the stack (I know, bad practice). I expected that I could have issues like a stack not being big enough (even though the allocation is still not too big). However, when using a big buffer, I get errors during the linking stage. The generated code by gcc, tries to call a function ___chkstk_ms, which (I think ) tries to check the stack. I'm linking the executable with libgcc, but this has not solved the issue.

The parameters I use to compile:
Code:
x86_64-w64-mingw32-gcc -ffreestanding -Wall -Wextra -std=c11 -O0 -fno-stack-protector -fpic -mno-red-zone -fno-builtin -o src/main.o -c src/main.c
x86_64-w64-mingw32-gcc -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -pie -e kernel_main -lgcc  -o bin/EFI/Boot/bootx64.efi src/main.o


The exact error that I get:
Code:
src/main.o: In function `kernel_main':
/home/rob/Projects/C-C++/RobOS/src/main.c:36: undefined reference to `___chkstk_ms'
collect2: error: ld returned 1 exit status


I figured that it may be because I'm not using a self built crosscompiler. I tried to compile gcc for the x86_64-w64-mingw32 target but this kept failing with errors about not having a valid /lib/cpp environment when compiling libgcc. I may be able to work around all the errors here, but I thought to first ask here if it actually is a problem with the environment, or whether I simply forget to link a certain library or something.


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sat Jul 26, 2014 4:10 am 
Offline
Member
Member
User avatar

Joined: Thu Dec 19, 2013 1:40 am
Posts: 100
Location: Asia, Singapore
Just a note: I don't think I have the best answer, so if anyone notices that my solution does have a problem do correct me.
Anyway it seems that there are some problems in your environment. Firstly, I don't think you should be using MinGW, you might want to use GCC instead unless Arch linux doesn't have the GCC package (yes, its probably around the same but MinGW stands for Minimalist GNU for Windows, not what I would suggest you to use...). Even if Arch linux doesn't have go grab the source from online. Next is the target you tried to build, it seems...invalid...you might want to look around for those that the developers of OS that uses UEFI uses, if I am not wrong its something else. The forum might have something...

I do understand this is rather vague, but that is all I know as of now hope it helps you. Hopefully someone with an insight into how you should be compiling your crosscompiler would answer to your problem quickly. This might not help you depending on the exact cause of your issue but it would prevent problems later on.

_________________
CookieOS. Want a cookie? Its only black and white for now though, probably as bad as my baking skills.


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sat Jul 26, 2014 4:33 am 
Offline
Member
Member

Joined: Fri May 16, 2014 2:40 pm
Posts: 36
Let me explain why I'm using mingw. UEFI uses the PE executable format for the application, which is about the same as a windows executable.
There are several ways to create such executable on windows. Using the UDK (UEFI DevKit) which is extremely big and difficult. Another one is using gnu-efi, which is gcc with a crosscompiled bin-utils which provides the ability to work with the pe format. They then use a wrapper function that converts the ABI between ms standards and gcc standards.

The third option is to use mingw to create the binary (since it normally creates windows binaries, meant to run on windows), and use the same headers as gnu-efi, only without the ABI conversions, since mingw already uses the microsoft conventions. Since this is in my opinion the easiest approach, I chose this last option. I definitely want to keep doing this, since it also allows me to compile the same source directly from visual studio from time to time...

Now, it could be that the target I tried to build is incorrect, however, it did produce a working compiler. The only problem is compiling the libgcc for that target. Since I'm not particularly looking for building the crosscompiler, but simply for fixing the error I got, I haven't investigated this further. I will do that if it actually turns out to be my environment, since it will take me some work to figur out. I haven't done this yet since it may as well be some standard lib that I have to link which I forgot or something.
In other words, I'm simply looking for confirmation whether my way of compiling and linking is correct for a UEFI application.


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sat Jul 26, 2014 5:31 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
According to a quick google, ___chkstk_ms should be defined in libgcc. You probably want the '-lgcc' option at the end of your link command, after the object files (rather than before).

If that does not work, try adding '-fno-stack-check -fno-stack-protector -mno-stack-arg-probe' to your CFLAGS.

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 7:10 am 
Offline
Member
Member

Joined: Fri May 16, 2014 2:40 pm
Posts: 36
Wow, I feel stupid now. I did find the correlation with libgcc, however I assumed it had to be something different since I had it specified in the parameters. Placing the -lgcc at the end of the command line worked.

Thanks jnc100 for all the help already!


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 7:28 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
No problem. Out of interest, do you know exactly what change to your source caused it to emit a dependency on ___chkstk_ms? I only ask because I'm unable to reproduce it here and would like to test out whether the stack protector in libgcc still works correctly in a UEFI environment before adding it to the wiki article.

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 8:05 am 
Offline
Member
Member

Joined: Fri May 16, 2014 2:40 pm
Posts: 36
I simply declared a big array on the stack. Inside of a function, simply declare the following: EFI_MEMORY_DESCRIPTOR descriptors[150];

Obviously this depends on the amount of other data on the stack. In my case, I triggered it when using more than 90 as size ;)


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 8:36 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9289
Location: On the balcony, where I can actually keep 1½m distance
I.e. provoking windows-specific code to poke the stack in chunks as to not make it believe you smashed the stack instead. I guess that's a particular problem of not having a native EFI toolchain.

But large stack arrays are often a signature of unhealthy code anyway...

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 8:39 am 
Offline
Member
Member

Joined: Fri May 16, 2014 2:40 pm
Posts: 36
I just used it when poking around a little. I know that allocating big arrays on the stack is bad practice ;) I still wanted to figure out how to solve it since it could be a deeper problem (which it was because apparently libgcc wasn't linked in...)


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 10:07 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
robbiedobbie wrote:
I simply declared a big array on the stack.)
Thanks, confirmed and fixed in the wiki.

Combuster wrote:
I.e. provoking windows-specific code to poke the stack in chunks as to not make it believe you smashed the stack instead. I guess that's a particular problem of not having a native EFI toolchain.
I wouldn't consider a dependency on libgcc to be 'windows-specific' code, despite it using the same name as a function in MSVCRT. I'd imagine the Mingw developers haven't looked at the MS source code in order to implement it. Regardless, there are compiler options to disable it if you like.

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 12:14 pm 
Offline
Member
Member

Joined: Sat Nov 21, 2009 5:11 pm
Posts: 727
It's Windows-specific because calling chkstk is only meaningful on Windows. Other systems do not require it.


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 2:47 pm 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
Gigasoft wrote:
It's Windows-specific because calling chkstk is only meaningful on Windows. Other systems do not require it.
Its an implementation of stack protection that works on the Microsoft x64 ABI (the same ABI as used in UEFI). It is not required per se under Windows as you can disable it. There also exists a GCC stack protection mechanism, which can also be enabled or disabled, which emits references to __stack_chk_guard which is defined in libssp (and incidentally cannot be compiled easily for a vanilla cross-compiler due to dependencies on libc).

My point was that the compiler is free to emit calls to its bundled libraries at will and you should link with them, and that I do not consider a dependency on libgcc to be windows-specific. However I feel we are arguing about semantics.

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 4:35 pm 
Offline
Member
Member

Joined: Sat Nov 21, 2009 5:11 pm
Posts: 727
You must be thinking of something else. Chkstk is definitely only meaningful for Windows user mode applications, as it requires that stack pages are accessed in a decrementing manner. Although it is possible to prevent the compiler from generating chkstk calls, the resulting program will not be correct (unless you know that you have committed all the stack pages in advance). A program that fails to touch all stack pages in the correct order will crash. On other systems, there is no such requirement, and calling chkstk does nothing except waste time.


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Sun Jul 27, 2014 11:36 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9289
Location: On the balcony, where I can actually keep 1½m distance
From the libgcc source (libgcc/config/i386/cygwin.S):
Code:
/* Function prologue calls __chkstk to probe the stack when allocating more
   than CHECK_STACK_LIMIT bytes in one go.  Touching the stack at 4K
   increments is necessary to ensure that the guard pages used
   by the OS virtual memory manger are allocated in correct sequence.  */
Note the mention of "guard pages" and "OS virtual memory manager"

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: reference to `___chkstk_ms'
PostPosted: Mon Jul 28, 2014 3:41 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
My apologies, I was mistaken. I'd thought it was an implementation of a stack protector (i.e. with canary value et al). Thank you for the pointers, but I guess it is something we don't need in a UEFI environment (at least I can find no evidence that stack probing is required in x64 UEFI). Out of interest, the MSVC compiler also appears to emit these references when used for UEFI (link).

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: PeterX, rizxt and 13 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group