|
Packit |
6c4009 |
/* x86 CET initializers function.
|
|
Packit |
6c4009 |
Copyright (C) 2018 Free Software Foundation, Inc.
|
|
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 <unistd.h>
|
|
Packit |
6c4009 |
#include <errno.h>
|
|
Packit |
6c4009 |
#include <libintl.h>
|
|
Packit |
6c4009 |
#include <ldsodefs.h>
|
|
Packit |
6c4009 |
#include <dl-cet.h>
|
|
Packit Service |
8bbac7 |
#include <cet-tunables.h>
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK
|
|
Packit |
6c4009 |
are defined in <elf.h>, which are only available for C sources.
|
|
Packit |
6c4009 |
X86_FEATURE_1_IBT and X86_FEATURE_1_SHSTK are defined in <sysdep.h>
|
|
Packit |
6c4009 |
which are available for both C and asm sources. They must match. */
|
|
Packit |
6c4009 |
#if GNU_PROPERTY_X86_FEATURE_1_IBT != X86_FEATURE_1_IBT
|
|
Packit |
6c4009 |
# error GNU_PROPERTY_X86_FEATURE_1_IBT != X86_FEATURE_1_IBT
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
#if GNU_PROPERTY_X86_FEATURE_1_SHSTK != X86_FEATURE_1_SHSTK
|
|
Packit |
6c4009 |
# error GNU_PROPERTY_X86_FEATURE_1_SHSTK != X86_FEATURE_1_SHSTK
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
|
|
Packit Service |
8bbac7 |
static int
|
|
Packit Service |
8bbac7 |
dl_cet_mark_legacy_region (struct link_map *l)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
/* Mark PT_LOAD segments with PF_X in legacy code page bitmap. */
|
|
Packit Service |
8bbac7 |
size_t i, phnum = l->l_phnum;
|
|
Packit Service |
8bbac7 |
const ElfW(Phdr) *phdr = l->l_phdr;
|
|
Packit Service |
8bbac7 |
#ifdef __x86_64__
|
|
Packit Service |
8bbac7 |
typedef unsigned long long word_t;
|
|
Packit Service |
8bbac7 |
#else
|
|
Packit Service |
8bbac7 |
typedef unsigned long word_t;
|
|
Packit Service |
8bbac7 |
#endif
|
|
Packit Service |
8bbac7 |
unsigned int bits_to_set;
|
|
Packit Service |
8bbac7 |
word_t mask_to_set;
|
|
Packit Service |
8bbac7 |
#define BITS_PER_WORD (sizeof (word_t) * 8)
|
|
Packit Service |
8bbac7 |
#define BITMAP_FIRST_WORD_MASK(start) \
|
|
Packit Service |
8bbac7 |
(~((word_t) 0) << ((start) & (BITS_PER_WORD - 1)))
|
|
Packit Service |
8bbac7 |
#define BITMAP_LAST_WORD_MASK(nbits) \
|
|
Packit Service |
8bbac7 |
(~((word_t) 0) >> (-(nbits) & (BITS_PER_WORD - 1)))
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
word_t *bitmap = (word_t *) GL(dl_x86_legacy_bitmap)[0];
|
|
Packit Service |
8bbac7 |
word_t bitmap_size = GL(dl_x86_legacy_bitmap)[1];
|
|
Packit Service |
8bbac7 |
word_t *p;
|
|
Packit Service |
8bbac7 |
size_t page_size = GLRO(dl_pagesize);
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
for (i = 0; i < phnum; i++)
|
|
Packit Service |
8bbac7 |
if (phdr[i].p_type == PT_LOAD && (phdr[i].p_flags & PF_X))
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
/* One bit in legacy bitmap represents a page. */
|
|
Packit Service |
8bbac7 |
ElfW(Addr) start = (phdr[i].p_vaddr + l->l_addr) / page_size;
|
|
Packit Service |
8bbac7 |
ElfW(Addr) len = (phdr[i].p_memsz + page_size - 1) / page_size;
|
|
Packit Service |
8bbac7 |
ElfW(Addr) end = start + len;
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
if ((end / 8) > bitmap_size)
|
|
Packit Service |
8bbac7 |
return -EINVAL;
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
p = bitmap + (start / BITS_PER_WORD);
|
|
Packit Service |
8bbac7 |
bits_to_set = BITS_PER_WORD - (start % BITS_PER_WORD);
|
|
Packit Service |
8bbac7 |
mask_to_set = BITMAP_FIRST_WORD_MASK (start);
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
while (len >= bits_to_set)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
*p |= mask_to_set;
|
|
Packit Service |
8bbac7 |
len -= bits_to_set;
|
|
Packit Service |
8bbac7 |
bits_to_set = BITS_PER_WORD;
|
|
Packit Service |
8bbac7 |
mask_to_set = ~((word_t) 0);
|
|
Packit Service |
8bbac7 |
p++;
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
if (len)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
mask_to_set &= BITMAP_LAST_WORD_MASK (end);
|
|
Packit Service |
8bbac7 |
*p |= mask_to_set;
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
return 0;
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
|
|
Packit |
6c4009 |
/* Check if object M is compatible with CET. */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
static void
|
|
Packit |
6c4009 |
dl_cet_check (struct link_map *m, const char *program)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
/* Check how IBT should be enabled. */
|
|
Packit Service |
8bbac7 |
unsigned int enable_ibt_type
|
|
Packit Service |
8bbac7 |
= GL(dl_x86_feature_1)[1] & ((1 << CET_MAX) - 1);
|
|
Packit |
6c4009 |
/* Check how SHSTK should be enabled. */
|
|
Packit Service |
8bbac7 |
unsigned int enable_shstk_type
|
|
Packit Service |
8bbac7 |
= ((GL(dl_x86_feature_1)[1] >> CET_MAX) & ((1 << CET_MAX) - 1));
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* No legacy object check if both IBT and SHSTK are always on. */
|
|
Packit Service |
8bbac7 |
if (enable_ibt_type == CET_ALWAYS_ON
|
|
Packit Service |
8bbac7 |
&& enable_shstk_type == CET_ALWAYS_ON)
|
|
Packit |
6c4009 |
return;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Check if IBT is enabled by kernel. */
|
|
Packit |
6c4009 |
bool ibt_enabled
|
|
Packit Service |
8bbac7 |
= (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_IBT) != 0;
|
|
Packit |
6c4009 |
/* Check if SHSTK is enabled by kernel. */
|
|
Packit |
6c4009 |
bool shstk_enabled
|
|
Packit Service |
8bbac7 |
= (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (ibt_enabled || shstk_enabled)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
struct link_map *l = NULL;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Check if IBT and SHSTK are enabled in object. */
|
|
Packit |
6c4009 |
bool enable_ibt = (ibt_enabled
|
|
Packit Service |
8bbac7 |
&& enable_ibt_type != CET_ALWAYS_OFF);
|
|
Packit |
6c4009 |
bool enable_shstk = (shstk_enabled
|
|
Packit Service |
8bbac7 |
&& enable_shstk_type != CET_ALWAYS_OFF);
|
|
Packit |
6c4009 |
if (program)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
/* Enable IBT and SHSTK only if they are enabled in executable.
|
|
Packit |
6c4009 |
NB: IBT and SHSTK may be disabled by environment variable:
|
|
Packit |
6c4009 |
|
|
Packit Service |
8bbac7 |
GLIBC_TUNABLES=glibc.tune.hwcaps=-IBT,-SHSTK
|
|
Packit |
6c4009 |
*/
|
|
Packit Service |
60411f |
enable_ibt &= (HAS_CPU_FEATURE (IBT)
|
|
Packit Service |
8bbac7 |
&& (enable_ibt_type == CET_ALWAYS_ON
|
|
Packit |
6c4009 |
|| (m->l_cet & lc_ibt) != 0));
|
|
Packit Service |
60411f |
enable_shstk &= (HAS_CPU_FEATURE (SHSTK)
|
|
Packit Service |
8bbac7 |
&& (enable_shstk_type == CET_ALWAYS_ON
|
|
Packit |
6c4009 |
|| (m->l_cet & lc_shstk) != 0));
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* ld.so is CET-enabled by kernel. But shared objects may not
|
|
Packit |
6c4009 |
support IBT nor SHSTK. */
|
|
Packit |
6c4009 |
if (enable_ibt || enable_shstk)
|
|
Packit |
6c4009 |
{
|
|
Packit Service |
8bbac7 |
int res;
|
|
Packit |
6c4009 |
unsigned int i;
|
|
Packit Service |
8bbac7 |
unsigned int first_legacy, last_legacy;
|
|
Packit Service |
8bbac7 |
bool need_legacy_bitmap = false;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
i = m->l_searchlist.r_nlist;
|
|
Packit |
6c4009 |
while (i-- > 0)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
/* Check each shared object to see if IBT and SHSTK are
|
|
Packit |
6c4009 |
enabled. */
|
|
Packit |
6c4009 |
l = m->l_initfini[i];
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (l->l_init_called)
|
|
Packit |
6c4009 |
continue;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#ifdef SHARED
|
|
Packit |
6c4009 |
/* Skip CET check for ld.so since ld.so is CET-enabled.
|
|
Packit |
6c4009 |
CET will be disabled later if CET isn't enabled in
|
|
Packit |
6c4009 |
executable. */
|
|
Packit |
6c4009 |
if (l == &GL(dl_rtld_map)
|
|
Packit |
6c4009 |
|| l->l_real == &GL(dl_rtld_map)
|
|
Packit |
6c4009 |
|| (program && l == m))
|
|
Packit |
6c4009 |
continue;
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
|
|
Packit Service |
8bbac7 |
if (enable_ibt
|
|
Packit Service |
8bbac7 |
&& enable_ibt_type != CET_ALWAYS_ON
|
|
Packit Service |
8bbac7 |
&& !(l->l_cet & lc_ibt))
|
|
Packit |
6c4009 |
{
|
|
Packit Service |
8bbac7 |
/* Remember the first and last legacy objects. */
|
|
Packit Service |
8bbac7 |
if (!need_legacy_bitmap)
|
|
Packit Service |
8bbac7 |
last_legacy = i;
|
|
Packit Service |
8bbac7 |
first_legacy = i;
|
|
Packit Service |
8bbac7 |
need_legacy_bitmap = true;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* SHSTK is enabled only if it is enabled in executable as
|
|
Packit |
6c4009 |
well as all shared objects. */
|
|
Packit Service |
8bbac7 |
enable_shstk &= (enable_shstk_type == CET_ALWAYS_ON
|
|
Packit |
6c4009 |
|| (l->l_cet & lc_shstk) != 0);
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
if (need_legacy_bitmap)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
if (GL(dl_x86_legacy_bitmap)[0])
|
|
Packit Service |
6de65a |
{
|
|
Packit Service |
8bbac7 |
/* Change legacy bitmap to writable. */
|
|
Packit Service |
8bbac7 |
if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0],
|
|
Packit Service |
8bbac7 |
GL(dl_x86_legacy_bitmap)[1],
|
|
Packit Service |
8bbac7 |
PROT_READ | PROT_WRITE) < 0)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
mprotect_failure:
|
|
Packit Service |
8bbac7 |
if (program)
|
|
Packit Service |
8bbac7 |
_dl_fatal_printf ("%s: mprotect legacy bitmap failed\n",
|
|
Packit Service |
8bbac7 |
l->l_name);
|
|
Packit Service |
8bbac7 |
else
|
|
Packit Service |
8bbac7 |
_dl_signal_error (EINVAL, l->l_name, "dlopen",
|
|
Packit Service |
8bbac7 |
N_("mprotect legacy bitmap failed"));
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
6de65a |
}
|
|
Packit Service |
8bbac7 |
else
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
/* Allocate legacy bitmap. */
|
|
Packit Service |
8bbac7 |
int res = dl_cet_allocate_legacy_bitmap
|
|
Packit Service |
8bbac7 |
(GL(dl_x86_legacy_bitmap));
|
|
Packit Service |
8bbac7 |
if (res != 0)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
if (program)
|
|
Packit Service |
8bbac7 |
_dl_fatal_printf ("%s: legacy bitmap isn't available\n",
|
|
Packit Service |
8bbac7 |
l->l_name);
|
|
Packit Service |
8bbac7 |
else
|
|
Packit Service |
8bbac7 |
_dl_signal_error (EINVAL, l->l_name, "dlopen",
|
|
Packit Service |
8bbac7 |
N_("legacy bitmap isn't available"));
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
/* Put legacy shared objects in legacy bitmap. */
|
|
Packit Service |
8bbac7 |
for (i = first_legacy; i <= last_legacy; i++)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
l = m->l_initfini[i];
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
if (l->l_init_called || (l->l_cet & lc_ibt))
|
|
Packit Service |
8bbac7 |
continue;
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
#ifdef SHARED
|
|
Packit Service |
8bbac7 |
if (l == &GL(dl_rtld_map)
|
|
Packit Service |
8bbac7 |
|| l->l_real == &GL(dl_rtld_map)
|
|
Packit Service |
8bbac7 |
|| (program && l == m))
|
|
Packit Service |
8bbac7 |
continue;
|
|
Packit Service |
8bbac7 |
#endif
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
/* If IBT is enabled in executable and IBT isn't enabled
|
|
Packit Service |
8bbac7 |
in this shard object, mark PT_LOAD segments with PF_X
|
|
Packit Service |
8bbac7 |
in legacy code page bitmap. */
|
|
Packit Service |
8bbac7 |
res = dl_cet_mark_legacy_region (l);
|
|
Packit Service |
8bbac7 |
if (res != 0)
|
|
Packit Service |
8bbac7 |
{
|
|
Packit Service |
8bbac7 |
if (program)
|
|
Packit Service |
8bbac7 |
_dl_fatal_printf ("%s: failed to mark legacy code region\n",
|
|
Packit Service |
8bbac7 |
l->l_name);
|
|
Packit Service |
8bbac7 |
else
|
|
Packit Service |
8bbac7 |
_dl_signal_error (-res, l->l_name, "dlopen",
|
|
Packit Service |
8bbac7 |
N_("failed to mark legacy code region"));
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
}
|
|
Packit Service |
8bbac7 |
|
|
Packit Service |
8bbac7 |
/* Change legacy bitmap to read-only. */
|
|
Packit Service |
8bbac7 |
if (__mprotect ((void *) GL(dl_x86_legacy_bitmap)[0],
|
|
Packit Service |
8bbac7 |
GL(dl_x86_legacy_bitmap)[1], PROT_READ) < 0)
|
|
Packit Service |
8bbac7 |
goto mprotect_failure;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
bool cet_feature_changed = false;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (enable_ibt != ibt_enabled || enable_shstk != shstk_enabled)
|
|
Packit |
6c4009 |
{
|
|
Packit Service |
8bbac7 |
if (!program
|
|
Packit Service |
8bbac7 |
&& enable_shstk_type != CET_PERMISSIVE)
|
|
Packit |
6c4009 |
{
|
|
Packit Service |
8bbac7 |
/* When SHSTK is enabled, we can't dlopening a shared
|
|
Packit Service |
8bbac7 |
object without SHSTK. */
|
|
Packit Service |
8bbac7 |
if (enable_shstk != shstk_enabled)
|
|
Packit Service |
8bbac7 |
_dl_signal_error (EINVAL, l->l_name, "dlopen",
|
|
Packit Service |
8bbac7 |
N_("shadow stack isn't enabled"));
|
|
Packit Service |
8bbac7 |
return;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Disable IBT and/or SHSTK if they are enabled by kernel, but
|
|
Packit |
6c4009 |
disabled in executable or shared objects. */
|
|
Packit |
6c4009 |
unsigned int cet_feature = 0;
|
|
Packit |
6c4009 |
|
|
Packit Service |
8bbac7 |
/* Disable IBT only during program startup. */
|
|
Packit Service |
8bbac7 |
if (program && !enable_ibt)
|
|
Packit |
6c4009 |
cet_feature |= GNU_PROPERTY_X86_FEATURE_1_IBT;
|
|
Packit |
6c4009 |
if (!enable_shstk)
|
|
Packit |
6c4009 |
cet_feature |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
int res = dl_cet_disable_cet (cet_feature);
|
|
Packit |
6c4009 |
if (res != 0)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
if (program)
|
|
Packit |
6c4009 |
_dl_fatal_printf ("%s: can't disable CET\n", program);
|
|
Packit |
6c4009 |
else
|
|
Packit Service |
8bbac7 |
_dl_signal_error (-res, l->l_name, "dlopen",
|
|
Packit Service |
8bbac7 |
N_("can't disable CET"));
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Clear the disabled bits in dl_x86_feature_1. */
|
|
Packit Service |
8bbac7 |
GL(dl_x86_feature_1)[0] &= ~cet_feature;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
cet_feature_changed = true;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#ifdef SHARED
|
|
Packit Service |
8bbac7 |
if (program
|
|
Packit Service |
8bbac7 |
&& (!shstk_enabled
|
|
Packit Service |
8bbac7 |
|| enable_shstk_type != CET_PERMISSIVE)
|
|
Packit Service |
8bbac7 |
&& (ibt_enabled || shstk_enabled))
|
|
Packit |
6c4009 |
{
|
|
Packit Service |
8bbac7 |
/* Lock CET if IBT or SHSTK is enabled in executable. Don't
|
|
Packit Service |
8bbac7 |
lock CET if SHSTK is enabled permissively. */
|
|
Packit Service |
8bbac7 |
int res = dl_cet_lock_cet ();
|
|
Packit Service |
8bbac7 |
if (res != 0)
|
|
Packit Service |
8bbac7 |
_dl_fatal_printf ("%s: can't lock CET\n", program);
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
cet_feature_changed = true;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
#endif
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
if (cet_feature_changed)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
unsigned int feature_1 = 0;
|
|
Packit |
6c4009 |
if (enable_ibt)
|
|
Packit |
6c4009 |
feature_1 |= GNU_PROPERTY_X86_FEATURE_1_IBT;
|
|
Packit |
6c4009 |
if (enable_shstk)
|
|
Packit |
6c4009 |
feature_1 |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
|
|
Packit |
6c4009 |
struct pthread *self = THREAD_SELF;
|
|
Packit |
6c4009 |
THREAD_SETMEM (self, header.feature_1, feature_1);
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
void
|
|
Packit |
6c4009 |
_dl_cet_open_check (struct link_map *l)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
dl_cet_check (l, NULL);
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#ifdef SHARED
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
# ifndef LINKAGE
|
|
Packit |
6c4009 |
# define LINKAGE
|
|
Packit |
6c4009 |
# endif
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
LINKAGE
|
|
Packit |
6c4009 |
void
|
|
Packit |
6c4009 |
_dl_cet_check (struct link_map *main_map, const char *program)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
dl_cet_check (main_map, program);
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
#endif /* SHARED */
|