4

I have a code like this in mylib.h, and then I use it to create mylib.so. Is there a way to check how MY_MACROS is defined in .so?

#ifdef SWITCH_CONDITION
    #define MY_MACROS       0
#else
    #define MY_MACROS       1
#endif

If that would be a function, I'd simply do

nm mylib.so | grep myfunction

Is there a way to do the same for macros?

P.S. There should be because of

> grep MY_MACROS mylib.so 
> Binary file mylib.so matches
tkrishtop
  • 734
  • 1
  • 8
  • 18
  • 6
    Macros are not defined in dynamic libraries, they are compile-time (rather preprocessing time) only. What are you trying to achieve? – walnut Sep 02 '19 at 13:35
  • 8
    Macros are replaced by the preprocessor so they do not exist as symbols in the compiled code. In other words, in general it's not possible – Ingo Leonhardt Sep 02 '19 at 13:36
  • @uneven_mark thank you ! I'm not sure if SWITCH_CONDITION works as it should and trying to figure out how to verify this. – tkrishtop Sep 02 '19 at 13:41
  • Some of you make that into an answer. – Marco Bonelli Sep 02 '19 at 13:41
  • macro definitions is lost information during compilation, you cannot, in general, see what compilation macros were defined and with what values. – Luis Colorado Sep 04 '19 at 08:45

2 Answers2

5

In general there is no way to do this sort of thing for macros. (But see more below.)

Preprocessor macros are theoretically a compile-time concept. In fact, in the early implementations of C, the preprocessor was -- literally -- a separate program, running in a separate process, converting C code with #include and #define and #ifdef into C code without them. The actual C compiler saw only the "preprocessed" code.

Now, theoretically a compiler could somehow save away some record of macro definitions, perhaps to aid in debugging. I wasn't aware of any that did this, although evidently those using the DWARF format actually do! See comments below, and this answer.

You can always write your own, explicit code to track the definition of certain macros. For example, I've often written code elong the lines of

void print_version()
{
    printf("myprogram version %s", VERSION_STRING);
#ifdef DEBUG
    printf(" (debug version)");
#endif
    printf("\n");
}

Some projects have rather elaborate mechanisms to keep track of the compilation switches which are in effect for a particular build. For example, in projects managed by a configure script, there's often a single file config.status containing one single record of all the compilation options, for posterity.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Note that you can `grep` the resulting binary to see if the macro name was defined if you compile with `-gdwarf-4 -g3`. – S.S. Anne Sep 02 '19 at 14:12
  • @SteveSummit The strange thing is that `grep MY_MACROS mylib.so` results in `Binary file mylib.so matches`. This macros should be somewhere! :) The problem is that `grep -a MY_MACROS mylib.so | less` and then direct search finds nothing. – tkrishtop Sep 02 '19 at 14:16
  • 1
    @tkrishtop Aha! So it's looking like my "no" answer is wrong, and that the answer is actually "yes"! – Steve Summit Sep 02 '19 at 14:18
  • @tkrishtop Yeah, you can use `-a` for that purpose. However, the value of the macro (if it's an integer) is stored in binary. – S.S. Anne Sep 02 '19 at 14:22
  • @JL2210 The problem is that `grep -a MY_MACROS mylib.so | less` and then direct search finds nothing. – tkrishtop Sep 02 '19 at 14:24
  • @tkrishtop There's no way to do that. However, I *may* be able to write a tool that does the job. Give me a minute (or an hour) and I'll see what I can do. – S.S. Anne Sep 02 '19 at 14:25
  • 2
    @JL2210 I was tempted to do the same thing! You probably know this already, but before reinventing wheels, check the external links at https://en.wikipedia.org/wiki/DWARF . – Steve Summit Sep 02 '19 at 14:27
4

Yes, but it requires debugging info.

You can compile your code with -g3:

$ gcc -g3 -shared -fPIC test.c -o test.so

and then run strings on the resulting binary:

$ strings test.so
...
__DEC32_EPSILON__ 1E-6DF
MY_MACROS 1
__UINT_LEAST32_TYPE__ unsigned int
S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
  • 1
    Good catch. `-g3` is the key observation. `-g2` or below does not include macro definitions. (And also see questions like [gdb macro symbols not present even when using -g3 or -ggdb3 or -gdwarf-4](https://stackoverflow.com/q/10496195/608639)). – jww Sep 02 '19 at 18:36