Partially Compile C++ Source

Goal

I want to be able to extract some information out of a collection of C++ source files by partially compiling them. I say partially compile, because I don’t have access to all the shared libraries it is supposed to link against. The exact situation will be explained further below.

In pseudo-code, I have (roughly) the following structure:

class AParent : public AClassFromSharedLib {
    ...
    void setup(void);
    void otherThings(void);
    ...
}

class AChild : public AParent {
    ...
    void setup(void);
    void moreStuff(void);
    ...
}
...
AParent::setup(void)
{
    interestingFunction("foo");
    interestingFunction("bar");
    interestingFunction("baz");
    somethingElse("cafe");
}
...
AChild::setup(void)
{
    super::setup();
    interestingFunction("dead");
    interestingFunction("beef");
    somethingElse("babe");
}
...
REGISTER_CLASS("SomeName", AChild);

All I want to do is print the interestingFunction arguments from the setup() method call path for AChild (and other objects registered through REGISTER_CLASS).

SomeName:
    "foo"
    "bar"
    "baz"
    "dead"
    "beef"

I don’t care about anything else. Just the object hierarchy and method setup are all I really need to accomplish what I want.

I want to tell the compiler, “remove all methods from this class except setup, I’ll provide all the symbols you need from there”. Is this possible? Targeting a RedHat 5 system with g++ 4.4.x.

Background

Because I don’t have access to the .so files to link against, the code I am working with is meant to be compiled as a .so itself. That way, the linker can defer resolving symbols until later. This file gets passed along to something that does eventually have access to all the necessary libraries and compiles the final program. Unfortunately, this process is hidden so I can’t tap into it for the libraries.

I figured that I could extract some information by making a simple program that links against my own .so, defining simple implementations to symbols I care about, and then just have my debug program instantiate some objects and call some methods. This way, I could capture some information about my program without needing to have access to all the libraries.

I don’t really care about the actual implementation, so I could easily provide dummy implementations for the symbols I don’t care about and print statements for the ones I do care about. Problem is, there are hundreds of headers and hundreds of objects, classes, functions, etc that I would need to dummy out. Things got quickly out of hand.

What I have tried

My first thought was to exploit gcc’s ability to strip dead code. I thought if I only called this one method from this one object, it would see that all the other code was unreachable and throw out those symbols. Unfortunately, no amount of -Os -fdata-sections -ffunction-sections -Wl,--gc-sections or anything of the like worked out for me. The most promising flag seemed like -flto, but I wasn’t able to try it because my compiler was too old.

I also tried telling the linker -Wl,--unresolved-symbols=ignore-in-object-files, but that just caused the program to segfault during runtime, even when I didn’t use any of those undefined symbols from main().

My bag of tricks is running thin, and there isn’t much else I can think of doing. It’s looking like the solution is to do a crude parse with grep and enforce simple coding standards (no variables, function calls, etc) so the dumb parser can pick up this information somewhat reliably. It feels like there aught to be a better solution to this problem.


Source: gcc

Leave a Reply