2

I need to keep some information about each function in my program in the form of a constant number. I was wondering if it is possible to put the constant for a function just before it in the code memory, so if a function is called through a function pointer, that information could be read by subtracting the value of the function pointer.

To illustrate further, my code memory should look as follows.

ConstantForFunc1
Func1:
 ....

ConstantForFunc2
Func2:
 ....

And following is an example code of how I would read that information

FuncPointer f = &Func2;
int constantForFunc2 = *((int*)(f - sizeof(int)));

And note that using Hash tables is too slow for what I'm trying to achieve, so I need a very fast method. And all this modification, which is inserting constants and code to read from them is done by a compiler pass, which I'm writing and which modifies the LLVM IR. Using structures would be too cumbersome for the compiler pass, as it would have to modify a lot of code.

13
  • 7
    What. No. You need to describe a problem instead of describing a solution. Commented Feb 1, 2013 at 13:32
  • 1
    I don't think you can do this in a portable way. Also, why - 4? And do you have in mind, that pointers can have different sizes? Commented Feb 1, 2013 at 13:33
  • 1
    The only case where code like this would make any sense whatsoever is perhaps when writing embedded bootloaders or non-volatile memory programming algorithms. Is that what you are doing? Commented Feb 1, 2013 at 13:34
  • 1
    Compilers will optimize the layout so putting a constant before a function in a code file doesn't guarantee it will be there in the compiled binary. Commented Feb 1, 2013 at 13:37
  • 5
    Typical "XY" question, you have a problem, X, which you think should be solved by doing Y, so you ask how to do Y. Describe what you are actually trying to achieve, and we can probably help. Commented Feb 1, 2013 at 13:37

3 Answers 3

6

What you are doing doesn't make sense, yet:

You could use structs maybe?

struct example
{
  int constantForFunc;
  void (*ptrToFunc)();
};

//After declaring, maybe 3, functions

struct example funcList[3] = {{5, &func1}, {10, &func2}, {15, &func3}};

int currentFuncConstant=funcList[1].constantForFunc;
(*funcList[1].ptrToFunc)();

I haven't used function pointers to be honest, probaby has mistakes.

Sign up to request clarification or add additional context in comments.

9 Comments

I was thinking something like that too.
Ya but that requires a lot of change to the code, and I'm writing a compiler pass. It would be difficult to write a compiler pass that modifies the code so much.
And a searchable data structure either containing constants or pointing to them. The function pointer would be the key/index into the structure.
Alexey, Yes hash could be used, but hashing is slow for what I'm trying to achieve.
In your case the key is already a number. So you may use something extremely simple like func % 1000 or even func << N >> N as a hash function. It gets some last digits of your func address. If fucntions are closely located, then collisions are not very probable.
|
0

Is this not acceptable at all?:

#include <iostream>

using namespace std;

const int Const__Fxn1 = 1;
void Fxn1()
{
  cout << "Fxn1" << endl;
}

const int Const__Fxn2 = 2;
void Fxn2()
{
  cout << "Fxn2" << endl;
}

#define GetFxnConst(FxnName) Const__ ## FxnName

int main()
{
  cout << GetFxnConst(Fxn1) << endl;
  cout << GetFxnConst(Fxn2) << endl;
  return 0;
}

Option 2:

#include <iostream>
#include <cstring>

using namespace std;

const volatile int v1 = 0;
volatile unsigned v2 = 0;

void Fxn1()
{
  if (v1) { v2 = 0x12345601; }
  cout << "Fxn1" << endl;
}

void Fxn2()
{
  if (v1) { v2 = 0x12345602; }
  cout << "Fxn2" << endl;
}

int FindFxnConst(void(*f)())
{
  const unsigned char* p = (const unsigned char*)f;
  while (memcmp(p, "\x56\x34\x12", 3))
    p++;
  return p[-1];
}

int main()
{
  Fxn1();
  cout << FindFxnConst(Fxn1) << endl;
  Fxn2();
  cout << FindFxnConst(Fxn2) << endl;
  return 0;
}

Output (Ideone):

Fxn1
1
Fxn2
2

You can embed more than 8 bits of data per function by using other magic prefixes, e.g.:

  if (v1)
  {
    v2 = 0x12345611; // byte 1
    v2 = 0x789ABC22; // byte 2
    v2 = 0xDEF01233; // byte 3
    v2 = 0xFEDCBA44; // byte 4
  }

This is not necessarily a reliable solution, let alone portable.

2 Comments

Actually my solution should work for function pointers. With function pointers, you don't have the name of the function, just its address.
Got it. But if you keep names for long enough, this could work. The thing is, at one point you get function addresses from function names anyway.
0

Since the addresses of the functions are known from the executable binary (unless they are loaded from a shared library ofcourse), if you have the address space layout randomization (ASLR) off, you could use gperf to generate a highly efficient hash function for you and use that hash function to get the constants for each function.

However, for this, you will have to compile your program twice, first to get the addresses of the functions from the generated binary, so that you could give those addresses as an input to gperf and recompile using the hash function generated by gperf. But you have to be careful that the addresses of the functions from the first compilation do not become different in the second compilation. I am not sure, how to achieve that.

An alternative, would be to do something like gperf just after your program is loaded, so you don't have to compile twice. But I don't know how to do that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.