diff options
author | mckay <mckay@FreeBSD.org> | 1998-06-21 14:22:29 +0000 |
---|---|---|
committer | mckay <mckay@FreeBSD.org> | 1998-06-21 14:22:29 +0000 |
commit | 446517db8125477c5a4cabac18929f405c716326 (patch) | |
tree | 9a23b83459efc0d9c90dde0693b0812b0a6d0481 /libexec | |
parent | f5384af525a2dc92a763f2530ddbf7b9597d2b0f (diff) | |
download | FreeBSD-src-446517db8125477c5a4cabac18929f405c716326.zip FreeBSD-src-446517db8125477c5a4cabac18929f405c716326.tar.gz |
Since I got no objections to this patch, and no one has offered any
alternative, I present .. ta! da! .. the __error() hack.
This patch to the a.out dynamic loader provides old a.out binaries
with __error() if they are linked with an older libc that lacks it,
but are also linked against a library that needs it.
There is a smaller, tricker hack that takes advantage of the fact
that ld.so has __error() too, courtesy of the new libc, but this
hack is the straightforward version.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-aout/rtld.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c index 5239c38..4ae4fa6 100644 --- a/libexec/rtld-aout/rtld.c +++ b/libexec/rtld-aout/rtld.c @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.53 1998/05/26 20:12:51 sos Exp $ + * $Id: rtld.c,v 1.54 1998/06/07 03:53:06 brian Exp $ */ #include <sys/param.h> @@ -252,6 +252,7 @@ static struct nzlist *lookup_in_obj __P((char *, unsigned long, static struct rt_symbol *enter_rts __P((char *, unsigned long, long, int, caddr_t, long, struct so_map *)); static void *sym_addr __P((char *)); +static struct nzlist * lookup_errno_hack(char *, struct so_map **, int); static void die __P((void)); static void generror __P((char *, ...)); static int maphints __P((void)); @@ -1502,6 +1503,13 @@ lookup(name, src_map, real_def_only) return rtsp->rt_sp; } + /* + * Just before giving up, check for the __error() hack. + */ + np = lookup_errno_hack(name, src_map, real_def_only); + if (np != NULL) + return np; + /* No definition was found for the symbol. */ return NULL; } @@ -1596,6 +1604,67 @@ sym_addr(name) return ((smp == NULL) ? NULL : smp->som_addr) + np->nz_value; } + +/* + * Help old a.out binaries that are broken by the new errno macro. They + * can be missing __error() through no fault of their own. In particular, + * old a.out binaries can link against an old libc that does not contain + * __error(), yet still require __error() because of other libraries that + * have been recompiled since the errno change. This locates the backward + * compatible work-alike we have hidden here in ld.so. + */ +static struct nzlist * +lookup_errno_hack(sym, src_map, real_def_only) + char *sym; + struct so_map **src_map; + int real_def_only; +{ + struct so_map *smp; + struct nzlist *np; + + if (strcmp(sym, "___error") != 0) + return NULL; + + /* + * Specifically find the ld.so link map because most routines + * skip over it during normal operation. + */ + for (smp = link_map_head; ; smp = smp->som_next) + if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD) + break; + + /* + * Actually, ld.so uses errno via the new macro, so it has a copy + * of __error() lying around. The really neat but obscure hack + * is to just use that one, but to be really clear about what + * is going on, we use an explicit __error() substitute. + */ + np = lookup("___error_unthreaded_hack", &smp, real_def_only); + if (np != NULL) + *src_map = smp; + +#ifdef DEBUG + if (np == NULL) + xprintf(" HACK: %s fudge not found, oops\n", sym); + else + xprintf(" HACK: %s fudge in %s\n", sym, smp->som_path); +#endif + + return np; +} + + +/* + * Just like __error_unthreaded(), but for those poor orphaned a.out + * binaries from way back that are bamboozled by the new errno macro. + */ +int * +__error_unthreaded_hack() +{ + return &errno; +} + + /* * This routine is called from the jumptable to resolve * procedure calls to shared objects. |