GCC Inline asm label 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.
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

GCC Inline asm label BUG??

Post by tsdnz »

Hi, this code does not return the correct address, any ideas why?

!!!!!!!!!!!!!!!!!!!!!!!!!!! This is the issue !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SOM
2nd Update ******

Just look at the value passed into RAX!!!!!
The only difference is optimization.
It should point to the label!!!

2nd Update End ****
!!!!!!!!!!!!!!!!!!!!!!!!!!! This is the issue !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! EOM


Just looking at the address moved into rax, just example code of what has taken days to find.

Updated *****

I know my code is wrong, it is just example code, the issue is the value stored in rax, not the code, or the void proc.
It appears to be using the wrong address for rax.

End of Update ****

My work-around is going to be injecting values, which after testing also returns the incorrect address due to gcc optimization.

Here is the source:

Code: Select all

	void tInterrupts::SetupInterruptCodes()
	{
		QWORD Addr = (QWORD)&&TSD_InterruptCode_Start;
		asm volatile ("		movq %0, %%rax" : : "r"(Addr));
		asm volatile ("		retq");
		
TSD_InterruptCode_Start:

		asm volatile ("TSD_InterruptCode:");

		asm volatile ("		movq		%rax, -0x108(%rsp)");
}
The debug works fine, here:

Code: Select all

00000000003074de <_ZN6Kernel11tInterrupts19SetupInterruptCodesEv>:
  3074de:	55                   	push   rbp
  3074df:	48 89 e5             	mov    rbp,rsp
  3074e2:	48 83 ec 10          	sub    rsp,0x10
  3074e6:	48 c7 45 f8 f6 74 30 	mov    QWORD PTR [rbp-0x8],0x3074f6
  3074ed:	00 
  3074ee:	48 8b 45 f8          	mov    rax,QWORD PTR [rbp-0x8]
  3074f2:	48 89 c0             	mov    rax,rax
  3074f5:	c3                   	ret    

00000000003074f6 <TSD_InterruptCode>:
  3074f6:	48 89 84 24 f8 fe ff 	mov    QWORD PTR [rsp-0x108],rax
  3074fd:	ff 
  3074fe:	c9                   	leave  
  3074ff:	c3                   	ret    
But release, optimised is wrong:

Code: Select all

000000000031a960 <_ZN6Kernel11tInterrupts19SetupInterruptCodesEv>:
  31a960:	48 b8 60 a9 31 00 00 	movabs rax,0x31a960
  31a967:	00 00 00 
  31a96a:	48 89 c0             	mov    rax,rax
  31a96d:	c3                   	ret    

000000000031a96e <TSD_InterruptCode>:
  31a96e:	48 89 84 24 f8 fe ff 	mov    QWORD PTR [rsp-0x108],rax
  31a975:	ff 
  31a976:	c3                   	ret    
  31a977:	90                   	nop
  31a978:	0f 1f 84 00 00 00 00 	nop    DWORD PTR [rax+rax*1+0x0]
  31a97f:	00 
Last edited by tsdnz on Sat Jun 21, 2014 6:08 am, edited 6 times in total.
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: GCC Inline asm label BUG??

Post by tsdnz »

Also notice that debug is wrong, which means no optimization, when 00000000003074f6 <TSD_InterruptCode>: is an odd number
Octocontrabass
Member
Member
Posts: 5601
Joined: Mon Mar 25, 2013 7:01 pm

Re: GCC Inline asm label BUG??

Post by Octocontrabass »

GCC is working fine. Your code doesn't compile the way you want because it's wrong.

Code: Select all

   void tInterrupts::SetupInterruptCodes()
Your function returns void. If you want it to return a pointer, write it to return a pointer.

Code: Select all

   {
      QWORD Addr = (QWORD)&&TSD_InterruptCode_Start;
      asm volatile ("      movq %0, %%rax" : : "r"(Addr));
You don't need inline assembly to return a pointer.

Code: Select all

      asm volatile ("      retq");
This breaks the ABI. Your code will crash.

Code: Select all

TSD_InterruptCode_Start:

      asm volatile ("TSD_InterruptCode:");
This should be a separate function. Don't try to embed one function inside another.

Code: Select all

      asm volatile ("      movq      %rax, -0x108(%rsp)");
}
What is this supposed to do?
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: GCC Inline asm label BUG??

