[solved] clang, uefi and global constructors

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
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

[solved] clang, uefi and global constructors

Post by kzinti »

I am using clang to cross-compile a UEFI bootloader (I use "-target x86_64-unknown-windows"). I would like to call global constructors before running any other code. I am not able to find the usual suspects ".init_array", "__CTOR_LIST__", "__init()" etc. Of course I am not linking any of the crtxxx stuff as this is a "bare metal" target.

Dumping the PDB I can see that there are references to global constructors (so they are generated):

Code: Select all

  0x1006 | LF_FUNC_ID [size = 48, hash = 0x38C6C]
           name = `dynamic initializer for 'g_test', type = 0x102E, parent scope = <no type>
  0x10B3 | LF_FUNC_ID [size = 52, hash = 0x2B878]
           name = metal::`dynamic initializer for 'g_log', type = 0x102E, parent scope = <no type>

    5976 | S_LPROCREF [size = 48] ``dynamic initializer for 'g_test'`
           module = 1, sum name = 0, offset = 236
   11592 | S_LPROCREF [size = 56] `metal::`dynamic initializer for 'g_log'`
           module = 11, sum name = 0, offset = 52

    6244 | S_GDATA32 [size = 24] `g_test`
           type = 0x1033 (Test), addr = 0003:0032
   11916 | S_GDATA32 [size = 28] `metal::g_log`
           type = 0x119E (metal::LogSystem), addr = 0003:1032
Dumping the PE file, I see a ".CRT" section that might or might not be related. It basically contains some address that points within the code, but I am not sure what is going on here.

What I cannot find is a way to run them on entry. The googles are not working today. Any idea?
Last edited by kzinti on Mon Aug 30, 2021 8:01 pm, edited 1 time in total.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: clang, uefi and global constructors

Post by kzinti »

It does look like the constructors end up listed in a table in the ".CRT" section. I have two global constructors and my ".CRT" is 16 bytes long. It contains two 64-bits addresses that point to initialization code for them.

At this point the question is how to I get access to that ".CRT" section from the PE code itself. I am thinking that adding two symbols in the .CRT section (at the beginning and end of the array) should do. That seems to be what VC does: https://docs.microsoft.com/en-us/cpp/c- ... om=vs-2019
Post Reply