1

Is there any index-based table in the program that stores metadata for each function in the executeable? I need to attach pointer to every function pointer given; For example:

if (!HasMetadata(functionPointer)) //Something of the form ...(*)(...)
    SetMetadata(new FunctionMetadata()); //Pointer of object of some structure of data
((FunctionMetadata*)GetMetadata(functionPointer))->Counter++;

NOTE: I considered using object from key/value type; I can't because I have more than 3000+ functions, which potentially all of them need to be in the table. If I hadn't 3000+ functions, then I would manually consider adding static value for each function.

LyingOnTheSky
  • 2,844
  • 1
  • 14
  • 33
  • What part of it is unclear? – LyingOnTheSky Nov 29 '14 at 16:39
  • What's the problem with having a map (or hash) with 3000+ key/value pairs ? – Félix Cantournet Nov 29 '14 at 16:46
  • @FélixCantournet Very slow(?). It's kind of self-modifying code; I must excessively use it. – LyingOnTheSky Nov 29 '14 at 16:58
  • I don't think it's in any way clear that a map or hash would be prohibitively slow. This seems like a bit of premature optimization if you ask me. Why not abstract the function metadata access as your code shows and try a map/hash based implementation? It's by far the simplest and if it works, you'll save yourself a lot of effort. If not, you might try something else like wrapping the functions in a class or struct that contains a pointer to the metadata, but I would imagine that would be far more work. – jjm Nov 29 '14 at 17:55
  • That's a tricky situation. A tree based map (which std::map is) does give you performance guarantees that are suitable for real time stuff (that is, it's *always* going to take k*log(n) steps for some k). But other than doing that or wrapping functions in objects, there's not much you can do short of horrifying unportable hacks, like stealing some high bits from the pointer or (such horror) placing a pointer to the metadata inside the function by manipulating it's code. But the bottom line is that a function pointer is just a pointer, and it doesn't have extra room for anything else. – jjm Nov 29 '14 at 21:12
  • 1
    @jjm I like horrifying codes; I think I've got an idea. Thanks I will be back when I am done. – LyingOnTheSky Nov 29 '14 at 21:22
  • @LyingOnTheSky Haha, let me know what you come up with, I like horrifying code too, I just try not to use it at work :-) – jjm Nov 29 '14 at 21:34
  • 1
    @jjm I need help here :(; [evil code ahead] http://pastebin.com/VQ0rPQ5r, this code in debug mode outputs `TestFunction` and `TestFunction` because the actual function pointer in debug mode is just `jmp` to the function. If you uncomment those two lines in `GetMetadata`, then it will throw read violation :(. Do you have any alternative to `VirtualProtect` that works with `.code` segments? Or is this just impossible? – LyingOnTheSky Nov 29 '14 at 23:24
  • @LyingOnTheSky I think what you are doing wouldn't be faster then wrapping your function pointers in objects with metadata as members. Anyway it does sound like premature optimization which is the root of all evil. Also a hashmap would provide amortized constant-time lookups. Depending on the constraints of your system the performance might actually not be that bad. (i.e how much time do the functions actually take to run, how often do you need to access the metadata etc..) You don't provide enough information to assess the performance issues. – Félix Cantournet Nov 29 '14 at 23:52
  • @LyingOnTheSky I don't know much about the windows api, but you will have to do something to make the page the function is on writeable if you want to manipulate it. You will probably want to make it readonly again when you're done too. What I was thinking was more along the lines of prepending a jmp to skip one pointer size and then having a pointer to your data in the instructions skipped by the jmp. The tricky part of course, is to do this without relocating the function :( – jjm Nov 29 '14 at 23:57
  • Oh, thought of something else: in debug mode, the debugger is going to be modifying your code in ways that might break this strategy. – jjm Nov 29 '14 at 23:58
  • This sounds like an XY problem. What meta data are you referring to? Where is this meta data coming from, how is it being loaded, and how do you expect to get direct and fast access to it? I think you need to revisit your reasoning and goals and definitely rethink why you believe this is even a good idea. Since the compiler is unlikely to provide any type of unique and sequential identifier for the functions you're best bet if you want to move forward is going to be using `std::map`. Also, your code on pastebin is **not** going to work, _ever_. – Captain Obvlious Nov 29 '14 at 23:59
  • Also calling VirtualProtect probably involves going into kernel mode and all of the overhead associated with that... – jjm Nov 29 '14 at 23:59

1 Answers1

-1

C++ has no intrinsic metadata attached to functions, classes or instances. However, there are several libraries available that, with some discipline, allow you to add metadata to various things. See this stackoverflow question, amongst others.

For your purposes it may suffice to have a sort of global map between function pointers and their metadata. For example,

// we'll use a generic function pointer as the key type for functions.  Note that things will 
// be somewhat trickier should you want to work with virtual functions or instance 
//members.

typedef void(*)() FunctionPtr;

static std::map<FunctionPtr, Metadata *> gFunctionMetadata;

Metadata *GetMetadata(FunctionPtr functionPtr){
   return gFunctionMetadata[functionPtr];
}

A prettier solution would of course be to have a singleton class (MetadataManager or some such) which contains the map and provides methods to access the metadata..

Community
  • 1
  • 1
jjm
  • 6,028
  • 2
  • 24
  • 27