Post by tsdnz »

Thanks, I know the code is wrong with stack.
The address used by rax is incorrect.
Did you try compiling the code with no optimization and full optimization?
It returns different rax addresses.
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: GCC Inline asm label BUG??

Post by tsdnz »

The code creates custom interrupt handlers for my OS.
I am removing two calls and cache misses.
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: GCC Inline asm label BUG??

Post by tsdnz »

I have to embedded one function inside another, otherwise when no optimization gcc adds stack code, which crashes the interrupt
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: GCC Inline asm label BUG??

Post by Combuster »

BUG
Rule 1: GCC has no bugs that you will find.
tsdnz wrote:The code creates custom interrupt handlers for my OS.
Write such things in assembly instead of trying to fight a war against the compiler.
"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 ]
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: GCC Inline asm label BUG??

Post by tsdnz »

Rule 1: GCC has no bugs that you will find.
How do you know this? LOL. Did you try to compile the program with no optimistation and full optimistation?
My GCC shows the output I pasted, which is wrong, I am sure??
Write such things in assembly instead of trying to fight a war against the compiler.
Totally agree, I had most of this in my second loader, but I want it in the Kernel as I can remove cache misses and some calls.
Now that I have found the issue I have tried to this is assembly, but not sure how to get it working.

To do this in asm I also need the address in a register.

Source:

Code: Select all

		asm volatile ("TSD_InterruptCode:");
		asm volatile ("		movq		TSD_InterruptCode, %rax");
		asm volatile ("		lea			TSD_InterruptCode, %rax");
but it returns this:

Code: Select all

00000000003074f6 <TSD_InterruptCode>:
  3074f6:	48 8b 04 25 f6 74 30 	mov    rax,QWORD PTR ds:0x3074f6
  3074fd:	00 
  3074fe:	48 8d 04 25 f6 74 30 	lea    rax,ds:0x3074f6
  307505:	00 
How do I get the address of the label??
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: GCC Inline asm label BUG??

Post by tsdnz »

Right, just tested the lea, as below, which works, so time for asm!!

Code: Select all

		asm volatile ("TSD_InterruptCode:");
		asm volatile ("		lea			(TSD_InterruptCode), %rax");
		asm volatile ("		cmp			$0x3074e6, %rax");
		asm volatile ("		je			TSD_InterruptCode");
		asm volatile ("		hlt");

Code: Select all

00000000003074e6 <TSD_InterruptCode>:
  3074e6:	48 8d 04 25 e6 74 30 	lea    rax,ds:0x3074e6
  3074ed:	00 
  3074ee:	48 3d e6 74 30 00    	cmp    rax,0x3074e6
  3074f4:	74 f0                	je     3074e6 <TSD_InterruptCode>
  3074f6:	f4                   	hlt    
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: GCC Inline asm label BUG??

Post by Combuster »

Because rule 1 says you won't find bugs in GCC, your claim that GCC has a bug must be wrong. And in fact, GCC behaves as expected. The entire rest of your post only demonstrates you don't know what you're doing.


The next thing of my post that you ignored is that you're still using inline assembly. Inline assembly is a complicated structure meant to allow cooperation between snippets and compiler-generated code. It's so complicated that almost nobody knows how to use it correctly. That includes you. Write everything you need in a dedicated assembly file, then we can discuss the remaining problems with your knowledge of that language. But before that, all bets are off.
"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 ]
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: GCC Inline asm label BUG??

Post by tsdnz »

