I'm having the following problem: my software is causing a deadlock and the only clue that I have about its origin is a primitive stack trace with only 8 levels provided by my chipset for situations like this.
However, my stack trace is something like:
memset
memset
memset
memset
memset
memset
memset
memset
I want to remove memset out of my way to see which function is causing this mess. If I ask gcc to inline memset, it will complain stating that I don't have the function body for it.
So, is there a way to inline memset? Does anyone have any other idea about debugging this problem?
EDIT
I've already tried to replace memset with a dumb implementation using a for, but this made my software behave strangely and other problems appear that prevents me from getting to the deadlock.
EDIT
By the way, I'm using the MIPS arch. I'm not an MIPS assembly expert, so I've made a dumb attempt at getting the disassembled code for memset and inserting in the body of a C function. I got different instructions from objdump -d and gdb disassemble, so I've tried with both of them. Here are the functions that I've created:
void * memset(void * str_a, int ch, size_t count) {
asm("mov #12,r0");
asm("cmp/gt r6,r0");
asm("mov r4,r0");
asm("bt.s 30 <.L_dup_bytes+0x18>");
asm("add r4,r6");
asm("tst #3,r0");
asm("bt.s 18 <.L_dup_bytes>");
asm("extu.b r5,r5");
asm("mov.b r5,@r0");
asm("add #1,r0");
asm("tst #3,r0");
asm("bf 10 <_memset+0x10>");
}
void * memset(void * str_a, int ch, size_t count) {
asm("mov #12,r0");
asm("cmp/gt r6,r0");
asm("mov r4,r0");
asm("bt.s 0x8163682c <memset+48>");
asm("add r4,r6");
asm("tst #3,r0");
asm("bt.s 0x81636814 <memset+24>");
asm("extu.b r5,r5");
asm("mov.b r5,@r0");
asm("add #1,r0");
asm("tst #3,r0");
asm("bf 0x8163680c <memset+16>");
asm("swap.b r5,r2");
asm("or r2,r5");
asm("swap.w r5,r2");
asm("or r2,r5");
asm("add #-16,r6");
asm("nop ");
asm("mov.l r5,@r0");
asm("cmp/hs r6,r0");
asm("mov.l r5,@(4,r0)");
asm("bf.s 0x81636820 <memset+36>");
asm("add #8,r0");
asm("add #16,r6");
asm("cmp/eq r6,r0");
asm("bt 0x81636838 <memset+60>");
asm("mov.b r5,@r0");
asm("add #1,r0");
asm("cmp/eq r6,r0");
asm("bf 0x81636830 <memset+52>");
asm("rts ");
asm("mov r4,r0");
}
This gave me the following errors:
First memset:
/tmp/ccAuFFap.s: Assembler messages:
/tmp/ccAuFFap.s:3457: Warning: missing operand; zero assumed
/tmp/ccAuFFap.s:3469: Warning: missing operand; zero assumed
/tmp/ccAuFFap.s:3489: Warning: missing operand; zero assumed
/tmp/ccAuFFap.s:3457: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/ccAuFFap.s:3469: Error: displacement to undefined symbol .L0 overflows 8-bit field
/tmp/ccAuFFap.s:3489: Error: displacement to defined symbol .L0 overflows 8-bit field
Second memset:
/tmp/cctCDgi5.s: Assembler messages:
/tmp/cctCDgi5.s:3457: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3469: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3489: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3529: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3545: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3561: Warning: missing operand; zero assumed
/tmp/cctCDgi5.s:3457: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3469: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3489: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3529: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3545: Error: displacement to defined symbol .L0 overflows 8-bit field
/tmp/cctCDgi5.s:3561: Error: displacement to defined symbol .L0 overflows 8-bit field
Can someone help with those errors?
EDIT
Tried another version with the source code from :
void * memset(void * str_a, int ch, size_t count) {
asm("slti t1, a2, 8 ");
asm("bne t1, zero, L(last8)");
asm("move v0, a0 ");
asm("beq a1, zero, L(ueven) ");
asm("andi a1, 0xff ");
asm("sll t0, a1, 8");
asm("or a1, t0");
asm("sll t0, a1, 16");
asm("or a1, t0 ");
asm("L(ueven): ");
asm("subu t0, zero, a0 ");
asm("andi t0, 0x3");
asm("beq t0, zero, L(chkw)");
asm("subu a2, t0");
asm("SWHI a1, 0(a0) ");
asm("addu a0, t0 ");
asm("L(chkw): ");
asm("andi t0, a2, 0x7 ");
asm("beq t0, a2, L(chkl)");
asm("subu a3, a2, t0");
asm("addu a3, a0 ");
asm("move a2, t0 ");
asm("L(loopw): ");
asm("addiu a0, 8 ");
asm("sw a1, -8(a0)");
asm("bne a0, a3, L(loopw)");
asm("sw a1, -4(a0)");
asm("L(chkl): ");
asm("andi t0, a2, 0x4 ");
asm("beq t0, zero, L(last8) ");
asm("subu a2, t0");
asm("sw a1, 0(a0) ");
asm("addiu a0, 4");
asm("L(last8): ");
asm("blez a2, L(exit) ");
asm("addu a3, a2, a0 ");
asm("L(lst8l): ");
asm("addiu a0, 1");
asm("bne a0, a3, L(lst8l)");
asm("sb a1, -1(a0)");
asm("L(exit): ");
asm("j ra ");
asm("nop");
}
Here are the errors this time:
/tmp/ccuyfGW5.s: Assembler messages:
/tmp/ccuyfGW5.s:5131: Error: unknown opcode
/tmp/ccuyfGW5.s:5135: Error: unknown opcode
/tmp/ccuyfGW5.s:5139: Error: unknown opcode
/tmp/ccuyfGW5.s:5143: Error: unknown opcode
/tmp/ccuyfGW5.s:5147: Error: unknown opcode
/tmp/ccuyfGW5.s:5151: Error: unknown opcode
/tmp/ccuyfGW5.s:5155: Error: invalid operands for opcode
/tmp/ccuyfGW5.s:5159: Error: unknown opcode
/tmp/ccuyfGW5.s:5163: Error: invalid operands for opcode
/tmp/ccuyfGW5.s:5167: Error: unknown opcode
/tmp/ccuyfGW5.s:5171: Error: unknown opcode
/tmp/ccuyfGW5.s:5175: Error: unknown opcode
/tmp/ccuyfGW5.s:5179: Error: unknown opcode
/tmp/ccuyfGW5.s:5183: Error: unknown opcode
/tmp/ccuyfGW5.s:5187: Error: unknown opcode
/tmp/ccuyfGW5.s:5191: Error: unknown opcode
/tmp/ccuyfGW5.s:5195: Error: unknown opcode
/tmp/ccuyfGW5.s:5199: Error: unknown opcode
/tmp/ccuyfGW5.s:5203: Error: unknown opcode
/tmp/ccuyfGW5.s:5207: Error: unknown opcode
/tmp/ccuyfGW5.s:5211: Error: unknown opcode
/tmp/ccuyfGW5.s:5215: Error: unknown opcode
/tmp/ccuyfGW5.s:5219: Error: unknown opcode
/tmp/ccuyfGW5.s:5223: Error: unknown opcode
/tmp/ccuyfGW5.s:5227: Error: unknown opcode
/tmp/ccuyfGW5.s:5231: Error: unknown opcode
/tmp/ccuyfGW5.s:5235: Error: unknown opcode
/tmp/ccuyfGW5.s:5239: Error: unknown opcode
/tmp/ccuyfGW5.s:5243: Error: unknown opcode
/tmp/ccuyfGW5.s:5247: Error: unknown opcode
/tmp/ccuyfGW5.s:5251: Error: unknown opcode
/tmp/ccuyfGW5.s:5255: Error: unknown opcode
/tmp/ccuyfGW5.s:5259: Error: unknown opcode
/tmp/ccuyfGW5.s:5263: Error: unknown opcode
/tmp/ccuyfGW5.s:5267: Error: unknown opcode
/tmp/ccuyfGW5.s:5271: Error: unknown opcode
/tmp/ccuyfGW5.s:5275: Error: unknown opcode
/tmp/ccuyfGW5.s:5279: Error: unknown opcode
/tmp/ccuyfGW5.s:5283: Error: unknown opcode
/tmp/ccuyfGW5.s:5287: Error: unknown opcode
/tmp/ccuyfGW5.s:5291: Error: unknown opcode
/tmp/ccuyfGW5.s:5295: Error: unknown opcode
EDIT
The problem was indeed related to stack corruption, but I'll let this question here to see if anyone knows the answer about how to get the disassembled code from a subroutine and put it back into a C function body for inlining.