public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [bfd] Redirecting function calls in object files
@ 2006-04-11 14:43 Ames Andreas
  2006-04-25 17:25 ` Nick Clifton
  0 siblings, 1 reply; 3+ messages in thread
From: Ames Andreas @ 2006-04-11 14:43 UTC (permalink / raw)
  To: binutils

Hi all,

please note, that I'm almost a complete newbie when it comes to libbfd
and linker techniques in general.

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.

As I understand so far, please correct me, this shouldn't be a problem
for functions in sections, for which bfd_is_und_section is true,
because I can just define them in another compilation unit and the
linker will pick them up.  I can't figure out how this could work for
functions defined in the same compilation unit as the class under
test (think templates, for example).  So here are the questions:

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?

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)?  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)?

Any pointers to docs or sample code (if it doesn't mean I have to
understand the whole ld code at once :-) and general explanations are
appreciated.


TIA,

aa

-- 
Andreas Ames | Programmer | Comergo GmbH |
Voice:  +49 69 7505 3213 | ames AT avaya . com

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [bfd] Redirecting function calls in object files
  2006-04-11 14:43 [bfd] Redirecting function calls in object files Ames Andreas
@ 2006-04-25 17:25 ` Nick Clifton
  0 siblings, 0 replies; 3+ messages in thread
From: Nick Clifton @ 2006-04-25 17:25 UTC (permalink / raw)
  To: Ames Andreas; +Cc: binutils

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



^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [bfd] Redirecting function calls in object files
@ 2006-04-28  6:23 Ames Andreas
  0 siblings, 0 replies; 3+ messages in thread
From: Ames Andreas @ 2006-04-28  6:23 UTC (permalink / raw)
  To: binutils

Hi Nick,

thanks for your valuable comments.

> -----Original Message-----
> From: Nick Clifton [mailto:nickc@redhat.com] 
> Sent: Tuesday, April 25, 2006 7:10 PM
> Subject: Re: [bfd] Redirecting function calls in object files
> 
> 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

I've got actually two reasons why I don't want to change the sources:

1) The sources of legacy applications would have to be changed to
   support them with my test harness, which I'd rather not require.
   But even in new applications it wouldn't help making the
   application code more readable.

2) In C++ it's sometimes hard to know and specify what functions are
   really called (overloading, templates etc.) at the source level.

> Alternatively have you considered using the "--wrap SYMBOL" 
> switch that 
> is provided by the linker ?

Frankly I didn't know about that feature in ld.  It certainly looks
very useful but I'd rather not commit to a single linker.  For
instance Microsoft's link.exe is much more often used around here and
I don't see anything similar in its docs.

> 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%20switch
> es%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.

Again, thanks a lot that you have taken the time to explain all this
to me.  This actually leads me to the insight that I should simply
advice the user to compile her code with inlining turned off (gcc as
well as cl.exe support this and these are currently my primary
concern).

What I'd like to provide is a framework for easy generation of mock
objects and stubs.  I imagine the following steps, please feel free to
comment on them (believe me, I really need advice on that).

In a first step the user specifies the class under test (or rather
unit under test) as an object file together with the libs she isn't
intersted in mocking (like runtime libs etc.).  The test tool gathers
all undefined symbols, demangles their names (so C++ only) and
provides stubs to satisfy these symbols together with a framework to
specify expectations and to enforce those (like what parameters are
used, calling sequences and other things that other mock frameworks
support).  By reading the source code of nm I believe bfd provides the
needed support (besides demangling, because I'd need more structured
information than only a human readable equivalent of the mangled
symbol).

In a further step it would be nice to be able to also mock functions
defined within the unit under test.  Inlining issues aside, I could
imagine the following:

The user specifies the function she is interested in, the tool finds
the function's code in the object file and patches it with, say, a jmp
to an externally defined symbol (as its first instruction).  If this
is possible and when so, how, is currently completely beyond me.
Following some issues I can currently think of (please tell me which
others you can see):

1) Is it possible to inject imported symbols into an existing object
   file?  If so, how?

2) Obvious portability issues aside, can I easily find a functions
   code and patch it (in an existing object file)?  If so, how?

3) The goal of the patched in jump would have to deal with different
   calling conventions.  When the goal of the jump has the same
   calling convention as the the mocked function, I currently only see
   a problem with microsoft's thiscall convention (this ptr in CX).
   This would probably need special treatment (like inline assembly).
   Do you know of examples where a thiscall is 'transparently'
   transformed into a cdecl call or something?


TIA,

aa

-- 
Andreas Ames | Programmer | Comergo GmbH |
Voice:  +49 69 7505 3213 | ames AT avaya . com

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-04-27 18:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-11 14:43 [bfd] Redirecting function calls in object files Ames Andreas
2006-04-25 17:25 ` Nick Clifton
2006-04-28  6:23 Ames Andreas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).