digitalmars.D - Function size?
- Niall FitzGibbon (49/49) Feb 01 2005 Is there some way to get the length of a particular function in D?
- Walter (2/2) Feb 01 2005 Unfortunately, there is no straightforward way to make this work in D. L...
- Niall FitzGibbon (27/31) Feb 01 2005 Thanks for the swift reply, Walter. I know this kind of feature would
- Walter (7/38) Feb 01 2005 Let
Is there some way to get the length of a particular function in D? Perhaps as a property of the function? The reason I ask is that I'm trying to implement something similar to Microsoft Detours' ContinueWithDLL/CreateWithDLL in D, but in Detours they use static functions in order to get the size of the function that needs to be copied into the foreign memory context. They take the address of AfterThreadFunc and subtract the address of ThreadFunc in order to get the size of the code to be copied into the foreign process. I'm not sure if the "static" function attribute is part of Standard C++ or simply a MS/VC++ thing, but this kind of functionality, either through fixed-position functions or a "size" property that can be accessed through the function or a delegate to it, would be very useful. Perhaps D already places function code in declaration order in the resulting executable, though I haven't seen this behaviour described in the language spec? Here's a copy of the function declarations from MS Detours: /////////////////////////////////////////////////////////////// Injected Code. // #pragma check_stack(off) #pragma pack(push, 8) typedef HINSTANCE (WINAPI *PROCLOADLIBRARY)(PWCHAR); typedef struct { PROCLOADLIBRARY fnLoadLibrary; WCHAR wzLibFile[MAX_PATH]; } INJLIBINFO, *PINJLIBINFO; // Calls to the stack-checking routine must be disabled. static DWORD WINAPI ThreadFunc(PINJLIBINFO pInjLibInfo) { // There must be less than a page-worth of local // variables used in this function. HINSTANCE hinstLib; // Call LoadLibrary(A/W) to load the DLL. hinstLib = pInjLibInfo->fnLoadLibrary(pInjLibInfo->wzLibFile); return((DWORD) hinstLib); } #pragma warning(disable: 4702) static DWORD WINAPI DeadThreadFunc(PINJLIBINFO pInjLibInfo) { (void)pInjLibInfo; x: goto x; return 0; } // This function marks the memory address after ThreadFunc. // ThreadFuncCodeSizeInBytes = (PBYTE) AfterThreadFunc - (PBYTE) ThreadFunc. static void AfterThreadFunc (void) { } #pragma pack(pop) #pragma check_stack
Feb 01 2005
Unfortunately, there is no straightforward way to make this work in D. Let me think about it.
Feb 01 2005
Walter wrote:Unfortunately, there is no straightforward way to make this work in D. Let me think about it.Thanks for the swift reply, Walter. I know this kind of feature would hardly be used at all and its implementation would probably conflict with your code generation and optimisation procedures. I was kind of hoping that by some twist of luck or fate it was already possible within the current language in a way that I had overlooked :) If the symbol table output of DMD is in COFF format, I believe I know enough to be able to read the function beginning and end symbols from the debug section and use them to get the length of the function. I can then hopefully create an AA, indexed by function address (after taking relocation into account), that can be used to look up code length or other information given a pointer to the start of the function. Perhaps another method would be to add some inline asm after the function return, something very simple like this int func() { // function code return 1; asm { db "FUNCEND"; } } In this way I'd be able to scan forward from the function start address until the "signature" bytes in the inline asm at the very end of the function are found. However, I'm wondering if the code generator might optimise away any code following the final return statement of the function?
Feb 01 2005
"Niall FitzGibbon" <billdoor gmail.com> wrote in message news:ctplf4$22bt$1 digitaldaemon.com...Walter wrote:LetUnfortunately, there is no straightforward way to make this work in D.You can look at the beginning and end symbols by examining the linker .map file output (-L/map).me think about it.Thanks for the swift reply, Walter. I know this kind of feature would hardly be used at all and its implementation would probably conflict with your code generation and optimisation procedures. I was kind of hoping that by some twist of luck or fate it was already possible within the current language in a way that I had overlooked :) If the symbol table output of DMD is in COFF format, I believe I know enough to be able to read the function beginning and end symbols from the debug section and use them to get the length of the function. I can then hopefully create an AA, indexed by function address (after taking relocation into account), that can be used to look up code length or other information given a pointer to the start of the function.Perhaps another method would be to add some inline asm after the function return, something very simple like this int func() { // function code return 1; asm { db "FUNCEND"; } } In this way I'd be able to scan forward from the function start address until the "signature" bytes in the inline asm at the very end of the function are found. However, I'm wondering if the code generator might optimise away any code following the final return statement of thefunction? The asm thing should work. Give it a try.
Feb 01 2005