Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/ld.elf_so Move compatibility for pre-2.0 ELF binarie...



details:   https://anonhg.NetBSD.org/src/rev/e23d9a182fad
branches:  trunk
changeset: 445200:e23d9a182fad
user:      joerg <joerg%NetBSD.org@localhost>
date:      Wed Oct 17 23:36:58 2018 +0000

description:
Move compatibility for pre-2.0 ELF binaries into separate file.
Early ELF binaries defined dlopen and friends in crt0.o by
using function pointers in the object handle passed from rtld.
This contract wastes space when many shared objects are allocated
and ties dynamic linker and rest of the system tightly together.
Fake the entry points in a static object and restrict them to the
platforms that had working ELF support at the time. Keep the magic and
version field used by modern crt0.o for all architectures. The checks
will be removed from crt0.o in a follow-up step.

diffstat:

 libexec/ld.elf_so/Makefile |   4 +-
 libexec/ld.elf_so/compat.c |  94 ++++++++++++++++++++++++++++++++++++++++++++++
 libexec/ld.elf_so/reloc.c  |  19 +--------
 libexec/ld.elf_so/rtld.c   |   6 +-
 libexec/ld.elf_so/rtld.h   |  18 +-------
 5 files changed, 103 insertions(+), 38 deletions(-)

diffs (229 lines):

diff -r c0fbc29ce5ab -r e23d9a182fad libexec/ld.elf_so/Makefile
--- a/libexec/ld.elf_so/Makefile        Wed Oct 17 16:56:40 2018 +0000
+++ b/libexec/ld.elf_so/Makefile        Wed Oct 17 23:36:58 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.138 2018/06/09 22:41:55 christos Exp $
+#      $NetBSD: Makefile,v 1.139 2018/10/17 23:36:58 joerg Exp $
 #
 # NOTE: when changing ld.so, ensure that ldd still compiles.
 #
@@ -72,7 +72,7 @@
 
 SRCS+=         rtld.c reloc.c symbol.c xmalloc.c xprintf.c debug.c \
                map_object.c load.c search.c headers.c paths.c expand.c \
-               tls.c symver.c diagassert.c
+               tls.c symver.c diagassert.c compat.c
 
 .if ${USE_FORT} == "yes"
 .PATH.c: ${NETBSDSRCDIR}/lib/libc/misc
diff -r c0fbc29ce5ab -r e23d9a182fad libexec/ld.elf_so/compat.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/libexec/ld.elf_so/compat.c        Wed Oct 17 23:36:58 2018 +0000
@@ -0,0 +1,94 @@
+/*     $NetBSD: compat.c,v 1.1 2018/10/17 23:36:58 joerg Exp $ */
+/*-
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Early ELF support in NetBSD up to April 2nd, 2000 exposed dlopen and
+ * friends via function pointers in the main object that is passed to the
+ * startup code in crt0.o. Later versions kept the magic and version number
+ * checks, but depend on normal symbol interposition to get the symbols from
+ * rtld. The compatibility object build here contains just enough fields to
+ * make either routine happy without polluting the rest of rtld.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: compat.c,v 1.1 2018/10/17 23:36:58 joerg Exp $");
+
+#include "rtld.h"
+
+#if defined(__alpha__)
+#define RTLD_OBJ_DLOPEN_OFFSET 264
+#elif defined(__i386__)
+#define RTLD_OBJ_DLOPEN_OFFSET 140
+#elif defined(__mips) && defined(_ABIO32)
+/* The MIPS legacy support is required for O32 only, N32 is not affected. */
+#define RTLD_OBJ_DLOPEN_OFFSET 152
+#elif defined(__powerpc__) && !defined(__powerpc64__)
+/* Only 32bit PowerPC is affected. */
+#define RTLD_OBJ_DLOPEN_OFFSET 140
+#elif defined(__sparc) && !defined(__sparc64__)
+/* Only 32bit SPARC is affected, 64bit SPARC ELF support was incomplete. */
+#define RTLD_OBJ_DLOPEN_OFFSET 140
+#endif
+
+#define RTLD_MAGIC     0xd550b87a
+#define RTLD_VERSION   1
+
+#ifdef RTLD_OBJ_DLOPEN_OFFSET
+const uintptr_t _rtld_compat_obj[] = {
+#  ifdef _LP64
+#    if BYTE_ORDER == BIG_ENDIAN
+       [0] = (((uint64_t)RTLD_MAGIC) << 32) | RTLD_VERSION,
+#    else
+       [0] = (((uint64_t)RTLD_VERSION) << 32) | RTLD_MAGIC,
+#    endif
+#  else
+       [0] = RTLD_MAGIC,
+       [1] = RTLD_VERSION,
+#  endif
+       [(RTLD_OBJ_DLOPEN_OFFSET / sizeof(uintptr_t)) + 0] = (uintptr_t)dlopen,
+       [(RTLD_OBJ_DLOPEN_OFFSET / sizeof(uintptr_t)) + 1] = (uintptr_t)dlsym,
+       [(RTLD_OBJ_DLOPEN_OFFSET / sizeof(uintptr_t)) + 2] = (uintptr_t)dlerror,
+       [(RTLD_OBJ_DLOPEN_OFFSET / sizeof(uintptr_t)) + 3] = (uintptr_t)dlclose,
+       [(RTLD_OBJ_DLOPEN_OFFSET / sizeof(uintptr_t)) + 4] = (uintptr_t)dladdr,
+};
+#else
+const uintptr_t _rtld_compat_obj[] = {
+#  ifdef _LP64
+#    if BYTE_ORDER == BIG_ENDIAN
+       [0] = (((uint64_t)RTLD_MAGIC) << 32) | RTLD_VERSION,
+#    else
+       [0] = (((uint64_t)RTLD_VERSION) << 32) | RTLD_MAGIC,
+#    endif
+#  else
+       [0] = RTLD_MAGIC,
+       [1] = RTLD_VERSION,
+#  endif
+};
+#endif /* RTLD_OBJ_DLOPEN_OFFSET */
diff -r c0fbc29ce5ab -r e23d9a182fad libexec/ld.elf_so/reloc.c
--- a/libexec/ld.elf_so/reloc.c Wed Oct 17 16:56:40 2018 +0000
+++ b/libexec/ld.elf_so/reloc.c Wed Oct 17 23:36:58 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: reloc.c,v 1.112 2018/04/03 21:10:27 joerg Exp $         */
+/*     $NetBSD: reloc.c,v 1.113 2018/10/17 23:36:58 joerg Exp $         */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.112 2018/04/03 21:10:27 joerg Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.113 2018/10/17 23:36:58 joerg Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -220,21 +220,6 @@
                if (!ok)
                        return -1;
 
