Page 1 of 1

Garbage inserted before a function?

Posted: Sat Jul 16, 2022 2:27 pm
by Techflash
I'm trying to have a function that initializes all of the stuff in my kernel (framebuffer TTY, keyboard LEDS, serial port). But for some reason, when GCC compiles it, it inserts a bunch of junk before the actual function code starts. This junk code then gets executed, and proceeds to triple fault. I verified this by putting `__asm__ ("cli\n" "hlt")` before anything else in the function. And sure enough, there's like 20 garbage bytes in front of the `cli hlt` in the disassembly. I have the x86_64-elf cross compiler, with red zone disabled, and `-mcmodel=kernel` for both libgcc and for my kernel. You can find the source code to the problematic file here: https://github.com/techflashYT/Techflas ... initions.c. And the hex bytes & disassembly of the junk below.

Code: Select all

55 48 89 E5 48 83 EC 20 F3 0F 7E 05 50 0F 00 00 F3 0F 7E 0D 40 0F 00 00 0F 16 05 31 0F 00 00 0F 16 0D 42 0F 00 00 0F 29 45 E0 0F 29 4D F0

Code: Select all

ffffffffffe02040 <__init>:
ffffffffffe02040:       55                      push   %rbp
ffffffffffe02041:       48 89 e5                mov    %rsp,%rbp
ffffffffffe02044:       48 83 ec 20             sub    $0x20,%rsp
ffffffffffe02048:       f3 0f 7e 05 50 0f 00    movq   0xf50(%rip),%xmm0        # ffffffffffe02fa0 <_binary_font_psf_end+0x10>
ffffffffffe0204f:       00 
ffffffffffe02050:       f3 0f 7e 0d 40 0f 00    movq   0xf40(%rip),%xmm1        # ffffffffffe02f98 <_binary_font_psf_end+0x8>
ffffffffffe02057:       00 
ffffffffffe02058:       0f 16 05 31 0f 00 00    movhps 0xf31(%rip),%xmm0        # ffffffffffe02f90 <_binary_font_psf_end>
ffffffffffe0205f:       0f 16 0d 42 0f 00 00    movhps 0xf42(%rip),%xmm1        # ffffffffffe02fa8 <_binary_font_psf_end+0x18>
ffffffffffe02066:       0f 29 45 e0             movaps %xmm0,-0x20(%rbp)
ffffffffffe0206a:       0f 29 4d f0             movaps %xmm1,-0x10(%rbp)
ffffffffffe0206e:       fa                      cli    
ffffffffffe0206f:       f4                      hlt

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 2:34 pm
by Demindiro

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 2:58 pm
by Techflash
It doesn't look at all like any of the examples in the wikipedia page you linked. I can understand if it was doing stuff with the base or stack pointers, but it's doing something wildly different (after the first 2 lines of disasm), and it causes a triple fault (I can tell, because I tried hex editing the binary to replace all of those bytes with 90h [nop], and it halts correctly)

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 3:24 pm
by Octocontrabass
Techflash wrote:This junk code then gets executed, and proceeds to triple fault
It's not junk, it's part of the code for populating the kernTTY, serial, and keyboard structs. You've turned on optimizations that cause the compiler to rearrange code. It causes a triple fault because it uses SSE registers and you haven't correctly initialized the CPU for SSE support.
Techflash wrote:and `-mcmodel=kernel` for both libgcc and for my kernel
Your kernel is definitely not using "-mcmodel=kernel".

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 3:38 pm
by nexos
Your kernel shouldn't be using the SSE registers. It will make things very complicated in your scheduler if it does use them. For this reason, you should pass the following arguments to GCC / Clang:

Code: Select all

-mno-3dnow -mno-mmx -mno-sse -mno-sse2 -mno-avx
That will suppress SSE usage, along with AVX, MMX, and 3DNow, which are in the same vein as SSE. Note that I probably missed some options here, but you get the idea.

That should fix the triple fault.

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 3:45 pm
by Octocontrabass
Or "-mgeneral-regs-only".

(But you can't build x86-64 libgcc with SSE disabled without patching it. One of these days I'm going to figure out how to do that...)

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 4:02 pm
by nexos
Octocontrabass wrote:Or "-mgeneral-regs-only".
I would have suggested that, but Clang didn't support it back when I tried it. But that probably doesn't matter as I assume the OP is using GCC.
Octocontrabass wrote:(But you can't build x86-64 libgcc with SSE disabled without patching it. One of these days I'm going to figure out how to do that...)
That's quite unfortunate. Sounds like libgcc can be quite finicky.

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 4:29 pm
by Techflash
Octocontrabass wrote:
Techflash wrote:This junk code then gets executed, and proceeds to triple fault
It's not junk, it's part of the code for populating the kernTTY, serial, and keyboard structs. You've turned on optimizations that cause the compiler to rearrange code. It causes a triple fault because it uses SSE registers and you haven't correctly initialized the CPU for SSE support.
Techflash wrote:and `-mcmodel=kernel` for both libgcc and for my kernel
Your kernel is definitely not using "-mcmodel=kernel".
Whoops. I guess it isn't. I reset everything a few days ago. Still getting around to fixing some thing.

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 4:30 pm
by Techflash
nexos wrote:Your kernel shouldn't be using the SSE registers. It will make things very complicated in your scheduler if it does use them. For this reason, you should pass the following arguments to GCC / Clang:

Code: Select all

-mno-3dnow -mno-mmx -mno-sse -mno-sse2 -mno-avx
That will suppress SSE usage, along with AVX, MMX, and 3DNow, which are in the same vein as SSE. Note that I probably missed some options here, but you get the idea.

That should fix the triple fault.
Ahhh. So those are the SSE registers. I knew that they were from one of the extensions. I was just concerned about why that code was there in the first place.

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 4:34 pm
by Techflash
Alright. It worked. Thanks for the help!

Re: Garbage inserted before a function?

Posted: Sat Jul 16, 2022 4:36 pm
by Octocontrabass
nexos wrote:I would have suggested that, but Clang didn't support it back when I tried it.
It's a relatively new feature. It seems to be supported in Clang 13 and up.