mirror of git://sourceware.org/git/glibc.git
Merge branch release/2.30/master into ibm/2.30/master
This commit is contained in:
commit
903f0b6942
3
NEWS
3
NEWS
|
@ -34,6 +34,7 @@ CVE-2020-29562: An assertion failure has been fixed in the iconv function
|
||||||
|
|
||||||
The following bugs are resolved with this release:
|
The following bugs are resolved with this release:
|
||||||
|
|
||||||
|
[20019] NULL pointer dereference in libc.so.6 IFUNC due to uninitialized GOT
|
||||||
[20543] Please move from .gnu.linkonce to comdat
|
[20543] Please move from .gnu.linkonce to comdat
|
||||||
[23296] Data race in setting function descriptor during lazy binding
|
[23296] Data race in setting function descriptor during lazy binding
|
||||||
[23518] login: Remove utmp backend jump tables
|
[23518] login: Remove utmp backend jump tables
|
||||||
|
@ -64,6 +65,8 @@ The following bugs are resolved with this release:
|
||||||
[25933] Off by one error in __strncmp_avx2
|
[25933] Off by one error in __strncmp_avx2
|
||||||
[25966] Incorrect access of __x86_shared_non_temporal_threshold for x32
|
[25966] Incorrect access of __x86_shared_non_temporal_threshold for x32
|
||||||
[25976] nss_compat: internal_end*ent may clobber errno, hiding ERANGE
|
[25976] nss_compat: internal_end*ent may clobber errno, hiding ERANGE
|
||||||
|
[27130] "rep movsb" performance issue
|
||||||
|
[27177] GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on doesn't work
|
||||||
|
|
||||||
|
|
||||||
Version 2.30
|
Version 2.30
|
||||||
|
|
|
@ -1302,6 +1302,8 @@ CFLAGS-ifuncmain7pie.c += $(pie-ccflag)
|
||||||
CFLAGS-ifuncmain9pie.c += $(pie-ccflag)
|
CFLAGS-ifuncmain9pie.c += $(pie-ccflag)
|
||||||
CFLAGS-tst-ifunc-textrel.c += $(pic-ccflag)
|
CFLAGS-tst-ifunc-textrel.c += $(pic-ccflag)
|
||||||
|
|
||||||
|
LDFLAGS-ifuncmain6pie = -Wl,-z,lazy
|
||||||
|
|
||||||
$(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so
|
$(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so
|
||||||
$(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o
|
$(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o
|
||||||
$(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so
|
$(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "ifunc-sel.h"
|
#include "ifunc-sel.h"
|
||||||
|
|
||||||
typedef int (*foo_p) (void);
|
typedef int (*foo_p) (void);
|
||||||
extern foo_p foo_ptr;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
one (void)
|
one (void)
|
||||||
|
@ -28,20 +27,17 @@ foo_ifunc (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int foo (void);
|
extern int foo (void);
|
||||||
extern foo_p get_foo (void);
|
extern int call_foo (void);
|
||||||
extern foo_p get_foo_p (void);
|
extern foo_p get_foo_p (void);
|
||||||
|
|
||||||
foo_p my_foo_ptr = foo;
|
foo_p foo_ptr = foo;
|
||||||
|
|
||||||
int
|
int
|
||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
foo_p p;
|
foo_p p;
|
||||||
|
|
||||||
p = get_foo ();
|
if (call_foo () != -30)
|
||||||
if (p != foo)
|
|
||||||
abort ();
|
|
||||||
if ((*p) () != -30)
|
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
p = get_foo_p ();
|
p = get_foo_p ();
|
||||||
|
@ -52,12 +48,8 @@ main (void)
|
||||||
|
|
||||||
if (foo_ptr != foo)
|
if (foo_ptr != foo)
|
||||||
abort ();
|
abort ();
|
||||||
if (my_foo_ptr != foo)
|
|
||||||
abort ();
|
|
||||||
if ((*foo_ptr) () != -30)
|
if ((*foo_ptr) () != -30)
|
||||||
abort ();
|
abort ();
|
||||||
if ((*my_foo_ptr) () != -30)
|
|
||||||
abort ();
|
|
||||||
if (foo () != -30)
|
if (foo () != -30)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ extern int foo (void);
|
||||||
|
|
||||||
typedef int (*foo_p) (void);
|
typedef int (*foo_p) (void);
|
||||||
|
|
||||||
foo_p foo_ptr = foo;
|
extern foo_p foo_ptr;
|
||||||
|
|
||||||
foo_p
|
foo_p
|
||||||
get_foo_p (void)
|
get_foo_p (void)
|
||||||
|
@ -12,8 +12,8 @@ get_foo_p (void)
|
||||||
return foo_ptr;
|
return foo_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
foo_p
|
int
|
||||||
get_foo (void)
|
call_foo (void)
|
||||||
{
|
{
|
||||||
return foo;
|
return foo ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ modules.so := $(addsuffix .so, $(modules))
|
||||||
ifeq (yes,$(build-shared))
|
ifeq (yes,$(build-shared))
|
||||||
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
|
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
|
||||||
tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
|
tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
|
||||||
bug-iconv10 bug-iconv11 bug-iconv12
|
bug-iconv10 bug-iconv11 bug-iconv12 bug-iconv14
|
||||||
ifeq ($(have-thread-library),yes)
|
ifeq ($(have-thread-library),yes)
|
||||||
tests += bug-iconv3
|
tests += bug-iconv3
|
||||||
endif
|
endif
|
||||||
|
@ -316,6 +316,8 @@ $(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \
|
||||||
$(addprefix $(objpfx),$(modules.so))
|
$(addprefix $(objpfx),$(modules.so))
|
||||||
$(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
|
$(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
|
||||||
$(addprefix $(objpfx),$(modules.so))
|
$(addprefix $(objpfx),$(modules.so))
|
||||||
|
$(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \
|
||||||
|
$(addprefix $(objpfx),$(modules.so))
|
||||||
|
|
||||||
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
|
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
|
||||||
$(addprefix $(objpfx),$(modules.so)) \
|
$(addprefix $(objpfx),$(modules.so)) \
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/* Assertion in ISO-2022-JP-3 due to two-character sequence (bug 27256).
|
||||||
|
Copyright (C) 2021 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
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <iconv.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
|
||||||
|
/* Use an escape sequence to return to the initial state. */
|
||||||
|
static void
|
||||||
|
with_escape_sequence (void)
|
||||||
|
{
|
||||||
|
iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
|
||||||
|
TEST_VERIFY_EXIT (c != (iconv_t) -1);
|
||||||
|
|
||||||
|
char in[] = "\e$(O+D\e(B";
|
||||||
|
char *inbuf = in;
|
||||||
|
size_t inleft = strlen (in);
|
||||||
|
char out[3]; /* Space for one output character. */
|
||||||
|
char *outbuf;
|
||||||
|
size_t outleft;
|
||||||
|
|
||||||
|
outbuf = out;
|
||||||
|
outleft = sizeof (out);
|
||||||
|
TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
|
||||||
|
TEST_COMPARE (errno, E2BIG);
|
||||||
|
TEST_COMPARE (inleft, 3);
|
||||||
|
TEST_COMPARE (inbuf - in, strlen (in) - 3);
|
||||||
|
TEST_COMPARE (outleft, sizeof (out) - 2);
|
||||||
|
TEST_COMPARE (outbuf - out, 2);
|
||||||
|
TEST_COMPARE (out[0] & 0xff, 0xc3);
|
||||||
|
TEST_COMPARE (out[1] & 0xff, 0xa6);
|
||||||
|
|
||||||
|
/* Return to the initial shift state, producing the pending
|
||||||
|
character. */
|
||||||
|
outbuf = out;
|
||||||
|
outleft = sizeof (out);
|
||||||
|
TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), 0);
|
||||||
|
TEST_COMPARE (inleft, 0);
|
||||||
|
TEST_COMPARE (inbuf - in, strlen (in));
|
||||||
|
TEST_COMPARE (outleft, sizeof (out) - 2);
|
||||||
|
TEST_COMPARE (outbuf - out, 2);
|
||||||
|
TEST_COMPARE (out[0] & 0xff, 0xcc);
|
||||||
|
TEST_COMPARE (out[1] & 0xff, 0x80);
|
||||||
|
|
||||||
|
/* Nothing should be flushed the second time. */
|
||||||
|
outbuf = out;
|
||||||
|
outleft = sizeof (out);
|
||||||
|
TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
|
||||||
|
TEST_COMPARE (outleft, sizeof (out));
|
||||||
|
TEST_COMPARE (outbuf - out, 0);
|
||||||
|
TEST_COMPARE (out[0] & 0xff, 0xcc);
|
||||||
|
TEST_COMPARE (out[1] & 0xff, 0x80);
|
||||||
|
|
||||||
|
TEST_COMPARE (iconv_close (c), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use an explicit flush to return to the initial state. */
|
||||||
|
static void
|
||||||
|
with_flush (void)
|
||||||
|
{
|
||||||
|
iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
|
||||||
|
TEST_VERIFY_EXIT (c != (iconv_t) -1);
|
||||||
|
|
||||||
|
char in[] = "\e$(O+D";
|
||||||
|
char *inbuf = in;
|
||||||
|
size_t inleft = strlen (in);
|
||||||
|
char out[3]; /* Space for one output character. */
|
||||||
|
char *outbuf;
|
||||||
|
size_t outleft;
|
||||||
|
|
||||||
|
outbuf = out;
|
||||||
|
outleft = sizeof (out);
|
||||||
|
TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
|
||||||
|
TEST_COMPARE (errno, E2BIG);
|
||||||
|
TEST_COMPARE (inleft, 0);
|
||||||
|
TEST_COMPARE (inbuf - in, strlen (in));
|
||||||
|
TEST_COMPARE (outleft, sizeof (out) - 2);
|
||||||
|
TEST_COMPARE (outbuf - out, 2);
|
||||||
|
TEST_COMPARE (out[0] & 0xff, 0xc3);
|
||||||
|
TEST_COMPARE (out[1] & 0xff, 0xa6);
|
||||||
|
|
||||||
|
/* Flush the pending character. */
|
||||||
|
outbuf = out;
|
||||||
|
outleft = sizeof (out);
|
||||||
|
TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
|
||||||
|
TEST_COMPARE (outleft, sizeof (out) - 2);
|
||||||
|
TEST_COMPARE (outbuf - out, 2);
|
||||||
|
TEST_COMPARE (out[0] & 0xff, 0xcc);
|
||||||
|
TEST_COMPARE (out[1] & 0xff, 0x80);
|
||||||
|
|
||||||
|
/* Nothing should be flushed the second time. */
|
||||||
|
outbuf = out;
|
||||||
|
outleft = sizeof (out);
|
||||||
|
TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
|
||||||
|
TEST_COMPARE (outleft, sizeof (out));
|
||||||
|
TEST_COMPARE (outbuf - out, 0);
|
||||||
|
TEST_COMPARE (out[0] & 0xff, 0xcc);
|
||||||
|
TEST_COMPARE (out[1] & 0xff, 0x80);
|
||||||
|
|
||||||
|
TEST_COMPARE (iconv_close (c), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
with_escape_sequence ();
|
||||||
|
with_flush ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <support/test-driver.c>
|
|
@ -67,23 +67,34 @@ enum
|
||||||
CURRENT_SEL_MASK = 7 << 3
|
CURRENT_SEL_MASK = 7 << 3
|
||||||
};
|
};
|
||||||
|
|
||||||
/* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the state
|
/* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the
|
||||||
also contains the last two bytes to be output, shifted by 6 bits, and a
|
state also contains the last two bytes to be output, shifted by 6
|
||||||
one-bit indicator whether they must be preceded by the shift sequence,
|
bits, and a one-bit indicator whether they must be preceded by the
|
||||||
in bit 22. */
|
shift sequence, in bit 22. During ISO-2022-JP-3 to UCS-4
|
||||||
|
conversion, COUNT may also contain a non-zero pending wide
|
||||||
|
character, shifted by six bits. This happens for certain inputs in
|
||||||
|
JISX0213_1_2004_set and JISX0213_2_set if the second wide character
|
||||||
|
in a combining sequence cannot be written because the buffer is
|
||||||
|
full. */
|
||||||
|
|
||||||
/* Since this is a stateful encoding we have to provide code which resets
|
/* Since this is a stateful encoding we have to provide code which resets
|
||||||
the output state to the initial state. This has to be done during the
|
the output state to the initial state. This has to be done during the
|
||||||
flushing. */
|
flushing. */
|
||||||
#define EMIT_SHIFT_TO_INIT \
|
#define EMIT_SHIFT_TO_INIT \
|
||||||
if ((data->__statep->__count & ~7) != ASCII_set) \
|
if (data->__statep->__count != ASCII_set) \
|
||||||
{ \
|
{ \
|
||||||
if (FROM_DIRECTION) \
|
if (FROM_DIRECTION) \
|
||||||
{ \
|
{ \
|
||||||
/* It's easy, we don't have to emit anything, we just reset the \
|
if (__glibc_likely (outbuf + 4 <= outend)) \
|
||||||
state for the input. */ \
|
{ \
|
||||||
data->__statep->__count &= 7; \
|
/* Write out the last character. */ \
|
||||||
data->__statep->__count |= ASCII_set; \
|
*((uint32_t *) outbuf) = data->__statep->__count >> 6; \
|
||||||
|
outbuf += sizeof (uint32_t); \
|
||||||
|
data->__statep->__count = ASCII_set; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
/* We don't have enough room in the output buffer. */ \
|
||||||
|
status = __GCONV_FULL_OUTPUT; \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
|
@ -151,7 +162,21 @@ enum
|
||||||
#define LOOPFCT FROM_LOOP
|
#define LOOPFCT FROM_LOOP
|
||||||
#define BODY \
|
#define BODY \
|
||||||
{ \
|
{ \
|
||||||
uint32_t ch = *inptr; \
|
uint32_t ch; \
|
||||||
|
\
|
||||||
|
/* Output any pending character. */ \
|
||||||
|
ch = set >> 6; \
|
||||||
|
if (__glibc_unlikely (ch != 0)) \
|
||||||
|
{ \
|
||||||
|
put32 (outptr, ch); \
|
||||||
|
outptr += 4; \
|
||||||
|
/* Remove the pending character, but preserve state bits. */ \
|
||||||
|
set &= (1 << 6) - 1; \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* Otherwise read the next input byte. */ \
|
||||||
|
ch = *inptr; \
|
||||||
\
|
\
|
||||||
/* Recognize escape sequences. */ \
|
/* Recognize escape sequences. */ \
|
||||||
if (__glibc_unlikely (ch == ESC)) \
|
if (__glibc_unlikely (ch == ESC)) \
|
||||||
|
@ -297,21 +322,25 @@ enum
|
||||||
uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0]; \
|
uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0]; \
|
||||||
uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1]; \
|
uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1]; \
|
||||||
\
|
\
|
||||||
|
inptr += 2; \
|
||||||
|
\
|
||||||
|
put32 (outptr, u1); \
|
||||||
|
outptr += 4; \
|
||||||
|
\
|
||||||
/* See whether we have room for two characters. */ \
|
/* See whether we have room for two characters. */ \
|
||||||
if (outptr + 8 <= outend) \
|
if (outptr + 4 <= outend) \
|
||||||
{ \
|
{ \
|
||||||
inptr += 2; \
|
|
||||||
put32 (outptr, u1); \
|
|
||||||
outptr += 4; \
|
|
||||||
put32 (outptr, u2); \
|
put32 (outptr, u2); \
|
||||||
outptr += 4; \
|
outptr += 4; \
|
||||||
continue; \
|
continue; \
|
||||||
} \
|
} \
|
||||||
else \
|
\
|
||||||
{ \
|
/* Otherwise store only the first character now, and \
|
||||||
result = __GCONV_FULL_OUTPUT; \
|
put the second one into the queue. */ \
|
||||||
break; \
|
set |= u2 << 6; \
|
||||||
} \
|
/* Tell the caller why we terminate the loop. */ \
|
||||||
|
result = __GCONV_FULL_OUTPUT; \
|
||||||
|
break; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
inptr += 2; \
|
inptr += 2; \
|
||||||
|
|
|
@ -248,7 +248,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||||
: NULL);
|
: NULL);
|
||||||
ndomain = (ndomain ? newbuf + ndomaindiff
|
ndomain = (ndomain ? newbuf + ndomaindiff
|
||||||
: NULL);
|
: NULL);
|
||||||
buffer = newbuf;
|
*tofreep = buffer = newbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
nhost = memcpy (buffer + bufused,
|
nhost = memcpy (buffer + bufused,
|
||||||
|
@ -319,7 +319,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
|
||||||
else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
|
else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
|
||||||
{
|
{
|
||||||
buflen *= 2;
|
buflen *= 2;
|
||||||
buffer = xrealloc (buffer, buflen);
|
*tofreep = buffer = xrealloc (buffer, buflen);
|
||||||
}
|
}
|
||||||
else if (status == NSS_STATUS_RETURN
|
else if (status == NSS_STATUS_RETURN
|
||||||
|| status == NSS_STATUS_NOTFOUND
|
|| status == NSS_STATUS_NOTFOUND
|
||||||
|
|
|
@ -338,16 +338,22 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||||
{
|
{
|
||||||
# ifndef RTLD_BOOTSTRAP
|
# ifndef RTLD_BOOTSTRAP
|
||||||
if (sym_map != map
|
if (sym_map != map
|
||||||
&& sym_map->l_type != lt_executable
|
|
||||||
&& !sym_map->l_relocated)
|
&& !sym_map->l_relocated)
|
||||||
{
|
{
|
||||||
const char *strtab
|
const char *strtab
|
||||||
= (const char *) D_PTR (map, l_info[DT_STRTAB]);
|
= (const char *) D_PTR (map, l_info[DT_STRTAB]);
|
||||||
_dl_error_printf ("\
|
if (sym_map->l_type == lt_executable)
|
||||||
|
_dl_fatal_printf ("\
|
||||||
|
%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
|
||||||
|
and creates an unsatisfiable circular dependency.\n",
|
||||||
|
RTLD_PROGNAME, strtab + refsym->st_name,
|
||||||
|
map->l_name);
|
||||||
|
else
|
||||||
|
_dl_error_printf ("\
|
||||||
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
|
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
|
||||||
RTLD_PROGNAME, map->l_name,
|
RTLD_PROGNAME, map->l_name,
|
||||||
sym_map->l_name,
|
sym_map->l_name,
|
||||||
strtab + refsym->st_name);
|
strtab + refsym->st_name);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
value = ((Elf32_Addr (*) (void)) value) ();
|
value = ((Elf32_Addr (*) (void)) value) ();
|
||||||
|
|
|
@ -12,6 +12,12 @@ endif
|
||||||
ifeq ($(subdir),setjmp)
|
ifeq ($(subdir),setjmp)
|
||||||
gen-as-const-headers += jmp_buf-ssp.sym
|
gen-as-const-headers += jmp_buf-ssp.sym
|
||||||
sysdep_routines += __longjmp_cancel
|
sysdep_routines += __longjmp_cancel
|
||||||
|
ifneq ($(enable-cet),no)
|
||||||
|
ifneq ($(have-tunables),no)
|
||||||
|
tests += tst-setjmp-cet
|
||||||
|
tst-setjmp-cet-ENV = GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on
|
||||||
|
endif
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(enable-cet),yes)
|
ifeq ($(enable-cet),yes)
|
||||||
|
|
|
@ -105,7 +105,11 @@ dl_cet_check (struct link_map *m, const char *program)
|
||||||
/* No legacy object check if both IBT and SHSTK are always on. */
|
/* No legacy object check if both IBT and SHSTK are always on. */
|
||||||
if (enable_ibt_type == CET_ALWAYS_ON
|
if (enable_ibt_type == CET_ALWAYS_ON
|
||||||
&& enable_shstk_type == CET_ALWAYS_ON)
|
&& enable_shstk_type == CET_ALWAYS_ON)
|
||||||
return;
|
{
|
||||||
|
THREAD_SETMEM (THREAD_SELF, header.feature_1,
|
||||||
|
GL(dl_x86_feature_1)[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if IBT is enabled by kernel. */
|
/* Check if IBT is enabled by kernel. */
|
||||||
bool ibt_enabled
|
bool ibt_enabled
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include <setjmp/tst-setjmp.c>
|
|
@ -315,16 +315,22 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
|
||||||
{
|
{
|
||||||
# ifndef RTLD_BOOTSTRAP
|
# ifndef RTLD_BOOTSTRAP
|
||||||
if (sym_map != map
|
if (sym_map != map
|
||||||
&& sym_map->l_type != lt_executable
|
|
||||||
&& !sym_map->l_relocated)
|
&& !sym_map->l_relocated)
|
||||||
{
|
{
|
||||||
const char *strtab
|
const char *strtab
|
||||||
= (const char *) D_PTR (map, l_info[DT_STRTAB]);
|
= (const char *) D_PTR (map, l_info[DT_STRTAB]);
|
||||||
_dl_error_printf ("\
|
if (sym_map->l_type == lt_executable)
|
||||||
|
_dl_fatal_printf ("\
|
||||||
|
%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
|
||||||
|
and creates an unsatisfiable circular dependency.\n",
|
||||||
|
RTLD_PROGNAME, strtab + refsym->st_name,
|
||||||
|
map->l_name);
|
||||||
|
else
|
||||||
|
_dl_error_printf ("\
|
||||||
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
|
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
|
||||||
RTLD_PROGNAME, map->l_name,
|
RTLD_PROGNAME, map->l_name,
|
||||||
sym_map->l_name,
|
sym_map->l_name,
|
||||||
strtab + refsym->st_name);
|
strtab + refsym->st_name);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
value = ((ElfW(Addr) (*) (void)) value) ();
|
value = ((ElfW(Addr) (*) (void)) value) ();
|
||||||
|
|
|
@ -67,6 +67,13 @@
|
||||||
# define REP_MOVSB_THRESHOLD (2048 * (VEC_SIZE / 16))
|
# define REP_MOVSB_THRESHOLD (2048 * (VEC_SIZE / 16))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Avoid short distance rep movsb only with non-SSE vector. */
|
||||||
|
#ifndef AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||||
|
# define AVOID_SHORT_DISTANCE_REP_MOVSB (VEC_SIZE > 16)
|
||||||
|
#else
|
||||||
|
# define AVOID_SHORT_DISTANCE_REP_MOVSB 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PREFETCH
|
#ifndef PREFETCH
|
||||||
# define PREFETCH(addr) prefetcht0 addr
|
# define PREFETCH(addr) prefetcht0 addr
|
||||||
#endif
|
#endif
|
||||||
|
@ -257,7 +264,21 @@ L(movsb):
|
||||||
# error Unsupported REP_MOVSB_THRESHOLD and VEC_SIZE!
|
# error Unsupported REP_MOVSB_THRESHOLD and VEC_SIZE!
|
||||||
# endif
|
# endif
|
||||||
jb L(more_8x_vec_backward)
|
jb L(more_8x_vec_backward)
|
||||||
|
# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||||
|
movq %rdi, %rcx
|
||||||
|
subq %rsi, %rcx
|
||||||
|
jmp 2f
|
||||||
|
# endif
|
||||||
1:
|
1:
|
||||||
|
# if AVOID_SHORT_DISTANCE_REP_MOVSB
|
||||||
|
movq %rsi, %rcx
|
||||||
|
subq %rdi, %rcx
|
||||||
|
2:
|
||||||
|
/* Avoid "rep movsb" if RCX, the distance between source and destination,
|
||||||
|
is N*4GB + [1..63] with N >= 0. */
|
||||||
|
cmpl $63, %ecx
|
||||||
|
jbe L(more_2x_vec) /* Avoid "rep movsb" if ECX <= 63. */
|
||||||
|
# endif
|
||||||
mov %RDX_LP, %RCX_LP
|
mov %RDX_LP, %RCX_LP
|
||||||
rep movsb
|
rep movsb
|
||||||
L(nop):
|
L(nop):
|
||||||
|
|
Loading…
Reference in New Issue