On Thu, Oct 11, 2018 at 07:15:30PM +0200, Joerg Sonnenberger wrote: > On Wed, Oct 03, 2018 at 10:40:32PM +0200, Joerg Sonnenberger wrote: > > Otherwise I would strictly reduce the compatibility hack to the above > > mentioned five architectures. The difference is 132-256 Bytes in .data > > and a couple of relocations. > > The attached patch implements this. Testing from non-x86 users, > especially 64bit Big Endian would be welcome :) The follow-up step would > drop the logic from lib/csu that is nowadays redundant.
Update diff that keeps all definitions in one place. Joerg
diff -r 82d7ff0ec9c7 libexec/ld.elf_so/Makefile --- a/libexec/ld.elf_so/Makefile Wed Oct 10 14:57:31 2018 +0000 +++ b/libexec/ld.elf_so/Makefile Sun Oct 14 20:33:51 2018 +0200 @@ -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 82d7ff0ec9c7 libexec/ld.elf_so/compat.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libexec/ld.elf_so/compat.c Sun Oct 14 20:33:51 2018 +0200 @@ -0,0 +1,94 @@ +/* $NetBSD$ */ +/*- + * 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$"); + +#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 82d7ff0ec9c7 libexec/ld.elf_so/reloc.c --- a/libexec/ld.elf_so/reloc.c Wed Oct 10 14:57:31 2018 +0000 +++ b/libexec/ld.elf_so/reloc.c Sun Oct 14 20:33:51 2018 +0200 @@ -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 82d7ff0ec9c7 libexec/ld.elf_so/rtld.c --- a/libexec/ld.elf_so/rtld.c Wed Oct 10 14:57:31 2018 +0000 +++ b/libexec/ld.elf_so/rtld.c Sun Oct 14 20:33:51 2018 +0200 @@ -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 82d7ff0ec9c7 libexec/ld.elf_so/rtld.h --- a/libexec/ld.elf_so/rtld.h Wed Oct 10 14:57:31 2018 +0000 +++ b/libexec/ld.elf_so/rtld.h Sun Oct 14 20:33:51 2018 +0200 @@ -136,20 +136,11 @@ * * 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 -#define RTLD_VERSION 1 - typedef void (*fptr_t)(void); typedef struct Struct_Obj_Entry { - Elf32_Word magic; /* Magic number (sanity check) */ - Elf32_Word version; /* Version number of struct format */ - struct Struct_Obj_Entry *next; char *path; /* Pathname of underlying file (%) */ int refcount; @@ -186,7 +177,6 @@ #endif const Elf_Symindx *buckets; /* Hash table buckets array */ - unsigned long unused1; /* Used to be nbuckets */ const Elf_Symindx *chains; /* Hash table chain array */ unsigned long nchains; /* Number of chains */ @@ -196,18 +186,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 +306,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;