PowerPC: use _dl_static_init to set GLRO(gl_pagesize)

This patch fixes dlfcn/tststatic5 for PowerPC where pagesize
variable was not properly initialized in certain cases. This patch
is based on other architecture code.
(cherry picked from commit 7b1f8b581f)
This commit is contained in:
Adhemerval Zanella 2013-07-23 07:39:57 -05:00 committed by Ryan S. Arnold
parent 5c616c0a75
commit a06663ebed
5 changed files with 137 additions and 0 deletions

View File

@ -1,3 +1,11 @@
2013-07-23 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/dl-static.c: New file to support
variable page size.
* sysdeps/unix/sysv/linux/powerpc/ldsodefs.h: Likewise.
* sysdeps/unix/sysv/linux/powerpc/Makefile: Build dl-static in elf.
* sysdeps/unix/sysv/linux/powerpc/Versions: Add _dl_var_init.
2013-06-20 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
* config.h.in (HAVE_CC_INHIBIT_LOOP_TO_LIBCALL): New define.

View File

@ -15,6 +15,12 @@ endif
ifeq ($(subdir),elf)
sysdep_routines += dl-vdso
ifeq ($(build-shared),yes)
# This is needed for DSO loading from static binaries.
sysdep-dl-routines += dl-static
sysdep_routines += dl-static
sysdep-rtld-routines += dl-static
endif
endif
ifeq ($(subdir),misc)

View File

@ -1,3 +1,9 @@
ld {
GLIBC_PRIVATE {
# used for loading by static libraries
_dl_var_init;
}
}
libc {
GLIBC_PRIVATE {
__vdso_get_tbfreq;

View File

@ -0,0 +1,84 @@
/* Variable initialization. PowerPC version.
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#include <ldsodefs.h>
#ifdef SHARED
void
_dl_var_init (void *array[])
{
/* It has to match "variables" below. */
enum
{
DL_PAGESIZE = 0
};
GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]);
}
#else
static void *variables[] =
{
&GLRO(dl_pagesize)
};
static void
_dl_unprotect_relro (struct link_map *l)
{
ElfW(Addr) start = ((l->l_addr + l->l_relro_addr)
& ~(GLRO(dl_pagesize) - 1));
ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size)
& ~(GLRO(dl_pagesize) - 1));
if (start != end)
__mprotect ((void *) start, end - start, PROT_READ | PROT_WRITE);
}
void
_dl_static_init (struct link_map *l)
{
struct link_map *rtld_map = l;
struct r_scope_elem **scope;
const ElfW(Sym) *ref = NULL;
lookup_t loadbase;
void (*f) (void *[]);
size_t i;
loadbase = _dl_lookup_symbol_x ("_dl_var_init", l, &ref, l->l_local_scope,
NULL, 0, 1, NULL);
for (scope = l->l_local_scope; *scope != NULL; scope++)
for (i = 0; i < (*scope)->r_nlist; i++)
if ((*scope)->r_list[i] == loadbase)
{
rtld_map = (*scope)->r_list[i];
break;
}
if (ref != NULL)
{
f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref);
_dl_unprotect_relro (rtld_map);
f (variables);
_dl_protect_relro (rtld_map);
}
}
#endif

View File

@ -0,0 +1,33 @@
/* Run-time dynamic linker data structures for loaded ELF shared objects.
PowerPC version.
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _LDSODEFS_H
/* Get the real definitions. */
#include_next <ldsodefs.h>
/* Now define our stuff. */
/* We need special support to initialize DSO loaded for statically linked
binaries. */
extern void _dl_static_init (struct link_map *map);
#undef DL_STATIC_INIT
#define DL_STATIC_INIT(map) _dl_static_init (map)
#endif /* ldsodefs.h */