2

I am trying out a C program. I have a c subroutine sub defined in a file sub.c as follows:

int sub (int a, int b)
{
   return a + b;
}

I compile this file and produce an object file sub.o.

I want to call the subroutine sub that sits in sub.o from my main subroutine that is defined in another file named main.c.

Normally I'd do it just as follows:

int main ()
{
   int r = sub(10, 20);
   printf("result = %d\n", r);
   return 0;
}

and then compiling as below: gcc -o main main.c sub.o

What I want to do is be able to call the subroutine sub by directly reading its code from the object file sub.o at runtime. I know I can use shared object based solution. But is there a way which does not require me to implement a full support for shared object and still allows me to load the code from an object file to some place in RAM and execute it by jumping to that location? In short I am looking for some sort of quickfix that allows me to do this.

I know objdump allows me to extract the executable code from the .o file but I don't what to do with it later. Any help or pointers in right direction are welcome.

Note: I want to do this on any Linux based system in user space.

Tem Pora
  • 2,043
  • 2
  • 24
  • 30
  • 1
    You can compile `sub.c` into a *shared object*, and use e.g. [`dlopen`](http://man7.org/linux/man-pages/man3/dlopen.3.html) and [`dlsym`](http://man7.org/linux/man-pages/man3/dlsym.3.html) to read the shared object file and get the function pointer. Do a search on "shared object" and "dlopen" to find examples on how to do it. – Some programmer dude Aug 15 '14 at 10:21
  • you need dynamic linked library? like what joachim said above – askmish Aug 15 '14 at 10:21
  • The problem with the quick-fix is that you're skipping segment allocation and pointer relocation that happen when you load a shared object and - worse! - downstream linking from that object into any dependencies. Which is fine in simple examples such as yours that don't need them, but once you've got more complex code you're going to run into issues. If you really do want to do this for non-trivial cases you may be able to use some of the libraries from binutils to help you and process object formats - but I'd advise against really. – Rup Aug 15 '14 at 10:22
  • 1
    @JoachimPileborg I have clearly mentioned that I know a shared object (`dlopen`) based solution. I am looking for something else. – Tem Pora Aug 15 '14 at 10:26
  • @Rup At this moment tThe quick-fix I am looking for is for simpler routines only. There is no downstream linking involved at lest for now. Can you give some example? – Tem Pora Aug 15 '14 at 10:28
  • And there is really nothing else. An plain object file can only be used for one thing: To link into a finished application, or into a shared object/library. Don't try to use it for something it's not intended for, that will only cause you problems. – Some programmer dude Aug 15 '14 at 10:29
  • Sorry, I've never done it. But you'd need to 1) allocate [some memory that is executable](http://stackoverflow.com/questions/3125756/allocate-executable-ram-in-c-on-linux) 2) read the object file into that memory as binary data (fine with the standard APIs) 3) locate the function call within the object format (don't know, sorry - you'd have to read the docs or use a library e.g. from binutils) 4) create a function pointer to the right place, with the right signature and calling convention, and invoke it in your code. – Rup Aug 15 '14 at 10:31
  • You may also be able to load the object with [mmap](http://stackoverflow.com/questions/6231486/injecting-code-into-executable-at-runtime) if you mark the segment executable on mapping, but not all filesystems support mmapping. – Rup Aug 15 '14 at 10:32
  • Regarding the method from @Rup's comments, you should know that this will only work for *very* simple code, and that to mark memory as executable you will probably need to have super-user privileges (and that will open you up to all kinds of security issues). Almost anything more complicated than the `sub` function you use, and you basically have to implement a complete static *and* runtime linker, with all their complexities. – Some programmer dude Aug 15 '14 at 10:39
  • @Joachim Thanks - I didn't know you needed privs to mark memory executable. But yes, I agree this is for trivial cases only as I said. – Rup Aug 15 '14 at 10:50
  • 1
    Please share why you want to do this, as this may give essential clues towards a good solution. – meaning-matters Aug 15 '14 at 11:13
  • WTF is "implement full support for shared object" you just add the -shared flag -there is no "implementation", its already there and that is as "full" as you need for dlopen to work, then its `dlopen()`, `dlsym()`, `git-r-done`, and optionally `dlclose()` – technosaurus Aug 15 '14 at 11:53
  • @technosaurus I think, you have not understood the question. And what do you mean by "there is no implementation"? Note well that someone has implemented it for you. – Tem Pora Aug 15 '14 at 19:44
  • @meaning-matters sometimes the overheads of `dlopen` etc can be too much and I am trying to run some programs on an embedded device where some such `simple` subroutines will be added later at runtime. p-code based another solution I have tried, but it also is more overheads. – Tem Pora Aug 15 '14 at 19:48
  • 1
    Then you may _actually_ want this: http://stackoverflow.com/a/12139145 and maybe consider using flat binary format vs elf – technosaurus Aug 16 '14 at 10:37
  • @technosaurus Thank you very much for directing me to that answer. I will give it it a try. – Tem Pora Aug 16 '14 at 11:29

0 Answers0