www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - get size of function

reply maarten van damme <maartenvd1994 gmail.com> writes:
--000e0cd14ab861b9f304abbaf7a7
Content-Type: text/plain; charset=ISO-8859-1

I'm playing around with writing memory to other processes and now I want to
write a whole function to the other processes memory. The problem is that
function.sizeof always returns 4. Is there a way to get the actual size?

--000e0cd14ab861b9f304abbaf7a7
Content-Type: text/html; charset=ISO-8859-1

I&#39;m playing around with writing memory to other processes and now I want to
write a whole function to the other processes memory. The problem is that
function.sizeof always returns 4. Is there a way to get the actual size?

--000e0cd14ab861b9f304abbaf7a7--
Aug 30 2011
next sibling parent Simon <s.d.hammett gmail.com> writes:
On 30/08/2011 16:50, maarten van damme wrote:
 I'm playing around with writing memory to other processes and now I want
 to write a whole function to the other processes memory. The problem is
 that function.sizeof always returns 4. Is there a way to get the actual
 size?

The short answer is no. You might find something useful in DDL: http://www.dsource.org/projects/ddl Though that looks like it hasn't been updated in ages. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Aug 30 2011
prev sibling next sibling parent reply Johannes Pfau <spam example.com> writes:
maarten van damme wrote:
I'm playing around with writing memory to other processes and now I
want to write a whole function to the other processes memory. The
problem is that function.sizeof always returns 4. Is there a way to
get the actual size?

