Re: detect empty functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 5, 2014 at 8:00 PM, Prathamesh Kulkarni
<bilbotheelffriend@xxxxxxxxx> wrote:
> On Wed, Feb 5, 2014 at 7:33 PM, vijay nag <vijunag@xxxxxxxxx> wrote:
>> On Wed, Feb 5, 2014 at 7:33 PM, vijay nag <vijunag@xxxxxxxxx> wrote:
>>> Hello,
>>>
>>> You can use the below program to find the length of the function
>>> compiled for X86 target.
>>>
>>> Note that assembly instruction for "function()" is immediately
>>> followed by assembly for "functionEnd"
>>>
>>> Key things to note here
>>>
>>> 1) Compiler still emits epilogue/prologue for a function with empty
>>> body. However you could disable this using -fomit-frame-ptr in which
>>> case function
>>>     body will only have "ret" instruction and in which case difference
>>> would be 1.
>>>     0x80483a4 <function>            ret
>>>
>>>                                    │
>>>    │0x80483a5 <functionEnd>         ret
>>>
>>>    So size of the function would be 0x80483a5 - 0x80483a4 = 1
>>>
>>>  2)In case if you need frame-ptr, there will be a minimum of 4
>>> instructions and in this case difference would be 5.
>>>     0x80483a4 <function>            push   %ebp
>>>
>>>                                    │
>>>    │0x80483a5 <function+1>          mov    %esp,%ebp
>>>
>>>                                    │
>>>    │0x80483a7 <function+3>          pop    %ebp
>>>
>>>                                    │
>>>    │0x80483a8 <function+4>          ret
>>>
>>>                                    │
>>>    │0x80483a9 <functionEnd>         push   %ebp
>>>
>>>                                    │
>>>    │0x80483aa <functionEnd+1>       mov    %esp,%ebp
>>>
>>>                                    │
>>>    │0x80483ac <functionEnd+3>       pop    %ebp
>>>
>>>                                    │
>>>    │0x80483ad <functionEnd+4>       ret
>>>
>>>      So size of the function would be 0x80483a9 - 0x80483a4 = 5
>>>
>>>
>>> cat fsize.c
>>> #include <stdio.h>
>>>
>>> int function(){
>>> }
>>>
>>> int functionEnd(){
>>> }
>>>
>>> int main()
>>> {
>>>   printf("%x\n", &functionEnd - &function);
>>> }
>>>
>>> vijayNag
>>>
>>> On Wed, Feb 5, 2014 at 7:00 PM, Prathamesh Kulkarni
>>> <bilbotheelffriend@xxxxxxxxx> wrote:
>>>> Hi, is there a way to find if a function has empty body ?
>>>>
>>>> Thanks and Regards,
>>>> Prathamesh
>>
>> My apologies for top-posting.
> I wanted to ask, is there a way to detect if a function has empty body
> using GCC API ?
> Sorry if I didn't phrase it correctly earlier.

Hello Prathamesh,

I do not know if GCC provides one to find if a function is empty or
not. You can extend the above logic and write a function to find if a
function has body or not. I have written a small function below called
"isFuncEmpty()". This function returns true if function has no body.
Note that I'm parsing instruction op-codes and that makes it
machinedependent(__i386__ in my case).  This function works even if
frame pointers to function is omitted by the compiler. Same logic can
be extended to any other platform by parsing preamble to the function.

#include <stdio.h>

#ifdef __i386__

typedef enum X86_OPCODES {
  X86_OPCODE_PUSH_EBP = 0x55,
  X86_OPCODE_MOV_ESP_EBP = 0xe589,
  X86_OPCODE_POP_EBP = 0x5d,
  X86_OPCODE_RETURN_INS = 0xc3,
  X86_OPCODE_MAX = 0xff,
} X86_OPCODES;

int function()
{
}

int functionEnd()
{
  int a;

  printf("Function with a body\n");
}

int isFuncEmpty(void *funcAddr)
{
  //prologue 0x5de58955
   const int prologue = (X86_OPCODE_POP_EBP << 24 |
X86_OPCODE_MOV_ESP_EBP << 8 | X86_OPCODE_PUSH_EBP);
   const int epilogue =  X86_OPCODE_RETURN_INS;
   unsigned long opcode = *(unsigned long*)funcAddr;
   unsigned char nxtOpcode = *(char*)((unsigned long*)funcAddr+1);

   /*
    * if frame-ptr exists then check for epilogue/prologue seq
    * else check for ret as the first ins
    */
   return ((X86_OPCODE_RETURN_INS) == (opcode & 0xff)) ? 1
:((opcode==prologue)&&(nxtOpcode == epilogue)) ? 1 : 0;
}

#elif /*__i386__ */
int isFuncEmpty(void *funcAddr)
{
   /*add logic for any other platform and return false or assert for now */
    return 0;
}
#endif

int main()
{
  if(isFuncEmpty(&function)) {
    printf("function() is empty\n");
  } else {
    printf("function() is not empty\n");
  }
  if (isFuncEmpty(&functionEnd)) {
    printf("functionEnd() is empty\n", isFuncEmpty(&functionEnd));
  } else {
    printf("functionEnd() is not empty\n");
  }
}





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux