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
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to