Subject: Re: help with inline assembly code?

From: Scott Wood <[email-masked]>
Date: Fri, 24 Apr 2009 12:34:57 -0500

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