Because rule 1 says you won't find bugs in GCC, your claim that GCC has a bug must be wrong. And in fact, GCC behaves as expected.
Do you work for Microsoft? It took me months to prove to them they had bugs in .net, Silverlight and VS, but anyway we got there in the end.
How does it behave as expected? RAX does not point to the label, what am I missing that you can see?
The entire rest of your post only demonstrates you don't know what you're doing.
Take you med's mate, I know exactly what I am doing and where I am taking my OS.
The next thing of my post that you ignored is that you're still using inline assembly. Inline assembly is a complicated structure meant to allow cooperation between snippets and compiler-generated code. It's so complicated that almost nobody knows how to use it correctly. That includes you. Write everything you need in a dedicated assembly file, then we can discuss the remaining problems with your knowledge of that language. But before that, all bets are off.
I know it is only meant for cooperation ....
But it is also nice to code directly inline, I will tidy up the inline, but this code is just to show what "I THINK" is a bug??
If you are suggesting the lea code, just never seen it in that form, used to lea rax, [], thats all!!

Have you tried to compile it and have you checked the results?
Or have you just reviewed the code?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: GCC Inline asm label BUG??

Post by bluemoon »

tsdnz wrote:How does it behave as expected? RAX does not point to the label, what am I missing that you can see?
Since you declare the function to return nothing (void), the compiler is free to put anything, including leftover or trash, in RAX (or preserve the value, never write such things so have to check the manual). Things work without optimisation is generally an indicator that you broke the ABI contract or compiler rules.

One in a million chance you will find bug in gcc, and one in a zillion chance you would be the first one. So it's better to first verify if any other problem, including user error, which has relatively higher chance to occur.
tsdnz wrote:Take you med's mate, I know exactly what I am doing and where I am taking my OS.
http://en.wikipedia.org/wiki/Dunning%E2 ... ger_effect
No offence but your code provide certain indication that you did not respect the compiler rules and ABI.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: GCC Inline asm label BUG??

Post by jnc100 »

tsdnz wrote:

Code: Select all

	void tInterrupts::SetupInterruptCodes()
	{
		QWORD Addr = (QWORD)&&TSD_InterruptCode_Start;
		asm volatile ("		movq %0, %%rax" : : "r"(Addr));
		asm volatile ("		retq");
		
TSD_InterruptCode_Start:

		asm volatile ("TSD_InterruptCode:");

		asm volatile ("		movq		%rax, -0x108(%rsp)");
}
As far as the compiler is concerned, none of those asm statements actually do anything. The presence of the volatile modifier stops it deleting them, but it is free to reorder them as it wishes. In addition, it is free to insert any of its own code between the various asm statements which may overwrite anything you've saved in them.

Regards,
John.
Octocontrabass
Member
Member
Posts: 5601
Joined: Mon Mar 25, 2013 7:01 pm

Re: GCC Inline asm label BUG??

Post by Octocontrabass »

tsdnz wrote:what am I missing that you can see?
  • A function that returns a value is written as returning void
  • The inline assembly breaks the ABI by trying to return using "retq"
  • Labels are used as pointers outside their scope
  • Using a C function as an interrupt service routine breaks the ABI
User avatar
Lionel
Member
Member
Posts: 117
Joined: Fri Jul 16, 2010 2:16 pm
Libera.chat IRC: ryanel
Location: California

Re: GCC Inline asm label BUG??

Post by Lionel »

I would love to point out that if you were having a problem, telling the people that are attempting to help you is wrong. You're the one who knows less, yet you are rude to the people why try to help you. Regardless, here are your problems condensed:
  • This code violates the C language and the SysV ABI. Since your compiling with the optimizer enabled, GCC doesn't like it when you do stuff it doesn't understand. GCC does NOT understand inline assembly. It should be moved to an assembly file so that GCC doesn't touch it at all. This is what everyone else does.
  • I don't believe that labels are a good practice in inline assembly. It's voodoo, or at the very least, insane.
  • You being belligerent doesn't make us want to help you and we can and will refuse to help you anytime.
Don't break things you clearly don't understand and then blame other people for your own problems. :3
And if you ignore our advice and find an alternate solution mind you that next time anyone else tries to compile it IT WILL BREAK, and that if you upgrade your compiler, IT WILL BREAK.
Post Reply