turning (part of) an executable into a shared object

Ben Liblit liblit@cs.berkeley.edu
Wed Oct 1 07:39:00 GMT 2003


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?



More information about the Binutils mailing list