Unless you plan on spawning multiple shells over and over again I don't see how caching the entire object in kernel space would be all that useful. It seems like more of a waste of memory to me. You could simple use
Copy On Write pages for the shell, then starting a new shell would be as easy as making a link to the old one's code and creating a new data area. Why cache something that's already in memory?
The letting a user space library do the relocations could be a good idea provided a few requirements are met. You would need a way to verify that the library can be trusted. You would have to protect the library from viruses. If the library was infected it could make every application run virus code by providing faulty relocations.
If you are talking about a "server" (like in microkernels) doing the relocation then it sounds like a better idea than having a "library" do it. You could allow add-on modules for different file types without requiring a rewrite of any kernel code.