public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* __declspec(naked) and function body size
@ 2007-12-08 15:01 Ilyes Gouta
  2007-12-08 19:46 ` Brian Dessent
  0 siblings, 1 reply; 5+ messages in thread
From: Ilyes Gouta @ 2007-12-08 15:01 UTC (permalink / raw)
  To: gcc-help

Hi,

I'd like to do the following thing under Linux using GCC.

/* __declspec(naked) is Microsoft's C compiler specific. */

__declspec(naked) int function1()
{
	/* dummy stub dumped by the JIT. */

	int a = 0, b = 1;
	int c = a + b;

	return (c);
}
__declspec(naked) void end_function1() {}

unsigned char t[256];

void main()
{
	/* I'd like to do the following, i.e copying code around. */
	memcpy(t, function1, end_function1 - function1);
}

Is it possible using GCC? If yes, could you please tell me how?

Best regards,
Ilyes Gouta.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: __declspec(naked) and function body size
  2007-12-08 15:01 __declspec(naked) and function body size Ilyes Gouta
@ 2007-12-08 19:46 ` Brian Dessent
  2007-12-08 21:58   ` Ilyes Gouta
  0 siblings, 1 reply; 5+ messages in thread
From: Brian Dessent @ 2007-12-08 19:46 UTC (permalink / raw)
  To: Ilyes Gouta; +Cc: gcc-help

Ilyes Gouta wrote:

> Is it possible using GCC? If yes, could you please tell me how?

There is __attribute__((naked)) but it's not supported for x86.  I think
the feeling is that gcc should be able to detect when a prologue is not
necessary on its own and just not emit it, and that forcably disabling
the prologue just results in horribly broken code if the function
happens to require a spill.  See also
<http://gcc.gnu.org/ml/gcc/2004-02/threads.html#00939>.

Brian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: __declspec(naked) and function body size
  2007-12-08 19:46 ` Brian Dessent
@ 2007-12-08 21:58   ` Ilyes Gouta
  2007-12-08 23:26     ` Brian Dessent
  0 siblings, 1 reply; 5+ messages in thread
From: Ilyes Gouta @ 2007-12-08 21:58 UTC (permalink / raw)
  To: gcc-help


Hi,

Thank you for your reply!

Is it possible to get the size of a function, i.e the number of bytes generated by the compiler between the prologue and 
the final routine's ret instruction, so that it would be available through a 'sizeof' like operator for the other code?

It would be possible to do,

int a = sizeof(some_function);

I'm not expecting the standard sizeof to do that, but I'm looking for possibly another operator or some proprietary GCC 
extensions. I'm writing a JIT for my simplified C language and I'd like to copy template code around and patch it when 
necessary (and not only emitting opcode by opcode in the code buffers).

BR,
Ilyes Gouta.

