title: GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file
body: <p>to clarify, my question refers to wrapping/intercepting calls from one function/symbol to another function/symbol <strong>when the caller and the callee are defined in the same compilation unit</strong> with the GCC compiler and linker.</p>
  
  <p>I have a situation resembling the following:</p>
  
  <pre><code>/* foo.c */
  void foo(void)
  {
    /* ... some stuff */
    bar();
  }
  
  void bar(void)
  {
    /* ... some other stuff */
  }
  </code></pre>
  
  <p>I would like to wrap calls to these functions, and I can do that (to a point) with <a href="http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html" rel="noreferrer">ld's <code>--wrap</code> option</a> (and then I implement __wrap_foo and __wrap_bar which in turn call __real_foo and __real_bar as expected by the result of ld's <code>--wrap</code> option).</p>
  
  <pre><code>gcc -Wl,--wrap=foo -Wl,--wrap=bar ...
  </code></pre>
  
  <p>The problem I'm having is that this only takes effect for references to foo and bar <strong>from</strong> outside of this compilation unit (and resolved at link time). That is, calls to foo and bar from other functions <strong>within foo.c</strong> do not get wrapped. </p>
  
  <p><img src="https://i.stack.imgur.com/f9l8D.png" alt="calls from within the compilation unit get resolved before the linker&#39;s wrapping"></p>
  
  <p>I tried using <a href="http://sourceware.org/binutils/docs/binutils/objcopy.html" rel="noreferrer">objcopy --redefine-sym</a>, but that only renames the symbols and their references.</p>
  
  <p>I would like to replace calls to <code>foo</code> and <code>bar</code> (within foo.o) to <code>__wrap_foo</code> and <code>__wrap_bar</code> (just as they get resolved in other object files by the linker's <code>--wrap</code> option) BEFORE I pass the *.o files to the linker's <code>--wrap</code> options, and without having to modify foo.c's source code.</p>
  
  <p>That way, the wrapping/interception takes place for all calls to <code>foo</code> and <code>bar</code>, and not just the ones taking place outside of foo.o.</p>
  
  <p>Is this possible? </p>