[x64] Constructor of libsupc++.a uses FS

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
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

[x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

I'm porting my kernel to x64. In protected mode I used to use C++ features like constructors, virtual methods, exceptions. However in long mode I'm having a problem calling a constructor in the libsupc++.a library, particularly in the eh_alloc.o object file. All the others constructors are executed correctly. Disassembling the code which is going to be executed I found this in the first instructions of the constructor:

Code: Select all

ffffffff80235200 <_GLOBAL__I_eh_alloc.cc>:
ffffffff80235200:	48 83 ec 38          	sub    $0x38,%rsp
ffffffff80235204:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
ffffffff8023520b:	00 00 
ffffffff8023520d:	48 89 44 24 28       	mov    %rax,0x28(%rsp)
ffffffff80235212:	31 c0                	xor    %eax,%eax
ffffffff80235214:	48 83 3d 14 7f 05 00 	cmpq   $0x0,0x57f14(%rip)        # ffffffff8028d130 <AcpiRtypeNames+0x30>
ffffffff8023521b:	00 
...
Bochs stops at the second one (mov rax, fs:0x28). As far as I read on the wiki, the FS register can't be used in a legacy way, so I didn't bother initializing it among the other segment registers, and it still contains it's protected mode setup, pointing to a data segment from 0x00000000 to 0xffffffff. Why is this eh_alloc.o code using that register? Am I missing something? Should I initialize the register in a particular way?

Thanks...
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: [x64] Constructor of libsupc++.a uses FS

Post by gerryg400 »

Which tool chain are you using ?
If a trainstation is where trains stop, what is a workstation ?
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: [x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

The standard gcc/g++ compiler which cames with my ubuntu 64bit distribution. I'm using the libsup++ libgcc libgcc_eh taken from the host too.
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: [x64] Constructor of libsupc++.a uses FS

Post by Solar »

AFAIK, GCC assumes all segment registers being initialized to flat memory mode. I don't know why this specific constructor uses the FS register, but with the above assumption I'd think the GCC maintainers felt safe in doing so.
Every good solution is obvious once you've found it.
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: [x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

So I should use the MSR to set FS base address to 0, and that would suffice to set FS as flat?

Edit:
Set fs and gs using the "legacy" way (mov fs, ax). Still not working. This is the bochs dump when executing that instruction:

Code: Select all

00052987808i[CPU0 ] CPU is in long mode (active)
00052987808i[CPU0 ] CS.d_b = 16 bit
00052987808i[CPU0 ] SS.d_b = 16 bit
00052987808i[CPU0 ] EFER   = 0x00000500
00052987808i[CPU0 ] | RAX=ffffffff802351f0  RBX=0000000000103000
00052987808i[CPU0 ] | RCX=0000000000000080  RDX=00000000000003d5
00052987808i[CPU0 ] | RSP=ffffffff8010ef88  RBP=ffffffff8010eff8
00052987808i[CPU0 ] | RSI=0000000000000080  RDI=ffffffff8029b004
00052987808i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00052987808i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00052987808i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00052987808i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00052987808i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf SF zf AF PF cf
00052987808i[CPU0 ] | SEG selector     base    limit G D
00052987808i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00052987808i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 00000fff 1 0
00052987808i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00052987808i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00052987808i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 00000fff 1 0
00052987808i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00052987808i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00052987808i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00052987808i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00052987808i[CPU0 ] | RIP=ffffffff802351f4 (ffffffff802351f4)
00052987808i[CPU0 ] | CR0=0xe0000013 CR2=0x0000000000000080
00052987808i[CPU0 ] | CR3=0x00291000 CR4=0x00000620
(0).[52987808] [0x00000000002351f4] 0008:ffffffff802351f4 (unk. ctxt): mov rax, qword ptr fs:0x0000000000000028 ; 64488b042528000000
00052987808e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
Last edited by AlfaOmega08 on Tue Sep 13, 2011 7:31 am, edited 1 time in total.
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: [x64] Constructor of libsupc++.a uses FS

Post by Combuster »

GCC only expects DS=ES=SS; FS/GS were the only segmentation registers kept in long mode for thread-local storage purposes. They even added a SWAPGS instruction for convenience.

Since the operand is [FS:low_number], use of TLS seems most likely here. (and setting it FS.base to zero will consequently crash anything that expects TLS to be implemented)
"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 ]
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: [x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

ehm... I've never used thread local storage in kernel development... any particular setup?
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: [x64] Constructor of libsupc++.a uses FS

Post by Combuster »

Just a reminder why you don't want to reuse host toolchains :wink:
"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 ]
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: [x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

I wasn't successful at compiling libsupc++ and I read that using the host one would have worked. So I end up using the whole toolchain, from compilers to linkers and libraries
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: [x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

This is how I solved:

Code: Select all

//Alloc a page
void *tls = valloc(4096);
WriteMsr(0xC0001000, (uint64_t) tls);
The constructor now works as fs is pointing to valid memory.

I don't know if this will cause me problems, but actually it seems to work. I still didn't test exceptions..

Edit:

Exceptions don't work. Exploring the disassembly I found that __cxa_throw_exceptions calls __cxa_get_globals which takes a 64bit pointer at fs:0x0, then decreases it by 16, and since it's 0 it becomes the invalid pointer 0xFFFFFFFFFFF0. Looking in the libsupc++ source code, which now I MUST get to compile, I see preprocessors instructions like "#if _GLIBCXX_HAVE_TLS". I think a compilation is needed unless someone is able to point out how TLS works...
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: [x64] Constructor of libsupc++.a uses FS

Post by Owen »

...If the x86_64 SysV ABI doesn't say, the Thread Local Storage ELF supplement should
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: [x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

Well at this point I have three choices:
1) Remove libsupc++ and say godbye to exceptions
2) Compile or find a 64bit libsupc++ that won't use TLS (if someone is able to provide me one that would be great). But I have to say godbye to multithreading in the kernel
3) Add support for TLS in ELF in the Kernel loader and make everyone happy. Quite difficoult though...
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: [x64] Constructor of libsupc++.a uses FS

Post by jnc100 »

For TLS in IA-32, there was need for a register which stored the location of a thread pointer which was specific to each thread. Various data is accessed at positive and negative indices from this pointer. Due to the limited number of GPRs in the IA32 architecture, the GS register was chosen. GS is loaded with a segment which has its base at the address of the thread pointer (so that gs:0x0 is the address of the thread pointer) and a limit of 0xffffffff so that you can access gs:-0x4 without problems.

In x86_64, the mechanism is essentially the same, except that FS is used instead of GS.

The entire mechanism for setting up the TLS structures is specified in the document 'ELF Handling For Thread-Local Storage' as previously mentioned.

Regards,
John.
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: [x64] Constructor of libsupc++.a uses FS

Post by AlfaOmega08 »

berkus wrote:4) use some other library to implement exceptions?
If you can give me some links... because I've never heard of other libraries except from libsupc++
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
Post Reply