Brian Dessent wrote:
> Ilyes Gouta wrote:
> 
>> Is it possible using GCC? If yes, could you please tell me how?
> 
> There is __attribute__((naked)) but it's not supported for x86.  I think
> the feeling is that gcc should be able to detect when a prologue is not
> necessary on its own and just not emit it, and that forcably disabling
> the prologue just results in horribly broken code if the function
> happens to require a spill.  See also
> <http://gcc.gnu.org/ml/gcc/2004-02/threads.html#00939>.
> 
> Brian
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: __declspec(naked) and function body size
  2007-12-08 21:58   ` Ilyes Gouta
@ 2007-12-08 23:26     ` Brian Dessent
  2007-12-09  6:51       ` Ilyes Gouta
  0 siblings, 1 reply; 5+ messages in thread
From: Brian Dessent @ 2007-12-08 23:26 UTC (permalink / raw)
  To: Ilyes Gouta; +Cc: gcc-help

Ilyes Gouta wrote:

> Is it possible to get the size of a function, i.e the number of bytes generated by the compiler between the prologue and
> the final routine's ret instruction, so that it would be available through a 'sizeof' like operator for the other code?

You can do this at the assembler level:

int foo()
{
  int a = 0, b = 1;
  int c = a + b;

  return (c);
}

asm(".set foo_size, .-foo");
extern unsigned foo_size;                

int main()
{
  unsigned char buf[512];

  memcpy (buf, foo, foo_size);
}

There are two problems with this:

1. In unit-at-a-time mode (which is enabled by default when optimizing)
the compiler does not guarantee that functions and top-level asm
statements are emitted in the same order as specified in the input
source.  Since this technique requires that the asm() come immediately
after the function it refers to, this will break.  So you have to use
-fno-unit-at-a-time (for gcc < 4.2.0) or preferably
-fno-toplevel-reorder (for gcc >= 4.2.0) unless you use -O0.

2. The asm has to be adjusted if you want it to work on
leading-underscore targets.  For example on win32 you'd need to use
something like asm(".set _foo_size, .-_foo") instead.  I suppose you
could abstract this away with some macro junk:

#define ASMNAME(cname)          ASMNAME2 (__USER_LABEL_PREFIX__, cname)
#define ASMNAME2(prefix, cname) STRING (prefix) cname
#define STRING(x)               #x

// ...

asm(".set " ASMNAME("foo_size") ", .-" ASMNAME("foo"));
extern unsigned foo_size;

Brian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: __declspec(naked) and function body size
  2007-12-08 23:26     ` Brian Dessent
@ 2007-12-09  6:51       ` Ilyes Gouta
  0 siblings, 0 replies; 5+ messages in thread
From: Ilyes Gouta @ 2007-12-09  6:51 UTC (permalink / raw)
  To: gcc-help


Hi,

Thank you so much, Brian, for your help.
I'm going to try this out and see if it fits my requirements.

BR,
Ilyes Gouta.

Brian Dessent wrote:
> Ilyes Gouta wrote:
> 
>> Is it possible to get the size of a function, i.e the number of bytes generated by the compiler between the prologue and
>> the final routine's ret instruction, so that it would be available through a 'sizeof' like operator for the other code?
> 
> You can do this at the assembler level:
> 
> int foo()
> {
>   int a = 0, b = 1;
>   int c = a + b;
> 
>   return (c);
> }
> 
> asm(".set foo_size, .-foo");
> extern unsigned foo_size;                
> 
> int main()
> {
>   unsigned char buf[512];
> 
>   memcpy (buf, foo, foo_size);
> }
> 
> There are two problems with this:
> 
> 1. In unit-at-a-time mode (which is enabled by default when optimizing)
> the compiler does not guarantee that functions and top-level asm
> statements are emitted in the same order as specified in the input
> source.  Since this technique requires that the asm() come immediately
> after the function it refers to, this will break.  So you have to use
> -fno-unit-at-a-time (for gcc < 4.2.0) or preferably
> -fno-toplevel-reorder (for gcc >= 4.2.0) unless you use -O0.
> 
> 2. The asm has to be adjusted if you want it to work on
> leading-underscore targets.  For example on win32 you'd need to use
> something like asm(".set _foo_size, .-_foo") instead.  I suppose you
> could abstract this away with some macro junk:
> 
> #define ASMNAME(cname)          ASMNAME2 (__USER_LABEL_PREFIX__, cname)
> #define ASMNAME2(prefix, cname) STRING (prefix) cname
> #define STRING(x)               #x
> 
> // ...
> 
> asm(".set " ASMNAME("foo_size") ", .-" ASMNAME("foo"));
> extern unsigned foo_size;
> 
> Brian
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-12-09  6:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-08 15:01 __declspec(naked) and function body size Ilyes Gouta
2007-12-08 19:46 ` Brian Dessent
2007-12-08 21:58   ` Ilyes Gouta
2007-12-08 23:26     ` Brian Dessent
2007-12-09  6:51       ` Ilyes Gouta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).