Blame sysdeps/unix/sysv/linux/powerpc/dl-static.c

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