I'll walk through a solution you can use if your supplier has given you object files compiled
with GCC or Clang for GNU/Linux computers.
My supplier has given me a header foo_a.h
file that declares function foo
$cat foo_a.h
#pragma once
extern void foo(void);
and the matching object file foo.o
:
$ nm foo_a.o
0000000000000000 T foo
U _GLOBAL_OFFSET_TABLE_
U puts
that defines foo
.
Likewise they've given me a header foo_b.h
that also declares foo
$ cat foo_b.h
#pragma once
extern void foo(void);
and the matching object file foo_b.o
$ nm foo_b.o
0000000000000000 T foo
U _GLOBAL_OFFSET_TABLE_
U puts
that also defines foo
.
The functions foo_a.o:foo
and foo_b.o:foo
do different
things (or different variations of the same thing). I want to do both these things in the same program,
prog.c
:
$ cat prog.c
extern void foo_a(void);
extern void foo_b(void);
int main(void)
{
foo_a(); // Calls `foo_a.o:foo`
foo_b(); // Calls `foo_b.o:foo`
return 0;
}
I can make such a program as follows:
$ objcopy --redefine-sym foo=foo_a foo_a.o prog_foo_a.o
$ objcopy --redefine-sym foo=foo_b foo_b.o prog_foo_b.o
Now I have made a copy prog_foo_a.o
of foo_a.o
in which the symbol foo
is
renamed foo_a
, and a copy prog_foo_b.o
of foo_b.o
in which
the symbol foo
is renamed foo_b
.
Then I compile and link like this:
$ gcc -c -Wall -Wextra prog.c
$ gcc -o prog prog.o prog_foo_a.o prog_foo_b.o
And prog
runs like:
$ ./prog
foo_a
foo_b
Perhaps my supplier has given me foo_a.o
within a static library liba.a
that also contains other object files that refer to foo_a.o:foo
? And similarly
with foo_b.o
.
That's OK. Instead of:
$ objcopy --redefine-sym foo=foo_a foo_a.o prog_foo_a.o
$ objcopy --redefine-sym foo=foo_b foo_b.o prog_foo_b.o
I will run:
$ objcopy --redefine-sym foo=foo_a liba.a libprog_a.a
$ objcopy --redefine-sym foo=foo_b libb.a libprog_b.a
and this will give me a new static library libprog_a.a
in which foo
is renamed foo_a
in all the object files in the
library. Similarly foo
is renamed foo_b
throughout libprog_b.a
.
Then I'll link prog
:
$ gcc -o prog prog.o -L. -lprog_a -lprog_b
Consider a potential drawback with this solution. Possibly my supplier has
given me foo_a.o
and foo_b.o
with debugging information in them, and I want to
used it for debugging my prog
with gdb
?
I have changed the original symbol names, foo_a.o:foo
to foo_a
and
foo_b.o:foo
to foo_b
, but I haven't changed the debugging info associated
with those symbols. Debugging with gdb
will still work, but some of the
debugging output will be incorrect and possibly confusing. E.g. if I put
a breakpoint on foo_a
, gdb
will run to it and stop, but it will say
it has stopped at foo
from file foo_a.c
. And if I then breakpoint at foo_b
, gdb
will run to
it and again say it is at foo
, but from file foo_b.c
. If the person doing
the debugging doesn't know how the program was built, this would certainly be
confusing.
But giving you debugging info with binaries is not far from giving you the
source code, so as you haven't got source code you likely don't have
debugging info and are not concerned about it.