title: How to inline a function from libc with gcc?
body: <p>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.</p>
  
  <p>However, my stack trace is something like:</p>
  
  <pre><code>memset
  memset
  memset
  memset
  memset
  memset
  memset
  memset
  </code></pre>
  
  <p>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.</p>
  
  <p>So, is there a way to inline memset? Does anyone have any other idea about debugging this problem?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I've already tried to replace memset with a dumb implementation using a <strong>for</strong>, but this made my software behave strangely and other problems appear that prevents me from getting to the deadlock.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>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:</p>
  
  <pre><code>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 &lt;.L_dup_bytes+0x18&gt;");
      asm("add    r4,r6");
      asm("tst    #3,r0");
      asm("bt.s   18 &lt;.L_dup_bytes&gt;");
      asm("extu.b r5,r5");
      asm("mov.b  r5,@r0");
      asm("add    #1,r0");
      asm("tst    #3,r0");
      asm("bf 10 &lt;_memset+0x10&gt;");
  }
  
  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 &lt;memset+48&gt;");
      asm("add    r4,r6");
      asm("tst    #3,r0");
      asm("bt.s   0x81636814 &lt;memset+24&gt;");
      asm("extu.b r5,r5");
      asm("mov.b  r5,@r0");
      asm("add    #1,r0");
      asm("tst    #3,r0");
      asm("bf 0x8163680c &lt;memset+16&gt;");
      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 &lt;memset+36&gt;");
      asm("add    #8,r0");
      asm("add    #16,r6");
      asm("cmp/eq r6,r0");
      asm("bt 0x81636838 &lt;memset+60&gt;");
      asm("mov.b  r5,@r0");
      asm("add    #1,r0");
      asm("cmp/eq r6,r0");
      asm("bf 0x81636830 &lt;memset+52&gt;");
      asm("rts    ");
      asm("mov    r4,r0");
  }
  </code></pre>
  
  <p>This gave me the following errors:</p>
  
  <p>First memset:</p>
  
  <pre><code>/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
  </code></pre>
  
  <p>Second memset:</p>
  
  <pre><code>/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
  </code></pre>
  
  <p>Can someone help with those errors?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Tried another version with the source code from :</p>
  
  <pre><code>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");
  }
  </code></pre>
  
  <p>Here are the errors this time:</p>
  
  <pre><code>/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
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>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.</p>