[SOLVED] GCC bug?

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
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

[SOLVED] GCC bug?

Post by nexos »

I fixed my paging problem luckily, but when I try accessing the page, it gives me an invalid opcode. Stepping through the bochs debugger, I see a ud2 instruction! Is there a bug in GCC that causes this?
Last edited by nexos on Fri Jul 03, 2020 12:36 pm, edited 1 time in total.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Octocontrabass
Member
Member
Posts: 5885
Joined: Mon Mar 25, 2013 7:01 pm

Re: GCC bug?

Post by Octocontrabass »

GCC emits the UD2 instruction when it determines that there is no way to reach said instruction without relying on undefined behavior.

It's much more likely that there is a bug in your code.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: GCC bug?

Post by nexos »

That makes since. I was trying map address 0x0 and write to it. It works on any other address. I assume GCC thought it found a careless null pointer and try to prevent writing to it.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
8infy
Member
Member
Posts: 188
Joined: Sun Apr 05, 2020 1:01 pm

Re: GCC bug?

Post by 8infy »

nexos wrote:That makes since. I was trying map address 0x0 and write to it. It works on any other address. I assume GCC thought it found a careless null pointer and try to prevent writing to it.
yeah it does it for nullptr all the time, can confirm.
Octocontrabass
Member
Member
Posts: 5885
Joined: Mon Mar 25, 2013 7:01 pm

Re: GCC bug?

Post by Octocontrabass »

nexos wrote:I assume GCC thought it found a careless null pointer and try to prevent writing to it.
According to the C standard, converting the integer value 0 to a pointer is always equivalent to a null pointer. Dereferencing a null pointer is always undefined behavior.
PeterX
Member
Member
Posts: 590
Joined: Fri Nov 22, 2019 5:46 am

Re: GCC bug?

Post by PeterX »

Octocontrabass wrote:
nexos wrote:I assume GCC thought it found a careless null pointer and try to prevent writing to it.
According to the C standard, converting the integer value 0 to a pointer is always equivalent to a null pointer. Dereferencing a null pointer is always undefined behavior.
What puzzles me here: How does one get around that problem? By not using the (integer) const 0?

Greetings
Peter
Octocontrabass
Member
Member
Posts: 5885
Joined: Mon Mar 25, 2013 7:01 pm

Re: GCC bug?

Post by Octocontrabass »

GCC takes integers as memory addresses when converting to pointers, so there is no standards-compliant way to access memory address 0 with GCC (since it's equivalent to a null pointer). However, GCC provides -fno-delete-null-pointer-checks to relax that assumption, in case you're in a situation where 0 may be a valid address.

Personally, I would recommend never mapping anything at address 0.
nullplan
Member
Member
Posts: 1916
Joined: Wed Aug 30, 2017 8:24 am

Re: [SOLVED] GCC bug?

Post by nullplan »

Octocontrabass wrote:so there is no standards-compliant way to access memory address 0 with GCC (since it's equivalent to a null pointer).
I thought about this for a while: Wouldn't the easiest be to hide the fact that a pointer is NULL from GCC? So I thought, maybe write a function that returns a null pointer in assembler and call that. But that wouldn't work, since the resulting pointer would compare equal to a null pointer, and therefore accessing it is UB. So yeah, there is no valid way to access address 0 in C, as long as in your C implementation, address 0 is the null pointer. For that reason, and a bunch of other ones:
Octocontrabass wrote:Personally, I would recommend never mapping anything at address 0.
I wholeheartedly concur.

Or, to put this another way:
PeterX wrote:How does one get around that problem?
By writing a C compiler that does not represent null pointers as pointers to address zero. That is harder than it seems, since converting from integer to pointer now is no longer a no-op (converting integer 0 to pointer type must result in a null pointer). But this way you can actually tell between address 0 and a null pointer. Otherwise it is undefined.
Carpe diem!
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: [SOLVED] GCC bug?

Post by bzt »

You can take advantage of that if you know exactly what you're doing. I for one use -fno-delete-null-pointer-checks in my kernel all the time, because I map a supervisor-only page at 0 with information on the address space. This works fine: from user space, these information are unaccessible, plus all NULL references guaranteed to generate a page fault (so I can catch them even without the help of the compiler. I support multiple compilers for user land, and not all C compilers generate UD2). On the kernel side it has advantages too, as it's easy to get the properties of the current address space, they are always mapped at 0.

For an experienced OSdev programmer, "too smart" compilers are actually a lot more trouble than help. :-) For the kernel I use many many flags to turn off various features and make the compiler dumb, simply because I prefer to handle these things in my code myself. But I have many years of experience, I wouldn't recommend this approach for a newbie.

Cheers,
bzt
nullplan
Member
Member
Posts: 1916
Joined: Wed Aug 30, 2017 8:24 am

Re: [SOLVED] GCC bug?

Post by nullplan »

bzt wrote:You can take advantage of that if you know exactly what you're doing. I for one use -fno-delete-null-pointer-checks in my kernel all the time, because I map a supervisor-only page at 0 with information on the address space.
Dear god, why? The address space is a property of the task, so the pointer to the properties of the current address space belong into the task control block. Which in my OS is reachable by dereferencing GS and adding a constant to the result. Was gaining these few cycles really worth breaking your program for? Because a program that employs undefined behavior is fundamentally broken, whether compiler switches exist to smooth over the rough patch or not.

Wait, weren't you the guy who told me earlier you use uefi_call_wrapper() because you dislike compiler-specific extensions? So you don't like __attribute__, but you will write code that only works with special compiler switches and is no longer valid C. That seems like an inconsistency to me.
bzt wrote:For an experienced OSdev programmer, "too smart" compilers are actually a lot more trouble than help.
And for a smart compiler, "experienced" programmers are a lot of trouble. Learn C! It does not allow dereferencing null pointers, no matter how much you wish it did.
Carpe diem!
Post Reply