digitalmars.D.learn - get size of function
- maarten van damme (3/3) Aug 30 2011 I'm playing around with writing memory to other processes and now I want...
- Simon (8/12) Aug 30 2011 The short answer is no.
- Johannes Pfau (9/13) Aug 30 2011 You could use the same hacks as in C:
- maarten van damme (8/14) Aug 30 2011 I think thats the way to go, a sequential function's adress minus the
- maarten van damme (22/22) Aug 31 2011 substracting the pointers to two sequential functions didn't work out. t...
- Johannes Pfau (26/48) Aug 31 2011 Do you need to use function _pointers_?
- maarten van damme (8/8) Aug 31 2011 I always cast everything to ints that I use in calculations, a (bad) hab...
- Trass3r (5/10) Aug 31 2011 No. It's just an ugly hack and likely to go up in flames.
- Johannes Pfau (19/24) Aug 31 2011 That's true, as I already said it for sure is an ugly hack. There's no
- Simon (10/34) Aug 31 2011 Then you will run into problems with data execution prevention, so
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?
Aug 30 2011
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
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?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). 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
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).I think thats the way to go, a sequential function's adress minus the 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.But better a (dirty) way then no way at all. 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
Aug 30 2011
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?
Aug 31 2011
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?Do you need to use function _pointers_? 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
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?
Aug 31 2011
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
Trass3r wrote:Am 31.08.2011, 12:05 Uhr, schrieb maarten van damme <maartenvd1994 gmail.com>: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 PfauAm 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...
Aug 31 2011
On 31/08/2011 15:42, Johannes Pfau wrote:Trass3r wrote: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.ukAm 31.08.2011, 12:05 Uhr, schrieb maarten van damme <maartenvd1994 gmail.com>: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.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...
Aug 31 2011