(Fixed) Different Panic Values
(Fixed) Different Panic Values
Original problem: wrong panic values, different values on different emulators
Solution: bitwise AND your segment registers by 0xFFFF, a common handler must match your registers struct
Solution: bitwise AND your segment registers by 0xFFFF, a common handler must match your registers struct
Last edited by Octacone on Tue Apr 18, 2017 6:15 am, edited 4 times in total.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
-
- Member
- Posts: 116
- Joined: Thu May 06, 2010 4:34 am
- Libera.chat IRC: peterbjornx
- Location: Leiden, The Netherlands
- Contact:
Re: Different Panic Values
Your structure is wrong, the segment registers are 16 bits long, hence they will only be pushed as uint16_t, not 32_t ( x86 does not require stack alignment on 32 bit words so no upcasting is done ), you are thus reading the wrong parts of the stack.
An important indicator of this failure is getting a value > 0xFFFF for a 16 bit register, which is simply not possible ( your other post where you said "I had no idea a 16 bit int could hold a 24 bit number" is simply nonsensical as a native 16 bit register generally only consists of 16 memory elements )
An important indicator of this failure is getting a value > 0xFFFF for a 16 bit register, which is simply not possible ( your other post where you said "I had no idea a 16 bit int could hold a 24 bit number" is simply nonsensical as a native 16 bit register generally only consists of 16 memory elements )
Re: Different Panic Values
I was suspecting that too, but nothing has changed. Now I am just getting zeros. Some things are okay, but most of them are not.Peterbjornx wrote:Your structure is wrong, the segment registers are 16 bits long, hence they will only be pushed as uint16_t, not 32_t ( x86 does not require stack alignment on 32 bit words so no upcasting is done ), you are thus reading the wrong parts of the stack.
An important indicator of this failure is getting a value > 0xFFFF for a 16 bit register, which is simply not possible ( your other post where you said "I had no idea a 16 bit int could hold a 24 bit number" is simply nonsensical as a native 16 bit register generally only consists of 16 memory elements )
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Re: Different Panic Values
that is wrong... when you push a segment register in 32-bit mode (that is, with a 32-bit operation size), the register will be zero-extended to 32-bits (not 16-bits)Peterbjornx wrote:Your structure is wrong, the segment registers are 16 bits long, hence they will only be pushed as uint16_t, not 32_t ( x86 does not require stack alignment on 32 bit words so no upcasting is done ), you are thus reading the wrong parts of the stack.
if you push with a 16-bit size (in 16-bit mode, or 32-bit mode with an o32 override) then you are correct, but in 32-bit mode (while nothing enforces the stack alignment) all pushes are 32-bits wide, including pushes of segment registers
note pushes of 16-bit GPRs require an o32 override (which will change the write size to 16-bit) so pushes of 16-bit GPRs do appear on the stack as 16-bit values, but pushes of segment registers (without an o32) will appear as 32-bit values on the stack -- of course if you add a pointless o32 to a push segment register instruction, then only 16-bits will be pushed to the stack, but otherwise, 32-bits will always be pushed to the stack
Re: Different Panic Values
This is wrong, in 32 bit protected mode all stack pushes are aligned to 32 bit...Peterbjornx wrote:Your structure is wrong, the segment registers are 16 bits long, hence they will only be pushed as uint16_t, not 32_t ( x86 does not require stack alignment on 32 bit words so no upcasting is done ), you are thus reading the wrong parts of the stack.
An important indicator of this failure is getting a value > 0xFFFF for a 16 bit register, which is simply not possible ( your other post where you said "I had no idea a 16 bit int could hold a 24 bit number" is simply nonsensical as a native 16 bit register generally only consists of 16 memory elements )
Changing it to 16bit and still having the keyword packed will **** up hard time
Incase you change the registers to uint16_t you need to pad the rest 16 bits with an empty/unused variable!
Actually the first 2 digits of your selectors are pretty much right, so simply and them with 0xFFFF or change uint32_t to 2 uint16_t's
This is mine:
Code: Select all
typedef struct
{
// pushed by stub
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
uint32_t esi;
uint32_t edi;
uint32_t ebp;
uint16_t ds, ds_pad;
uint16_t es, es_pad;
uint16_t fs, fs_pad;
uint16_t gs, gs_pad;
uint32_t intr;
uint32_t error;
// pushed by cpu
uint32_t eip;
uint16_t cs, cs_pad;
uint32_t eflags;
uint32_t esp;
uint16_t ss, ss_pad;
} __attribute__((packed)) CPU_STATE;
Re: Different Panic Values
Hey Ch4ozz, I tried both of your suggestions and neither of them worked. I am confused. Does the struct order matter? Does it have to go like: eax, ebx, ecx, edx...,ds, es, fs... I guess it has to match with the values that are being pushed one by one.Ch4ozz wrote:This is wrong, in 32 bit protected mode all stack pushes are aligned to 32 bit...Peterbjornx wrote:Your structure is wrong, the segment registers are 16 bits long, hence they will only be pushed as uint16_t, not 32_t ( x86 does not require stack alignment on 32 bit words so no upcasting is done ), you are thus reading the wrong parts of the stack.
An important indicator of this failure is getting a value > 0xFFFF for a 16 bit register, which is simply not possible ( your other post where you said "I had no idea a 16 bit int could hold a 24 bit number" is simply nonsensical as a native 16 bit register generally only consists of 16 memory elements )
Changing it to 16bit and still having the keyword packed will **** up hard time
Incase you change the registers to uint16_t you need to pad the rest 16 bits with an empty/unused variable!
Actually the first 2 digits of your selectors are pretty much right, so simply and them with 0xFFFF or change uint32_t to 2 uint16_t's
This is mine:Code: Select all
typedef struct { // pushed by stub uint32_t eax; uint32_t ebx; uint32_t ecx; uint32_t edx; uint32_t esi; uint32_t edi; uint32_t ebp; uint16_t ds, ds_pad; uint16_t es, es_pad; uint16_t fs, fs_pad; uint16_t gs, gs_pad; uint32_t intr; uint32_t error; // pushed by cpu uint32_t eip; uint16_t cs, cs_pad; uint32_t eflags; uint32_t esp; uint16_t ss, ss_pad; } __attribute__((packed)) CPU_STATE;
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
-
- Member
- Posts: 5587
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Different Panic Values
As far as I can tell, it's all normal.octacone wrote:Do these panic values seem okay to you?
Your SS and (user) ESP values are garbage because there's no privilege level change. If you cause a fault in usermode, you'll see normal values there. Since you're causing a fault in kernel mode, the CPU didn't push SS:ESP onto the stack. (Also, you should rename "esp" in your struct to "useless_padding".)
Yep.octacone wrote:3 different emulator 3 different outputs!?
The segment registers are different because some emulators zero the high 16 bits of the dword when they push a segment register to a 32-bit stack, and other emulators leave the high bits alone. Cast to uint16_t or bitwise AND with 0xFFFF before printing them.
I suspect EFLAGS.RF, CR0.CD, and CR0.NW are different because you didn't initialize them. (Be careful if you decide to mess with CR0. The CD and NW bits mean different things on different CPUs.)
Re: Different Panic Values
Octocontrabass wrote:As far as I can tell, it's all normal.octacone wrote:Do these panic values seem okay to you?
Your SS and (user) ESP values are garbage because there's no privilege level change. If you cause a fault in usermode, you'll see normal values there. Since you're causing a fault in kernel mode, the CPU didn't push SS:ESP onto the stack. (Also, you should rename "esp" in your struct to "useless_padding".)
Yep.octacone wrote:3 different emulator 3 different outputs!?
The segment registers are different because some emulators zero the high 16 bits of the dword when they push a segment register to a 32-bit stack, and other emulators leave the high bits alone. Cast to uint16_t or bitwise AND with 0xFFFF before printing them.
I suspect EFLAGS.RF, CR0.CD, and CR0.NW are different because you didn't initialize them. (Be careful if you decide to mess with CR0. The CD and NW bits mean different things on different CPUs.)
Thanks for explaining. Now it makes much more sense.
I did as you said and here is how it looks now:
...removed...for post clearance...
I think something is very wrong -> This is how I am triggering my fault: TUI.Put_Int(1 / 0, 0x0F); -> whenever I change that number to lets say 6, I get a corresponding error message. Something must be wrong. Is my common handler fine? Does that struct have any specific order in which I should put it. Does it matter how those values are defined one after other?
Last edited by Octacone on Tue Apr 18, 2017 6:17 am, edited 2 times in total.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
-
- Member
- Posts: 5587
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Different Panic Values
Your assembly handler and C struct do not match. Whatever you changed broke it.octacone wrote:I did as you said and here is how it looks now:
(Fixed) Different Panic Values
Solved!Octocontrabass wrote:Your assembly handler and C struct do not match. Whatever you changed broke it.octacone wrote:I did as you said and here is how it looks now:
I found my old struct and "mounted" it, now everything works perfectly.
Thanks everybody for helping me out, I just wanted to be sure that my code has no flaws.
Better work on something for days than cry later.
Final render:
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
-
- Member
- Posts: 116
- Joined: Thu May 06, 2010 4:34 am
- Libera.chat IRC: peterbjornx
- Location: Leiden, The Netherlands
- Contact:
Re: (Fixed) Different Panic Values
Please do not remove your questions after they are resolved, a forum serves not just as a way to ask questions but also to find existing solutions.
Re: (Fixed) Different Panic Values
Please do not bump old threads.Peterbjornx wrote:Please do not remove your questions after they are resolved, a forum serves not just as a way to ask questions but also to find existing solutions.
Everything important is there. I simplified the question so people browsing can find the solution right away. Please do not reply to dead threads anymore.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Re: (Fixed) Different Panic Values
I usually don't consider three week old threads that old.. But I have to agree, modifying the OP is really annoying, modifying any post is annoying.. Fixing typo's is ok and _adding_ an edit is fine, but completely rewriting any post basically kills the flow of the thread..Octacone wrote:Please do not bump old threads.Peterbjornx wrote:Please do not remove your questions after they are resolved, a forum serves not just as a way to ask questions but also to find existing solutions.
Everything important is there. I simplified the question so people browsing can find the solution right away. Please do not reply to dead threads anymore.
If you want to help the people who might read the thread in the future then you might want to add an edit where you give the answer, but rewriting the OP shouldn't be necessary..
Just my 2c..
Re: (Fixed) Different Panic Values
Why would that be annoying? From now on I will just leave those hard to understand questions and let people search trough ton of comments to find the answer. Why would somebody want a "broken" question? It is not any different in terms of the topic. But whatever, as you two suggested leave the 30 min to read question... Okay, not a problem.LtG wrote:I usually don't consider three week old threads that old.. But I have to agree, modifying the OP is really annoying, modifying any post is annoying.. Fixing typo's is ok and _adding_ an edit is fine, but completely rewriting any post basically kills the flow of the thread..Octacone wrote:Please do not bump old threads.Peterbjornx wrote:Please do not remove your questions after they are resolved, a forum serves not just as a way to ask questions but also to find existing solutions.
Everything important is there. I simplified the question so people browsing can find the solution right away. Please do not reply to dead threads anymore.
If you want to help the people who might read the thread in the future then you might want to add an edit where you give the answer, but rewriting the OP shouldn't be necessary..
Just my 2c..
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Re: (Fixed) Different Panic Values
Why would that be annoying? From now on I will just leave those hard to understand questions and let people search trough ton of comments to find the answer. Why would somebody want a "broken" question? It is not any different in terms of the topic. But whatever, as you two suggested leave the 30 min to read question... Okay, not a problem.LtG wrote:I usually don't consider three week old threads that old.. But I have to agree, modifying the OP is really annoying, modifying any post is annoying.. Fixing typo's is ok and _adding_ an edit is fine, but completely rewriting any post basically kills the flow of the thread..Octacone wrote:Please do not bump old threads.Peterbjornx wrote:Please do not remove your questions after they are resolved, a forum serves not just as a way to ask questions but also to find existing solutions.
Everything important is there. I simplified the question so people browsing can find the solution right away. Please do not reply to dead threads anymore.
If you want to help the people who might read the thread in the future then you might want to add an edit where you give the answer, but rewriting the OP shouldn't be necessary..
Just my 2c..
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader