Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Is there such thing as a "delinker"? 1

Status
Not open for further replies.

chipperMDW

Programmer
Mar 24, 2002
1,268
US
This question isn't specific to C++, but there's no "linkers" forum, and this seems like a reasonable place to ask.


I've come across a situation where it would be useful to be able to statically link object files with a library to form an executable (most likely only needs to be ELF), then at some later point "delink" that library and link something else in its place -- either statically or dynamically.

I know I could use a shared library, but this needs to work as a static library. I also know I could keep the object files lying around and just redo the linking, but I'd like a better solution than that.


So, first of all, for someone who knows ELF format, is this even possible?

If it is possible, is there anything out there that can do this now?

If it is not possible, would it be feasible to extend ELF to support "delinking"?

Finally, is there already some solution to this type of problem (with statically linked libraries) and I'm just not looking hard enough or thinking in the right direction? If so, let me know.


Sorry if this was an inappropriate place to ask this question; just remember that people ask about decompiling in C/C++ forums, too.
 
Not sure about unix but on the old Intels, the lib utility which was used to create libraries could also extract the object files. Maybe this is possible with ar but it may not be possible with ld.
 
I've never tried this before and I haven't got a Unix system at the moment to try it on. Try ar -x
 
ar will remove object files from a static library, but that's not what I need. I want the reverse of a linking operation.

Say I had three object files: a.o, b.o, and c.o. I've statically linked them together (the normal, "forward" linking process) to create an executable: foo.

Can I now perform a reversed linking process to decompose foo back into a.o, b.o, and c.o? Or at least "rip" one of the .o files out of the bundle, leaving the other two partially linked?


If necessary, assume that, at the time of "forward" linking, I know which of the object files I'm going to want to rip out.
 
ar is like tar, you can extract object files, rtfm. that is if you have an archive lib upfront ... as far as i know it doesnt do shared libs.
 
I'm certain my question has nothing to do with ar.

An executable is not the same thing as a static library. Among other things, an executable has no unresolved references while an object file (and therefore a library) does.

I want the reverse of a link operation. You're telling me the reversal of placing object files into an archive (which is not linking); I want the opposite of the resolution of the references that occurs in the link phase (which is linking).


To clarify again:

I have an executable foo.

When foo was just some C++ source code, it looked like these two modules:

Code:
// foo.c
#include "null.h"
int main()
{
    null();
}


// null.c
void null()
{
}

These were statically linked together to produce foo.

So right now, running foo does nothing.


Can I, now, (using tar-like syntax in this example command) "delink xf foo null" to unresolve the resolved reference to null from foo (which was resolved at link time), and end up with an object file (foo-delinked.o) that has an unresolved reference to a function called null, and so can be linked to the object file produced by the following code (a different definition of null) to create a different executable?

Code:
// null.c
void null()
{
    for (;;)
        ;
}


To recap again, I want to reverse the link operation. I want to change foo (an executable) to an object file containing unresolved references (corresponding to the ones that were delinked).

I do not want to know how to remove archive members from a static library. I'm pretty good at that already.
 
You can't remove individual functions but you may be able to do whatever you wish using the dlopen family of routines.
 
Those won't work for my particular situation.

I want to give people the option of statically linking a module into an executable, but then later, being able to replace a given piece of it (which is known from the start) with either a different statically linked module or changing it to link to a shared library.

I can't use dlopen because the entire purpose of this module is to find the program's files on a filesystem, thus eliminating its dependence on where its files are installed. Putting the program's file-finder in a file it needs to find (a plugin) would be counterproductive. Being able to swap this module in and out would be useful for changing where a statically linked program thinks its files are installed.


So ok, since no one knows of any way to do this with currently available tools, consider this:


I can easily and quickly invent any executable format I want within the bounds of reason.

I have a.o and z.o.

a.o is a single, small module.

z.o is a large module produced by linking a bunch of smaller object files together.

I want to link these two to produce an executable foo...

...but I want to be able to "retrieve" z.o at some later point.


Is is possible, using a hypothetical executable format, to either:

A) include a "tag" on all symbols from a.o indicating that they are "delinkable," and have a linker that can either remove or replace references to those symbols in foo?

or

B) include "rollback" information in foo that can reproduce z.o?

or

C) do something that has an equivalent effect?
 
Mmm... same as a shared lib concept but not quite the same. I think you're on your own there.
 
Kinda like a shared library, yeah. Except with a shared lib, you really can only change the version of the library an application links to, 'cuz the linker will still look for the same filename (a symlink) to link; it just might now be pointing to a newer version of the library.

My intent is essentially to let the application be linked to completely different libraries (using the same interface, however) to produce different effects.

This can be sorta done with shared libraries by linking to something that's not the name of an actual library, but points to one.

The problem is that there is sufficient reason to want to use this as a static library, or to switch from using this as a static library to using it as a shared library or vice versa.

I can always just save the big object file (z.o above) and use it to relink the executable with a different library, but I was hoping to avoid that.


Oh, well. Thanks for the help.
 
such a tool will have to reverse engineer the relocations that have already been applied to create the executable. i am not very conversant with the elf format but i think this holds good to some extent. so you'll have to link in such a way as to keep the relocations dynamic (i dont know if that is possible or supported by any linker), but that may defeat your purpose of having an archived executable. maybe i am wrong all over ...

please do try to update this thread on how you solve this, when you do. thanks.
 
If you put the module object file content into the data part of your executable (and reserve some amount of space for it to grow), dump it to some temp file on program startup (unless you know of a way to point a pseudo-file to a part of another file content) then dlopen() it, you should be able to just overwrite the part of the program that contains the module (and it's size) whenever you want to change the module.
 
Advice of pfournier could work only in case of non-relocable executables (like .com in MS-DOS) and only if that module you want to reimplant to executable will be linked to the same start address in all versions of your executable.
Systems like Unix and Windows use relocable executables, they have table of references needed to be corrected directly before loading to correspond actual adresses of memory. In this case simply changing of image of the module will not work.
IMHO you can do it only in Assembler, producing fully relocable code which receives all global environment as call parameters and does not need any correction of code on loading.
 
Is that the case even when using dlopen?

dlopen lets you call code from a module external to the executable; this module need not have even existed at the time the executable was linked, and it need not have been specially designed to work with a particular executable.

It seems to me like the solution would theoretically work.


Even if it does, there's a problem with dlopen... it only works on Linux/Solaris. To support other platforms, I'd have to abstract a generic "plugin loader" module to be used in every application that could potentially use this. That also kinda defeats one of the purposes for doing this in the first place.
 
i know this wont help you a lot but for the record, dlopen etc are also supported on hpux PA32, PA64, IA32 and IA64.
 
I don't know what dlopen is, may be it loads the executable to the memory exactly like by normal it execution and then passes control to the module was called from the parent aplication. Isn't it tool for supporting dynamic linking in Unix? Anyway, my thoughts are only my opinion, may be I'm wrong. Also you can try to search help on detailed structure of executable files - may be there will be no problems to manage these reference tables by yourself and write some kind of delinker/linker.
I did not still understand, why are you not satisfyed with dynamic linked libraryes?
 
dlopen lets you sort of attach an object file or library to your program at runtime and access symbols in it "manually."

Thus, instead of calling the function
Code:
func1
directly, you "look up" the symbol
Code:
"func1"
and get back a pointer to a function, which you can then call through the pointer.

It's more complex in C++ due to name-mangling, but that's the general idea.


So I don't know if what you said applies to dlopen or not.


It's not that I'm not satisfied with dynamic libraries (or shared libraries), it's just that they don't solve the problem I want to solve.

I'm basically making a general purpose library for programs to find their resources on a filesystem (or somewhere more general).

The simplest possible behavior is to just have the file locations hard-coded in the library. In this case, this would need to be a static library; otherwise, you'd need one shared library for each program using the library and using the simplest behavior. That's unacceptable.

Now, a slightly more complex behavior would be to have the library look up the file locations in a configuration file; then, each program could link to the one library. This would be slower (looking stuff up in a potentially long list if many programs use the library on one system, plus possible extra time from using a shared lib), but it would afford the user the ability to change locations the program expects its files to be in.

Back to the simplest case, if you could delink the module that has the file locations hard-coded, you could then generate a different module with different hard-coded locations, thus giving you flexibility without needing to register each program's files with the shared library.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top