Overriding a 'C' function in a static library (.a)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mpatnam

    Overriding a 'C' function in a static library (.a)

    I have an executable which links to a static library (.a).
    I want to provide a hook by overriding a function part of this static
    library.
    Eg: I have a function "int blkstart(int i)" in this static library.
    I want to override this by having another function which is exactly
    similar in signature including name.
    When somebody call this function, control should automatically come to
    my overriddent function. Inside this function, based on certain
    conditions, I would like to call the original function in the static
    library.

    I tried using dlsym and dlopen APIs under SUN Solaris, but it didn't
    work as I suppose it is not meant for static library.
    Also I think this is the reason why it didn't work with static lib:

    Since static lib (.a) doesn't have identity at runtime like dlls, only
    the first available symbol was taken by linker during linking time and
    ignores any duplicate symbols available in any other
    static libs. At runtime, there is no way we can get the address of the
    duplicate
    function residing in the static library. Even running "nm <exe>" shows
    only one
    symbol which is the overloaded one (as in the make file, I have .o
    file ahead of
    -l<static-lib>). Basically at runtime, dlsym() can never resolve the
    duplicate function address as to start with, it was part of a static
    lib and linker ignores it as it has already resolved that symbol from
    the overloaded function.


    I would like to know if there is any other approach to fix this
    problem. Note that I don't have freedom to convert this static lib to
    dynamic one.
  • Eric Sosman

    #2
    Re: Overriding a 'C' function in a static library (.a)

    mpatnam wrote:[color=blue]
    >
    > I have an executable which links to a static library (.a).
    > I want to provide a hook by overriding a function part of this static
    > library.[/color]

    The details of how to do this (or whether it can be done
    at all) are specific to your platform, and really have nothing
    to do with the C language. However:
    [color=blue]
    > Eg: I have a function "int blkstart(int i)" in this static library.
    > I want to override this by having another function which is exactly
    > similar in signature including name.
    > [...]
    > I would like to know if there is any other approach to fix this
    > problem. Note that I don't have freedom to convert this static lib to
    > dynamic one.[/color]

    The C-and-nothing-but-C answer is to recompile all
    of the calling program, adding

    #define blkstart my_blkstart

    at the beginning of each translation unit ("source file")
    except for the file where my_blkstart is defined. Note
    that this will work only for those sources you can recompile;
    if the .a library itself contains un-recompilable functions
    that call blkstart(), this technique will not catch those
    calls.

    --
    Eric.Sosman@sun .com

    Comment

    • Kelsey Bjarnason

      #3
      Re: Overriding a 'C' function in a static library (.a)

      On Wed, 12 Nov 2003 12:08:53 -0800, mpatnam wrote:
      [color=blue]
      > I have an executable which links to a static library (.a). I want to
      > provide a hook by overriding a function part of this static library.
      > Eg: I have a function "int blkstart(int i)" in this static library. I
      > want to override this by having another function which is exactly
      > similar in signature including name.
      > When somebody call this function, control should automatically come to
      > my overriddent function. Inside this function, based on certain
      > conditions, I would like to call the original function in the static
      > library.[/color]

      Closest thing I can think of would be a macro. That is, do something
      like:

      #define blkstart mynewblkstart

      then, in mynewblkstart.c :

      #undef blkstart

      int mynewblkstart(i nt i )
      {
      return blkstart( i );
      }

      You'll just have to ensure that anyone calling blkstart also has the
      appropriate header included (to get the macro).


      Comment

      • Derk Gwen

        #4
        Re: Overriding a 'C' function in a static library (.a)

        mkpatnam@yahoo. com (mpatnam) wrote:
        # I have an executable which links to a static library (.a).
        # I want to provide a hook by overriding a function part of this static
        # library.
        # Eg: I have a function "int blkstart(int i)" in this static library.
        # I want to override this by having another function which is exactly
        # similar in signature including name.

        Once an external symbol is defined in a running program, you'll have
        little or no chance to redefine it.


        An alternative scheme is to something like

        plover.h
        typedef int (*BlkStartFunc) (int);
        void defineBlkStartF unc(BlkStartFun c);
        plover.c
        int default_blkstar t(int) {
        your current blkstart routine goes here
        };
        static BlkStartFunc blkstart = default_blkstar t;
        void defineBlkStartF unc(BlkStartFun c f) {
        blkstart = f;
        }

        Thus if your client does nothing, they use your default blkstart. If they
        want to override that, rather than depend on something tricky with the loader,
        they just call defineBlkStartF unc with their own blkstart routine. Within
        your code, you still call blkstart(x) the same as always.

        --
        Derk Gwen http://derkgwen.250free.com/html/index.html
        I think that's kinda of personal; I don't think I should answer that.

        Comment

        Working...