This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [bfd] Redirecting function calls in object files
- From: Nick Clifton <nickc at redhat dot com>
- To: Ames Andreas <Andreas dot Ames at comergo dot com>
- Cc: binutils at sourceware dot org
- Date: Tue, 25 Apr 2006 18:09:40 +0100
- Subject: Re: [bfd] Redirecting function calls in object files
- References: <552B6B925278EF478EA8887D7F9E5AC36CE7BD@tndefr-ws00024>
Hi Ames,
I'm writing a test facility for a bunch of C++ modules. To this end I
want to 'fix' function calls within an object file to point to some
stub functions, i.e. I want to test a given class (given as an object
file) by replacing calls to instances of other classes with calls to
stubs provided by my test facility. I'm currently only interested in
pei- and elf-targets. Requiring that the object contains symbols is
no problem, because I have the sources for the classes under test.
If you have the sources of the classes available, why can't you redirect
the calls at the source level ? ie why not create a set of macros that
alias the desired member functions. Something like:
#define foo testharness_foo
to replace calls to member function "foo" with calls to
"testharness_foo" which you would provide in your test facility.
Alternatively have you considered using the "--wrap SYMBOL" switch that
is provided by the linker ?
1) If they aren't inlined, can libbfd help me to replace the call(s)
to the original function defined in the object file under test to a
stub function defined in another object file, provided by my test
facility? If so, how?
This would be difficult. If the called function is in the same
compilation unit as the caller, then the compiler may have inlined it
automatically, even if it does not have the "inline" qualifier. It this
case you are hosed. Even if the function is not inlined, the call to it
can be computed statically by the assembler, so there may not be a reloc
to tell the linker where the call originates or what is being called.
Now it is true that you could analyze all of the instructions in the
input object files, locate all call-subroutine instructions, check their
destinations, and if any of them point to the start of one of the
functions you want to intercept then replace the destination address.
This would be time consuming and complex but it certainly can be done.
(This approach would probably be best done as a separate tool that runs
post-link. It would not have to use libbfd unless you really want to).
2) Can I use libbfd to determine if the interesting functions are
inlined within the object under test (e.g. to issue an error
message and require a recompilation with no inlining)?
No. :-( Even if a function is inlined, its code (and name) may still be
present in the object file. This is usually selectable by a compiler
switch.
Note - there is a GCC patch available which records the switches used to
build an object file as an extra section inside the object file. Thus
you could in theory scan this section and look for -finline or -O3 or
some other dangerous switch and issue an error message that way. The
patch has not been accepted into the GCC sources yet though, but you can
find it documented here:
http://gcc.gnu.org/wiki/Record%20GCC%20command%20line%20switches%20in%20object%20files
Is it
certain that all calls to the same function within a single
compilation unit are either inlined or not (this is more of a
compiler question, I guess)?
It is a compiler question and the answer is "no". Calls via function
pointers for example cannot be inlined. There are probably other cases
as well, although I cannot think of any off the top of my head.
Cheers
Nick