Declare another function, make sure their located sequentially in memory and compare their function addresses to get the size of the first function (+ potential padding for alignment, but that shouldn't matter). I do not recommend to do this though, it's a baaaad hack, and I don't even remember how exactly it worked. -- Johannes Pfau
Aug 30 2011
parent Simon <s.d.hammett gmail.com> writes:
On 31/08/2011 15:42, Johannes Pfau wrote:
 Trass3r wrote:
 Am 31.08.2011, 12:05 Uhr, schrieb maarten van damme
 <maartenvd1994 gmail.com>:

 Am I sure those functions aren't shift around during optimization?

No. It's just an ugly hack and likely to go up in flames. Also what you try could only work with PIC but even then...

That's true, as I already said it for sure is an ugly hack. There's no guarantee that the compiler outputs the functions in this order. The linker could change the order as well. And if you send this function to another process (or even a different machine), you might get even more issues (for example some kind of offset calculated by the compiler and "hard-coded" into the function could be wrong in the other process). The Linux kernel does some tricks to store 'dynamic' lists in ELF files. For this to work it also needs access to the size of the list. You could use a similar approach: You'd have to write your own linker script to put your function in an own sections, than output 2 symbols exactly before and after the function. But that's a lot of work and I personally think that's still an ugly hack. It's used in the Linux kernel however, so it has to work. DMD also uses a similar trick with the _deh_beg and _deh_end symbols, maybe dmd does something to make that mechanism less fragile, you could look it up in the compiler source.

Then you will run into problems with data execution prevention, so you'll have to write OS specific code for each platform to run the code. The easiest and most portable way to export runnable code is use an interpreted language. After that you could look at llvm, but there's no D interface to that. All in all, it's a big messy can of worms you are trying to open. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Aug 31 2011
prev sibling next sibling parent maarten van damme <maartenvd1994 gmail.com> writes:
--000e0cd29e266d0c7f04abc184eb
Content-Type: text/plain; charset=ISO-8859-1

2011/8/30 Johannes Pfau <spam example.com>

 You could use the same hacks as in C:
 Declare another function, make sure their located sequentially in
 memory and compare their function addresses to get the size of the first
 function (+ potential padding for alignment, but that shouldn't matter).

functions address. how can I make sure they're sequentially alligned?
 I do not recommend to do this though, it's a baaaad hack, and I don't
 even remember how exactly it worked.

I've also been playing with the idea of writing the function, and trying to compile that one function in a text file and importing at compile time in my main program. Then I can also count the bytes in the file. sounds an awfull lot of work :p --000e0cd29e266d0c7f04abc184eb Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">2011/8/30 Johannes Pfau <span dir=3D"ltr= ">&lt;<a href=3D"mailto:spam example.com">spam example.com</a>&gt;</span><b= r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:= 1px #ccc solid;padding-left:1ex;"> <div class=3D"im"> </div>You could use the same hacks as in C:<br> Declare another function, make sure their located sequentially in<br> memory and compare their function addresses to get the size of the first<br=

.<br></blockquote><div>I think thats the way to go, a sequential function&#= 39;s adress minus the functions address. how can I make sure they&#39;re se= quentially alligned?<br> =A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8= ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> I do not recommend to do this though, it&#39;s a baaaad hack, and I don&#39= ;t<br> even remember how exactly it worked.<font color=3D"#888888"><br></font></bl= ockquote><div>=A0But better a (dirty) way then no way at all.<br><br>I&#39;= ve also been playing with the idea of writing the function, and trying to c= ompile that one function in a text file and importing at compile time in my= main program. Then I can also count the bytes in the file.<br> sounds an awfull lot of work :p<br></div></div><br> --000e0cd29e266d0c7f04abc184eb--
Aug 30 2011
prev sibling next sibling parent maarten van damme <maartenvd1994 gmail.com> writes:
--000e0cd22f760d07b404abc8bad3
Content-Type: text/plain; charset=ISO-8859-1

substracting the pointers to two sequential functions didn't work out. the
following snippet:
//
auto first=function void(){
asm{
naked;
nop;
}
};
auto next=function void(){
asm{
naked;
nop;
}
};
writeln(cast(int)&next-cast(int)&first,"/",cast(int)&next,"/",&next,"/",cast(int)&first,"/",&first);
//
outputs
4/1244672/12FE00/1244668/12FDFC
so the conversions from hex to int work correctly and I still get a size of
4 while it shouldve been a size of 1.
Are there other options?

--000e0cd22f760d07b404abc8bad3
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

substracting the pointers to two sequential functions didn&#39;t work out. =
the following snippet:<div>//<br><div><div>auto first=3Dfunction void(){</d=
iv><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">		</span>a=
sm{</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">			</span>nak=
ed;</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">			<=
/span>nop;</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pr=
e">		</span>}</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space: pre; ">	</span>};=
</div><div>auto next=3Dfunction void(){</div><div><span class=3D"Apple-tab-=
span" style=3D"white-space: pre; ">	</span>asm{</div><div><span class=3D"Ap=
ple-tab-span" style=3D"white-space:pre">		</span>naked;</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">		</span>nop;=
</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">		</spa=
n>}</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</s=
pan>};</div>
<div><span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>write=
ln(cast(int)&amp;next-cast(int)&amp;first,&quot;/&quot;,cast(int)&amp;next,=
&quot;/&quot;,&amp;next,&quot;/&quot;,cast(int)&amp;first,&quot;/&quot;,&am=
p;first);</div>
</div></div><div>//</div><div>outputs=A0</div><div>4/1244672/12FE00/1244668=
/12FDFC</div><div>so the conversions from hex to int work correctly and I s=
till get a size of 4 while it shouldve been a size of 1.</div><div>Are ther=
e other options?</div>

--000e0cd22f760d07b404abc8bad3--
Aug 31 2011
prev sibling next sibling parent Johannes Pfau <spam example.com> writes:
maarten van damme wrote:
substracting the pointers to two sequential functions didn't work out.
the following snippet:
//
auto first=function void(){
asm{
naked;
nop;
}
};
auto next=function void(){
asm{
naked;
nop;
}
};
writeln(cast(int)&next-cast(int)&first,"/",cast(int)&next,"/",&next,"/",cast(int)&first,"/",&first);
//
outputs
4/1244672/12FE00/1244668/12FDFC
so the conversions from hex to int work correctly and I still get a
size of 4 while it shouldve been a size of 1.
Are there other options?

In your example next & first are function pointers and function pointers have a size of 4 (on a 32bit system). This seems to work: ----------------------------- int first(int a, int b) { return a - b; } int next(int a, int b) { return a + b; } void main(string args[]) { writeln(cast(int)&next-cast(int)&first,"/",cast(int)&next,"/",&next,"/",cast(int)&first,"/",&first); } ----------------------------- Output: 20/134772104/8087588/134772084/8087574 As next and first in your example should already be pointers, you could also try to change your writeln to this: writeln(cast(int)next-cast(int)first,"/",cast(int)next,"/",next,"/",cast(int)first,"/",first); BTW: Why not cast to void* (or at least size_t) instead of int? -- Johannes Pfau
Aug 31 2011
prev sibling next sibling parent maarten van damme <maartenvd1994 gmail.com> writes:
--000e0cd14ab8170d0804abca4497
Content-Type: text/plain; charset=ISO-8859-1

I always cast everything to ints that I use in calculations, a (bad) habit
of me.size_t makes more sense.
your example seems to work great, thank you.
I forgot I was using function pointers.
Am I sure those functions aren't shift around during optimization?

for now the function is working like a charm. int memory I can see that d
makes function size's multiples of four and fills the remaining bytes with
cc's. is this coincidence and if not, why is this?

--000e0cd14ab8170d0804abca4497
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I always cast everything to ints that I use in calculations, a (bad) habit =
of me.size_t makes more sense.<div>your example seems to work great, thank =
you.</div><div>I forgot I was using function pointers.</div><div>Am I sure =
those functions aren&#39;t shift around during optimization?</div>
<div><br></div><div>for now the function is working like a charm. int memor=
y I can see that d makes function size&#39;s multiples of four and fills th=
e remaining bytes with cc&#39;s. is this coincidence and if not, why is thi=
s?</div>

--000e0cd14ab8170d0804abca4497--
Aug 31 2011
prev sibling next sibling parent Trass3r <un known.com> writes:
Am 31.08.2011, 12:05 Uhr, schrieb maarten van damme  
<maartenvd1994 gmail.com>:

 Am I sure those functions aren't shift around during optimization?

No. It's just an ugly hack and likely to go up in flames. Also what you try could only work with PIC but even then...
 for now the function is working like a charm. int memory I can see that d
 makes function size's multiples of four and fills the remaining bytes  
 with
 cc's. is this coincidence and if not, why is this?

http://stackoverflow.com/questions/2863408/why-are-functions-loaded-at-aligned-addresses-in-x86-linux-for-elf-executables
Aug 31 2011
prev sibling parent Johannes Pfau <spam example.com> writes:
Trass3r wrote:
Am 31.08.2011, 12:05 Uhr, schrieb maarten van damme  
<maartenvd1994 gmail.com>:

 Am I sure those functions aren't shift around during optimization?

No. It's just an ugly hack and likely to go up in flames. Also what you try could only work with PIC but even then...

That's true, as I already said it for sure is an ugly hack. There's no guarantee that the compiler outputs the functions in this order. The linker could change the order as well. And if you send this function to another process (or even a different machine), you might get even more issues (for example some kind of offset calculated by the compiler and "hard-coded" into the function could be wrong in the other process). The Linux kernel does some tricks to store 'dynamic' lists in ELF files. For this to work it also needs access to the size of the list. You could use a similar approach: You'd have to write your own linker script to put your function in an own sections, than output 2 symbols exactly before and after the function. But that's a lot of work and I personally think that's still an ugly hack. It's used in the Linux kernel however, so it has to work. DMD also uses a similar trick with the _deh_beg and _deh_end symbols, maybe dmd does something to make that mechanism less fragile, you could look it up in the compiler source. -- Johannes Pfau
Aug 31 2011