linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* help with inline assembly code?
@ 2009-04-24 17:22 Chris Friesen
  2009-04-24 17:34 ` Scott Wood
  0 siblings, 1 reply; 5+ messages in thread
From: Chris Friesen @ 2009-04-24 17:22 UTC (permalink / raw)
  To: linuxppc-dev

Hi,

I've got a function that is used to overwrite opcodes in order to create 
self-modifying code.  It worked just fine with previous compilers, but 
with gcc 4.3 it seems like it sometimes (but not always) causes problems 
when inlined.  If I force it to never be inlined, it works fine.

First, here's the code:

void alter_opcode(unsigned long *addr, unsigned long opcode)
{
	asm volatile(
                 "stw    %1,0(%0)	\n\t"
                 "dcbf   0,%0		\n\t"
                 "sync			\n\t"
                 "icbi   0,%0,		\n\t"
                 "isync			\n\t"
                     :: "r" (addr), "r" (opcode): "memory");
}

The symptom of the problem is a segfault on the "stw" instruction.  I've 
verified that the address it's trying to write to is the expected 
address, and that the opcode being written is the expected opcode.

I assume I've mixed up the registers or constraints or 
something...anyone want to take a crack at it?

Chris

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: help with inline assembly code?
  2009-04-24 17:22 help with inline assembly code? Chris Friesen
@ 2009-04-24 17:34 ` Scott Wood
  2009-04-24 18:06   ` Chris Friesen
  0 siblings, 1 reply; 5+ messages in thread
From: Scott Wood @ 2009-04-24 17:34 UTC (permalink / raw)
  To: Chris Friesen; +Cc: linuxppc-dev

Chris Friesen wrote:
> I've got a function that is used to overwrite opcodes in order to create 
> self-modifying code.  It worked just fine with previous compilers, but 
> with gcc 4.3 it seems like it sometimes (but not always) causes problems 
> when inlined.  If I force it to never be inlined, it works fine.
> 
> First, here's the code:
> 
> void alter_opcode(unsigned long *addr, unsigned long opcode)
> {
>     asm volatile(
>                 "stw    %1,0(%0)    \n\t"
>                 "dcbf   0,%0        \n\t"
>                 "sync            \n\t"
>                 "icbi   0,%0,        \n\t"
>                 "isync            \n\t"
>                     :: "r" (addr), "r" (opcode): "memory");
> }
> 
> The symptom of the problem is a segfault on the "stw" instruction.  I've 
> verified that the address it's trying to write to is the expected 
> address, 

Verified by looking at the address in "addr", or by looking at the 
reported faulting address?

> and that the opcode being written is the expected opcode.
> 
> I assume I've mixed up the registers or constraints or 
> something...anyone want to take a crack at it?

Is the compiler assigning r0 to addr?  That will be treated as a literal 
zero instead.  Try changing "r" (addr) to "b" (addr), or use stwx.

-Scott

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: help with inline assembly code?
  2009-04-24 17:34 ` Scott Wood
@ 2009-04-24 18:06   ` Chris Friesen
  2009-04-24 18:14     ` Scott Wood
  0 siblings, 1 reply; 5+ messages in thread
From: Chris Friesen @ 2009-04-24 18:06 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev

Scott Wood wrote:
> Chris Friesen wrote:
>> I've got a function that is used to overwrite opcodes in order to create 
>> self-modifying code.  It worked just fine with previous compilers, but 
>> with gcc 4.3 it seems like it sometimes (but not always) causes problems 
>> when inlined.  If I force it to never be inlined, it works fine.
>>
>> First, here's the code:
>>
>> void alter_opcode(unsigned long *addr, unsigned long opcode)
>> {
>>     asm volatile(
>>                 "stw    %1,0(%0)    \n\t"
>>                 "dcbf   0,%0        \n\t"
>>                 "sync            \n\t"
>>                 "icbi   0,%0,        \n\t"
>>                 "isync            \n\t"
>>                     :: "r" (addr), "r" (opcode): "memory");
>> }
>>
>> The symptom of the problem is a segfault on the "stw" instruction.  I've 
>> verified that the address it's trying to write to is the expected 
>> address, 
> 
> Verified by looking at the address in "addr", or by looking at the 
> reported faulting address?

Verified by running it in userspace under gdb, then looking at the 
registers listed in the disassembly and comparing it to the process maps.


>> and that the opcode being written is the expected opcode.
>>
>> I assume I've mixed up the registers or constraints or 
>> something...anyone want to take a crack at it?
> 
> Is the compiler assigning r0 to addr?  That will be treated as a literal 
> zero instead.  Try changing "r" (addr) to "b" (addr), or use stwx.

Bingo!  Is there a constraint to tell the compiler to not use r0 for addr?

Chris

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: help with inline assembly code?
  2009-04-24 18:06   ` Chris Friesen
@ 2009-04-24 18:14     ` Scott Wood
  2009-04-24 18:23       ` Chris Friesen
  0 siblings, 1 reply; 5+ messages in thread
From: Scott Wood @ 2009-04-24 18:14 UTC (permalink / raw)
  To: Chris Friesen; +Cc: linuxppc-dev

Chris Friesen wrote:
> Scott Wood wrote:
>> Is the compiler assigning r0 to addr?  That will be treated as a 
>> literal zero instead.  Try changing "r" (addr) to "b" (addr), or use 
>> stwx.
> 
> Bingo!  Is there a constraint to tell the compiler to not use r0 for addr?

Yes, "b".

-Scott

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: help with inline assembly code?
  2009-04-24 18:14     ` Scott Wood
@ 2009-04-24 18:23       ` Chris Friesen
  0 siblings, 0 replies; 5+ messages in thread
From: Chris Friesen @ 2009-04-24 18:23 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev

Scott Wood wrote:
> Chris Friesen wrote:
>> Scott Wood wrote:
>>> Is the compiler assigning r0 to addr?  That will be treated as a 
>>> literal zero instead.  Try changing "r" (addr) to "b" (addr), or use 
>>> stwx.
>> Bingo!  Is there a constraint to tell the compiler to not use r0 for addr?
> 
> Yes, "b".

Doh.  Sorry, apparently I can't read today.  Both of those fixes seem to 
work.

Much appreciated.

Chris

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-04-24 18:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-24 17:22 help with inline assembly code? Chris Friesen
2009-04-24 17:34 ` Scott Wood
2009-04-24 18:06   ` Chris Friesen
2009-04-24 18:14     ` Scott Wood
2009-04-24 18:23       ` Chris Friesen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).