This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
turning (part of) an executable into a shared object
- From: Ben Liblit <liblit at cs dot berkeley dot edu>
- To: binutils at sources dot redhat dot com
- Date: Wed, 01 Oct 2003 00:39:27 -0700
- Subject: turning (part of) an executable into a shared object
I have executables with some extra read-only data in a non-standard
section (".debug_cfg" instead of ".data" or ".rodata"). I would like to
take a linked executable and extract just this data into a standalone
file. Furthermore, I would like the extracted data to be navigable by
an unrelated application using dlopen() and dlsym(). I am working on a
Linux x86 box with ELF binaries, and while portability is always
welcome, that specific platform is currently my top priority.
Extracting the special section is easy enough using objcopy. My gcc
section attributes notwithstanding, it appears that pointed-to strings
in the extra data actually end up in the ".rodata" section rather than
the ".debug_cfg" section. So we keep both:
% objcopy -j .debug_cfg -j .rodata executable extracted-data
gcc is perfectly willing to turn that extracted data into a shared object:
% gcc -shared -o extracted-data.so extracted-data
I can write a program that dlopen()'s this shared object and uses
dlsym() to fetch the address of a symbol that I know should be present
in the ".debug_cfg" section. That symbol refers to a structure
containing string pointer fields, non-string pointer fields, and
non-pointer fields. The string pointer fields should point into
".rodata", while the non-string pointer fields always point to other
data also in the ".debug_cfg" section. What I find, is that the
non-pointer fields have correct values, but the pointer fields do not. :-(
Presumably we lost some important reloc information when we linked the
executable. We can explicitly ask the linker to keep that information
around. Unfortunately, that leads to an error when turning the
extracted data into a shared object:
% gcc -Wl,--emit-relocs -o executable [...]
% objcopy -j .debug_cfg -j .rodata executable extracted-data
% gcc -shared -o extracted-data.so extracted-data
/usr/bin/ld: simple-cfg.sec(.debug_cfg+0x8048400): reloc against \
`.rodata': error 2
It looks like the ".rel.dyn" section contains relocation information.
Perhaps I need to keep that too? No luck:
% gcc -Wl,--emit-relocs -o executable ...
% objcopy -j .debug_cfg -j .rodata -j .rel.dyn executable \
extracted-data
% gcc -shared -o extracted-data.so extracted-data
/usr/bin/ld: simple-cfg.sec(.debug_cfg+0x8048400): reloc against \
`.rodata': error 2
Is there any way to make this alchemical trick work? How can I extract
selected data sections from a linked executable and turn them back into
a shared, dynamically loadable object with properly adjusted pointers?