0

I am trying to wrap the GLIBC math functions including summation, division, multiplication, Cosine, log, and etc. I found a similar post here.

I have created a wrapper script for the log function in which prints something before calculation. Something like this for log function:

#include <dlfcn.h>
#include <stdio.h>
#include <math.h>

static double (*real_log)(double dbl);

double log(double dbl)
{
    printf("value is %0.16f\n" , dbl);
    real_log = dlsym(RTLD_NEXT, "log");
    real_log(dbl);
}

And the test file is something like this:

#include <stdio.h>
#include <math.h>

int main () {
    double var;
    var = log(2.7);
    printf("log is equal to %0.16f\n" , var);
    return 0;
}

I have re-compiled the wrapper to create the shared library by this command: gcc -fPIC -shared -o libpreload.so wrapper.c -ldl.

I compiled test file: gcc -fno-builtin-log test.c -o test -lm.

Then I run my test script using: LD_PRELOAD=/path/to/libpreload.so ./test

The output now prints

value is 2.7000000000000002
log is equal to 0.0000000000000000

The log returns zero value while I expect to get the real calculation like this:

value is 2.7000000000000002
log is equal to 0.9932517730102834

I'm so beginner on C programming and also Glibc functionality. I would appreciate any ideas.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
Ali Salari
  • 29
  • 4
  • “[I]t doesn't work” is not an adequate problem description. Edit the question to show a [mre], including the commands used to compile and execute. Also be aware that a compiler may replace calls to library functions with inline code unless you turn off this feature. For further information on what you are trying to do, search for “interposition.” – Eric Postpischil May 26 '20 at 20:36
  • Try adding something like `printf("my log()\n");` at the top to see if the runtime link editor resolves callers to your routine. To print a double value, try `printf("dbl %g\n", dbl);` or similar; note that `print()` (no 'f') is likely unresolved. Also the line `log(dbl)` would call itself, not resolve to `log()` in another library. – Milag May 26 '20 at 20:53
  • @EricPostpischil Thanks for your comment, I've edited the post now. @Milag Thanks for your answer. Actually test.c doesn't run log from the shared library that I linked in `LD_PRELOAD` at all! – Ali Salari May 26 '20 at 21:06
  • i dont think this is possible since glibc contains so much required stuff, the normal way to do this is via #defines that replace log by my_log – pm100 May 26 '20 at 21:08
  • @pm100 Thanks for your response. Could you please elaborate on how is #defines work? or suggest me a related web-link to read. – Ali Salari May 26 '20 at 21:12
  • 2
    (a) You have not shown the command used to build the test program. You need the switch `-fno-builtin-log` at least. [Without it, GCC will evaluate `log(2.7)` during compilation and not call the library routine.](https://godbolt.org/z/jZp72K) (b) Your `log` routine cannot work. When it calls `log`, it will call itself, not the library routine. Example code for one way of dealing with this is in the question you linked to. (c) There may be other solutions, such as the `--wrap=function` switch in some linkers. As I wrote, search for “interposition” or “interpose” or “interposing.” – Eric Postpischil May 26 '20 at 21:27
  • Try the cmd `file ./test`; check for dynamic, runtime link editor doesn't run for static bins. Long ago and may/not apply today on your system: there might be different results when `LD_PRELOAD` is file.so vs /full/path/to/file.so . Also run as a regular user, not as root. Remember to nix the recursion within your `log()` routine. – Milag May 27 '20 at 00:26
  • 1
    A comment above led to some interesting reading: [GCC, other builtins](https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html) – Milag May 27 '20 at 00:43
  • @EricPostpischil, @Milag Thanks again. According to your suggestions, I just updated my post. Using `-fno-builtin-log` I avoided the built-in compilation of log and I used `dlsym` for calling the real `log` now. It seems to get through my wrapper now, but the real `log` running has an issue as it returns zero! – Ali Salari May 27 '20 at 01:47
  • 4
    `real_log(dbl);` calls the function but does nothing with its return value. You need to return it, with `return real_log(dbl);`. Your compiler likely warned you about this. If it did not, enable all warnings in your compiler. Pay attention to them. – Eric Postpischil May 27 '20 at 01:53
  • @EricPostpischil yes it fixed. Thank you so much! Besides, I still need to know how similarly wrapping summation, multiplication, and division. I would appreciate any suggestions? – Ali Salari May 27 '20 at 03:28

0 Answers0