-               /* Set some sanity-checking numbers in the Obj_Entry. */
-               obj->magic = RTLD_MAGIC;
-               obj->version = RTLD_VERSION;
-
-               /*
-                * Fill in the backwards compatibility dynamic linker entry points.
-                *
-                * DO NOT ADD TO THIS LIST
-                */
-               obj->dlopen = dlopen;
-               obj->dlsym = dlsym;
-               obj->dlerror = dlerror;
-               obj->dlclose = dlclose;
-               obj->dladdr = dladdr;
-
                dbg(("fixing up PLTGOT"));
                /* Set the special PLTGOT entries. */
                if (obj->pltgot != NULL)
diff -r c0fbc29ce5ab -r e23d9a182fad libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c  Wed Oct 17 16:56:40 2018 +0000
+++ b/libexec/ld.elf_so/rtld.c  Wed Oct 17 23:36:58 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.c,v 1.192 2018/04/03 21:10:27 joerg Exp $  */
+/*     $NetBSD: rtld.c,v 1.193 2018/10/17 23:36:58 joerg Exp $  */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.192 2018/04/03 21:10:27 joerg Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.193 2018/10/17 23:36:58 joerg Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -786,7 +786,7 @@
         */
 
        ((void **) osp)[0] = _rtld_exit;
-       ((void **) osp)[1] = _rtld_objmain;
+       ((void **) osp)[1] = __UNCONST(_rtld_compat_obj);
        return (Elf_Addr) _rtld_objmain->entry;
 }
 
diff -r c0fbc29ce5ab -r e23d9a182fad libexec/ld.elf_so/rtld.h
--- a/libexec/ld.elf_so/rtld.h  Wed Oct 17 16:56:40 2018 +0000
+++ b/libexec/ld.elf_so/rtld.h  Wed Oct 17 23:36:58 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.h,v 1.133 2018/04/03 21:10:27 joerg Exp $  */
+/*     $NetBSD: rtld.h,v 1.134 2018/10/17 23:36:58 joerg Exp $  */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -136,9 +136,6 @@
  *
  * Items marked with "(%)" are dynamically allocated, and must be freed
  * when the structure is destroyed.
- *
- * The layout of this structure needs to be preserved because pre-2.0 binaries
- * hard-coded the location of dlopen() and friends.
  */
 
 #define RTLD_MAGIC     0xd550b87a
@@ -196,18 +193,6 @@
        Elf_Addr        init;           /* Initialization function to call */
        Elf_Addr        fini;           /* Termination function to call */
 
-       /*
-        * BACKWARDS COMPAT Entry points for dlopen() and friends.
-        *
-        * DO NOT MOVE OR ADD TO THE LIST
-        *
-        */
-       void           *(*dlopen)(const char *, int);
-       void           *(*dlsym)(void *, const char *);
-       char           *(*dlerror)(void);
-       int             (*dlclose)(void *);
-       int             (*dladdr)(const void *, Dl_info *);
-
        u_int32_t       mainprog:1,     /* True if this is the main program */
                        rtld:1,         /* True if this is the dynamic linker */
                        textrel:1,      /* True if there are relocations to
@@ -328,6 +313,7 @@
 extern Obj_Entry **_rtld_objtail;
 extern u_int _rtld_objcount;
 extern u_int _rtld_objloads;
+extern const uintptr_t _rtld_compat_obj[];
 extern Obj_Entry *_rtld_objmain;
 extern Obj_Entry _rtld_objself;
 extern Search_Path *_rtld_paths;



Home | Main Index | Thread Index | Old Index