MFH @ r323558.
This commit is contained in:
commit
7daed4fc05
@ -557,7 +557,7 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
|
||||
# cross-tools stage
|
||||
XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \
|
||||
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
|
||||
MK_GDB=no MK_TESTS=no
|
||||
MK_GDB=no MK_LLD_IS_LD=${MK_LLD_BOOTSTRAP} MK_TESTS=no
|
||||
|
||||
# kernel-tools stage
|
||||
KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
|
||||
@ -1786,7 +1786,8 @@ update: .PHONY
|
||||
|
||||
# ELF Tool Chain libraries are needed for ELF tools and dtrace tools.
|
||||
# r296685 fix cross-endian objcopy
|
||||
.if ${BOOTSTRAPPING} < 1100102
|
||||
# r310724 fixed PR 215350, a crash in libdwarf with objects built by GCC 6.2.
|
||||
.if ${BOOTSTRAPPING} < 1200020
|
||||
_elftoolchain_libs= lib/libelf lib/libdwarf
|
||||
.endif
|
||||
|
||||
@ -1984,8 +1985,12 @@ _gcc_tools= gnu/usr.bin/cc/cc_tools
|
||||
_rescue=rescue/rescue
|
||||
.endif
|
||||
|
||||
.if ${MK_TCSH} != "no"
|
||||
_tcsh=bin/csh
|
||||
.endif
|
||||
|
||||
.for _tool in \
|
||||
bin/csh \
|
||||
${_tcsh} \
|
||||
bin/sh \
|
||||
${LOCAL_TOOL_DIRS} \
|
||||
lib/ncurses/ncurses \
|
||||
@ -2143,7 +2148,7 @@ native-xtools: .PHONY
|
||||
bin/cat \
|
||||
bin/chmod \
|
||||
bin/cp \
|
||||
bin/csh \
|
||||
${_tcsh} \
|
||||
bin/echo \
|
||||
bin/expr \
|
||||
bin/hostname \
|
||||
|
@ -38,6 +38,13 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20170913: remove unneeded catman utility
|
||||
OLD_FILES+=etc/periodic/weekly/330.catman
|
||||
OLD_FILES+=usr/bin/catman
|
||||
OLD_FILES+=usr/libexec/catman.local
|
||||
OLD_FILES+=usr/share/man/man1/catman.1.gz
|
||||
OLD_FILES+=usr/share/man/man8/catman.local.8.gz
|
||||
|
||||
# 20170802: ksyms(4) ioctl interface was removed
|
||||
OLD_FILES+=usr/include/sys/ksyms.h
|
||||
|
||||
|
23
UPDATING
23
UPDATING
@ -51,6 +51,29 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
||||
|
||||
****************************** SPECIAL WARNING: ******************************
|
||||
|
||||
20170912:
|
||||
The default serial number format for CTL LUNs has changed. This will
|
||||
affect users who use /dev/diskid/* device nodes, or whose FibreChannel
|
||||
or iSCSI clients care about their LUNs' serial numbers. Users who
|
||||
require serial number stability should hardcode serial numbers in
|
||||
/etc/ctl.conf .
|
||||
|
||||
20170912:
|
||||
For 32-bit arm compiled for hard-float support, soft-floating point
|
||||
binaries now always get their shared libraries from
|
||||
LD_SOFT_LIBRARY_PATH (in the past, this was only used if
|
||||
/usr/libsoft also existed). Only users with a hard-float ld.so, but
|
||||
soft-float everything else should be affected.
|
||||
|
||||
20170826:
|
||||
During boot the geli passphrase will be hidden. To restore previous
|
||||
behavior see geli(8) configuration options.
|
||||
|
||||
20170825:
|
||||
Move PMTUD blackhole counters to TCPSTATS and remove them from bare
|
||||
sysctl values. Minor nit, but requires a rebuild of both world/kernel
|
||||
to complete.
|
||||
|
||||
20170814:
|
||||
"make check" behavior (made in ^/head@r295380) has been changed to
|
||||
execute from a limited sandbox, as opposed to executing from
|
||||
|
@ -4,4 +4,7 @@
|
||||
PACKAGE=runtime
|
||||
PROG= chflags
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
5
bin/chflags/tests/Makefile
Normal file
5
bin/chflags/tests/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
ATF_TESTS_SH+= chflags_test
|
||||
|
||||
.include <bsd.test.mk>
|
63
bin/chflags/tests/chflags_test.sh
Normal file
63
bin/chflags/tests/chflags_test.sh
Normal file
@ -0,0 +1,63 @@
|
||||
#
|
||||
# Copyright 2017 Shivansh Rai
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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 AUTHOR 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 AUTHOR 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
usage_output='usage: chflags'
|
||||
|
||||
atf_test_case invalid_usage
|
||||
invalid_usage_head()
|
||||
{
|
||||
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
|
||||
}
|
||||
|
||||
invalid_usage_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags -f
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags -H
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags -h
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags -L
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags -P
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags -R
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags -v
|
||||
}
|
||||
|
||||
atf_test_case no_arguments
|
||||
no_arguments_head()
|
||||
{
|
||||
atf_set "descr" "Verify that chflags(1) fails and generates a valid usage message when no arguments are supplied"
|
||||
}
|
||||
|
||||
no_arguments_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" chflags
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case invalid_usage
|
||||
atf_add_test_case no_arguments
|
||||
}
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
@ -184,7 +185,7 @@ f_bs(char *arg)
|
||||
|
||||
res = get_num(arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(1, "bs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
|
||||
errx(1, "bs must be between 1 and %zd", (ssize_t)SSIZE_MAX);
|
||||
in.dbsz = out.dbsz = (size_t)res;
|
||||
}
|
||||
|
||||
@ -195,22 +196,22 @@ f_cbs(char *arg)
|
||||
|
||||
res = get_num(arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(1, "cbs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
|
||||
errx(1, "cbs must be between 1 and %zd", (ssize_t)SSIZE_MAX);
|
||||
cbsz = (size_t)res;
|
||||
}
|
||||
|
||||
static void
|
||||
f_count(char *arg)
|
||||
{
|
||||
intmax_t res;
|
||||
uintmax_t res;
|
||||
|
||||
res = (intmax_t)get_num(arg);
|
||||
if (res < 0)
|
||||
errx(1, "count cannot be negative");
|
||||
res = get_num(arg);
|
||||
if (res == UINTMAX_MAX)
|
||||
errc(1, ERANGE, "%s", oper);
|
||||
if (res == 0)
|
||||
cpy_cnt = (uintmax_t)-1;
|
||||
cpy_cnt = UINTMAX_MAX;
|
||||
else
|
||||
cpy_cnt = (uintmax_t)res;
|
||||
cpy_cnt = res;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -219,7 +220,7 @@ f_files(char *arg)
|
||||
|
||||
files_cnt = get_num(arg);
|
||||
if (files_cnt < 1)
|
||||
errx(1, "files must be between 1 and %jd", (uintmax_t)-1);
|
||||
errx(1, "files must be between 1 and %zu", SIZE_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -240,8 +241,8 @@ f_ibs(char *arg)
|
||||
if (!(ddflags & C_BS)) {
|
||||
res = get_num(arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(1, "ibs must be between 1 and %jd",
|
||||
(intmax_t)SSIZE_MAX);
|
||||
errx(1, "ibs must be between 1 and %zd",
|
||||
(ssize_t)SSIZE_MAX);
|
||||
in.dbsz = (size_t)res;
|
||||
}
|
||||
}
|
||||
@ -261,8 +262,8 @@ f_obs(char *arg)
|
||||
if (!(ddflags & C_BS)) {
|
||||
res = get_num(arg);
|
||||
if (res < 1 || res > SSIZE_MAX)
|
||||
errx(1, "obs must be between 1 and %jd",
|
||||
(intmax_t)SSIZE_MAX);
|
||||
errx(1, "obs must be between 1 and %zd",
|
||||
(ssize_t)SSIZE_MAX);
|
||||
out.dbsz = (size_t)res;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ block(void)
|
||||
*/
|
||||
ch = 0;
|
||||
for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
|
||||
maxlen = MIN(cbsz, in.dbcnt);
|
||||
maxlen = MIN(cbsz, (size_t)in.dbcnt);
|
||||
if ((t = ctab) != NULL)
|
||||
for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
|
||||
++cnt)
|
||||
@ -146,7 +146,7 @@ block(void)
|
||||
* Check for short record without a newline. Reassemble the
|
||||
* input block.
|
||||
*/
|
||||
if (ch != '\n' && in.dbcnt < cbsz) {
|
||||
if (ch != '\n' && (size_t)in.dbcnt < cbsz) {
|
||||
(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
|
||||
break;
|
||||
}
|
||||
@ -228,7 +228,7 @@ unblock(void)
|
||||
* translation has to already be done or we might not recognize the
|
||||
* spaces.
|
||||
*/
|
||||
for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
|
||||
for (inp = in.db; (size_t)in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
|
||||
for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t)
|
||||
;
|
||||
if (t >= inp) {
|
||||
|
@ -204,10 +204,10 @@ setup(void)
|
||||
* record oriented I/O, only need a single buffer.
|
||||
*/
|
||||
if (!(ddflags & (C_BLOCK | C_UNBLOCK))) {
|
||||
if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
|
||||
if ((in.db = malloc((size_t)out.dbsz + in.dbsz - 1)) == NULL)
|
||||
err(1, "input buffer");
|
||||
out.db = in.db;
|
||||
} else if ((in.db = malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL ||
|
||||
} else if ((in.db = malloc(MAX((size_t)in.dbsz, cbsz) + cbsz)) == NULL ||
|
||||
(out.db = malloc(out.dbsz + cbsz)) == NULL)
|
||||
err(1, "output buffer");
|
||||
|
||||
@ -405,7 +405,7 @@ dd_in(void)
|
||||
++st.in_full;
|
||||
|
||||
/* Handle full input blocks. */
|
||||
} else if ((size_t)n == in.dbsz) {
|
||||
} else if ((size_t)n == (size_t)in.dbsz) {
|
||||
in.dbcnt += in.dbrcnt = n;
|
||||
++st.in_full;
|
||||
|
||||
@ -562,7 +562,7 @@ dd_out(int force)
|
||||
outp += nw;
|
||||
st.bytes += nw;
|
||||
|
||||
if ((size_t)nw == n && n == out.dbsz)
|
||||
if ((size_t)nw == n && n == (size_t)out.dbsz)
|
||||
++st.out_full;
|
||||
else
|
||||
++st.out_part;
|
||||
|
@ -38,10 +38,9 @@
|
||||
typedef struct {
|
||||
u_char *db; /* buffer address */
|
||||
u_char *dbp; /* current buffer I/O address */
|
||||
/* XXX ssize_t? */
|
||||
size_t dbcnt; /* current buffer byte count */
|
||||
size_t dbrcnt; /* last read byte count */
|
||||
size_t dbsz; /* block size */
|
||||
ssize_t dbcnt; /* current buffer byte count */
|
||||
ssize_t dbrcnt; /* last read byte count */
|
||||
ssize_t dbsz; /* block size */
|
||||
|
||||
#define ISCHR 0x01 /* character device (warn on short) */
|
||||
#define ISPIPE 0x02 /* pipe-like (see position.c) */
|
||||
|
@ -207,7 +207,7 @@ pos_out(void)
|
||||
n = write(out.fd, out.db, out.dbsz);
|
||||
if (n == -1)
|
||||
err(1, "%s", out.name);
|
||||
if ((size_t)n != out.dbsz)
|
||||
if (n != out.dbsz)
|
||||
errx(1, "%s: write failure", out.name);
|
||||
}
|
||||
break;
|
||||
|
@ -4,4 +4,7 @@
|
||||
PACKAGE=runtime
|
||||
PROG= mkdir
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
5
bin/mkdir/tests/Makefile
Normal file
5
bin/mkdir/tests/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
ATF_TESTS_SH+= mkdir_test
|
||||
|
||||
.include <bsd.test.mk>
|
61
bin/mkdir/tests/mkdir_test.sh
Normal file
61
bin/mkdir/tests/mkdir_test.sh
Normal file
@ -0,0 +1,61 @@
|
||||
#
|
||||
# Copyright 2017 Shivansh Rai
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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 AUTHOR 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 AUTHOR 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
usage_output='usage: mkdir'
|
||||
|
||||
atf_test_case invalid_usage
|
||||
invalid_usage_head()
|
||||
{
|
||||
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
|
||||
}
|
||||
|
||||
invalid_usage_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e inline:"mkdir: option requires an argument -- m
|
||||
usage: mkdir [-pv] [-m mode] directory_name ...
|
||||
" mkdir -m
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" mkdir -p
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" mkdir -v
|
||||
}
|
||||
|
||||
atf_test_case no_arguments
|
||||
no_arguments_head()
|
||||
{
|
||||
atf_set "descr" "Verify that mkdir(1) fails and generates a valid usage message when no arguments are supplied"
|
||||
}
|
||||
|
||||
no_arguments_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" mkdir
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case invalid_usage
|
||||
atf_add_test_case no_arguments
|
||||
}
|
@ -568,7 +568,7 @@ main(int argc, char **argv)
|
||||
continue;
|
||||
rv |= (*action)(kp);
|
||||
}
|
||||
if (rv && pgrep)
|
||||
if (rv && pgrep && !quiet)
|
||||
putchar('\n');
|
||||
if (!did_action && !pgrep && longfmt)
|
||||
fprintf(stderr,
|
||||
|
@ -262,9 +262,9 @@ state(KINFO *k, VARENT *ve __unused)
|
||||
cp++;
|
||||
if (!(flag & P_INMEM))
|
||||
*cp++ = 'W';
|
||||
if (k->ki_p->ki_nice < NZERO)
|
||||
if (k->ki_p->ki_nice < NZERO || k->ki_p->ki_pri.pri_class == PRI_REALTIME)
|
||||
*cp++ = '<';
|
||||
else if (k->ki_p->ki_nice > NZERO)
|
||||
else if (k->ki_p->ki_nice > NZERO || k->ki_p->ki_pri.pri_class == PRI_IDLE)
|
||||
*cp++ = 'N';
|
||||
if (flag & P_TRACED)
|
||||
*cp++ = 'X';
|
||||
@ -274,6 +274,8 @@ state(KINFO *k, VARENT *ve __unused)
|
||||
*cp++ = 'V';
|
||||
if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0)
|
||||
*cp++ = 'L';
|
||||
if ((k->ki_p->ki_cr_flags & CRED_FLAG_CAPMODE) != 0)
|
||||
*cp++ = 'C';
|
||||
if (k->ki_p->ki_kiflag & KI_SLEADER)
|
||||
*cp++ = 's';
|
||||
if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid)
|
||||
|
@ -29,7 +29,7 @@
|
||||
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 25, 2017
|
||||
.Dd September 7, 2017
|
||||
.Dt PS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -436,6 +436,10 @@ information:
|
||||
The process is in the foreground process group of its control terminal.
|
||||
.It Li <
|
||||
The process has raised CPU scheduling priority.
|
||||
.It Li C
|
||||
The process is in
|
||||
.Xr capsicum 4
|
||||
capability mode.
|
||||
.It Li E
|
||||
The process is trying to exit.
|
||||
.It Li J
|
||||
@ -541,7 +545,7 @@ short-term CPU usage factor (for scheduling)
|
||||
.It Cm dsiz
|
||||
data size (in Kbytes)
|
||||
.It Cm emul
|
||||
system-call emulation environment
|
||||
system-call emulation environment (ABI)
|
||||
.It Cm etime
|
||||
elapsed running time, format
|
||||
.Op days- Ns
|
||||
|
@ -11,4 +11,7 @@ PACKAGE=rcmds
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
5
bin/rcp/tests/Makefile
Normal file
5
bin/rcp/tests/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
ATF_TESTS_SH+= rcp_test
|
||||
|
||||
.include <bsd.test.mk>
|
60
bin/rcp/tests/rcp_test.sh
Normal file
60
bin/rcp/tests/rcp_test.sh
Normal file
@ -0,0 +1,60 @@
|
||||
#
|
||||
# Copyright 2017 Shivansh Rai
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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 AUTHOR 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 AUTHOR 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
usage_output='usage: rcp'
|
||||
|
||||
atf_test_case invalid_usage
|
||||
invalid_usage_head()
|
||||
{
|
||||
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
|
||||
}
|
||||
|
||||
invalid_usage_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -4
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -6
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -p
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp -r
|
||||
}
|
||||
|
||||
atf_test_case no_arguments
|
||||
no_arguments_head()
|
||||
{
|
||||
atf_set "descr" "Verify that rcp(1) fails and generates a valid usage message when no arguments are supplied"
|
||||
}
|
||||
|
||||
no_arguments_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rcp
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case invalid_usage
|
||||
atf_add_test_case no_arguments
|
||||
}
|
@ -4,4 +4,7 @@
|
||||
PACKAGE=runtime
|
||||
PROG= rmdir
|
||||
|
||||
HAS_TESTS=
|
||||
SUBDIR.${MK_TESTS}+= tests
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
5
bin/rmdir/tests/Makefile
Normal file
5
bin/rmdir/tests/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
ATF_TESTS_SH+= rmdir_test
|
||||
|
||||
.include <bsd.test.mk>
|
58
bin/rmdir/tests/rmdir_test.sh
Normal file
58
bin/rmdir/tests/rmdir_test.sh
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright 2017 Shivansh Rai
|
||||
# All rights reserved.
|
||||
#
|
||||
# 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 AUTHOR 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 AUTHOR 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
usage_output='usage: rmdir'
|
||||
|
||||
atf_test_case invalid_usage
|
||||
invalid_usage_head()
|
||||
{
|
||||
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
|
||||
}
|
||||
|
||||
invalid_usage_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rmdir -p
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rmdir -v
|
||||
}
|
||||
|
||||
atf_test_case no_arguments
|
||||
no_arguments_head()
|
||||
{
|
||||
atf_set "descr" "Verify that rmdir(1) fails and generates a valid usage message when no arguments are supplied"
|
||||
}
|
||||
|
||||
no_arguments_body()
|
||||
{
|
||||
atf_check -s not-exit:0 -e match:"$usage_output" rmdir
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case invalid_usage
|
||||
atf_add_test_case no_arguments
|
||||
}
|
@ -74,7 +74,7 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
|
||||
char *dataptr, int datalen, char *optptr, int optlen)
|
||||
{
|
||||
struct iovec *iov;
|
||||
char *optstr, *os, *p;
|
||||
char *optstr, *os, *p, *tofree;
|
||||
int iovlen, rv;
|
||||
|
||||
assert(spec != NULL);
|
||||
@ -87,7 +87,7 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
|
||||
assert(optptr != NULL);
|
||||
assert(optlen > 0);
|
||||
|
||||
optstr = strdup(optptr);
|
||||
tofree = optstr = strdup(optptr);
|
||||
assert(optstr != NULL);
|
||||
|
||||
iov = NULL;
|
||||
@ -98,11 +98,9 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
|
||||
build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, dir),
|
||||
(size_t)-1);
|
||||
build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1);
|
||||
for (p = optstr; p != NULL; strsep(&p, ",/ ")) {
|
||||
if (*p != '\0')
|
||||
build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
|
||||
}
|
||||
while ((p = strsep(&optstr, ",/")) != NULL)
|
||||
build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
|
||||
rv = nmount(iov, iovlen, 0);
|
||||
free(optstr);
|
||||
free(tofree);
|
||||
return (rv);
|
||||
}
|
||||
|
@ -28,9 +28,6 @@
|
||||
|
||||
#pragma D option quiet
|
||||
|
||||
inline int AF_INET = 2;
|
||||
inline int AF_INET6 = 28;
|
||||
|
||||
in_addr_t *ip4a;
|
||||
in_addr_t *ip4b;
|
||||
in_addr_t *ip4c;
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file and its contents are supplied under the terms of the
|
||||
* Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
* You may only use this file in accordance with the terms version
|
||||
* 1.0 of the CDDL.
|
||||
*
|
||||
* A full copy of the text of the CDDL should have accompanied this
|
||||
* source. A copy of the CDDL is also available via the Internet at
|
||||
* http://www.illumos.org/license/CDDL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2017 Mark Johnston <markj@FreeBSD.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* A regression test for FreeBSD r322773. 100^9 fits in 64 bits, but
|
||||
* llquantize() will create buckets up to 100^{10}, which does not fit.
|
||||
*/
|
||||
|
||||
BEGIN
|
||||
{
|
||||
@ = llquantize(0, 100, 0, 9, 100);
|
||||
exit(0);
|
||||
}
|
@ -19,14 +19,15 @@
|
||||
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
.\"
|
||||
.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
|
||||
.\" Copyright 2011, Nexenta Systems, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2011, Justin T. Gibbs <gibbs@FreeBSD.org>
|
||||
.\" Copyright (c) 2013 by Delphix. All Rights Reserved.
|
||||
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
||||
.\" Copyright (c) 2013 by Delphix. All Rights Reserved.
|
||||
.\" Copyright 2017 Nexenta Systems, Inc.
|
||||
.\" Copyright (c) 2017 Datto Inc.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 26, 2014
|
||||
.Dd September 08, 2017
|
||||
.Dt ZPOOL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -153,7 +154,7 @@
|
||||
.Op Ar new_device
|
||||
.Nm
|
||||
.Cm scrub
|
||||
.Op Fl s
|
||||
.Op Fl s | Fl p
|
||||
.Ar pool ...
|
||||
.Nm
|
||||
.Cm set
|
||||
@ -1543,43 +1544,54 @@ manner.
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm scrub
|
||||
.Op Fl s
|
||||
.Op Fl s | Fl p
|
||||
.Ar pool ...
|
||||
.Xc
|
||||
.Pp
|
||||
Begins a scrub. The scrub examines all data in the specified pools to verify
|
||||
that it checksums correctly. For replicated (mirror or
|
||||
.No raidz )
|
||||
devices,
|
||||
.Tn ZFS
|
||||
automatically repairs any damage discovered during the scrub. The
|
||||
.Qq Nm Cm status
|
||||
Begins a scrub or resumes a paused scrub.
|
||||
The scrub examines all data in the specified pools to verify that it checksums
|
||||
correctly.
|
||||
For replicated
|
||||
.Pq mirror or raidz
|
||||
devices, ZFS automatically repairs any damage discovered during the scrub.
|
||||
The
|
||||
.Nm zpool Cm status
|
||||
command reports the progress of the scrub and summarizes the results of the
|
||||
scrub upon completion.
|
||||
.Pp
|
||||
Scrubbing and resilvering are very similar operations. The difference is that
|
||||
resilvering only examines data that
|
||||
.Tn ZFS
|
||||
knows to be out of date (for example, when attaching a new device to a mirror
|
||||
or replacing an existing device), whereas scrubbing examines all data to
|
||||
discover silent errors due to hardware faults or disk failure.
|
||||
Scrubbing and resilvering are very similar operations.
|
||||
The difference is that resilvering only examines data that ZFS knows to be out
|
||||
of date
|
||||
.Po
|
||||
for example, when attaching a new device to a mirror or replacing an existing
|
||||
device
|
||||
.Pc ,
|
||||
whereas scrubbing examines all data to discover silent errors due to hardware
|
||||
faults or disk failure.
|
||||
.Pp
|
||||
Because scrubbing and resilvering are
|
||||
.Tn I/O Ns -intensive
|
||||
operations,
|
||||
.Tn ZFS
|
||||
only allows one at a time. If a scrub is already in progress, the
|
||||
.Qq Nm Cm scrub
|
||||
command returns an error. To start a new scrub, you have to stop the old scrub
|
||||
with the
|
||||
.Qq Nm Cm scrub Fl s
|
||||
command first. If a resilver is in progress,
|
||||
.Tn ZFS
|
||||
does not allow a scrub to be started until the resilver completes.
|
||||
.Bl -tag -width indent
|
||||
Because scrubbing and resilvering are I/O-intensive operations, ZFS only allows
|
||||
one at a time.
|
||||
If a scrub is paused, the
|
||||
.Nm zpool Cm scrub
|
||||
resumes it.
|
||||
If a resilver is in progress, ZFS does not allow a scrub to be started until the
|
||||
resilver completes.
|
||||
.Bl -tag -width Ds
|
||||
.It Fl s
|
||||
Stop scrubbing.
|
||||
.El
|
||||
.Bl -tag -width Ds
|
||||
.It Fl p
|
||||
Pause scrubbing.
|
||||
Scrub pause state and progress are periodically synced to disk.
|
||||
If the system is restarted or pool is exported during a paused scrub,
|
||||
even after import, scrub will remain paused until it is resumed.
|
||||
Once resumed the scrub will pick up from the place where it was last
|
||||
checkpointed to disk.
|
||||
To resume a paused scrub issue
|
||||
.Nm zpool Cm scrub
|
||||
again.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm set
|
||||
|
@ -27,6 +27,7 @@
|
||||
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||
* Copyright 2016 Nexenta Systems, Inc.
|
||||
* Copyright (c) 2017 Datto Inc.
|
||||
*/
|
||||
|
||||
#include <solaris.h>
|
||||
@ -252,7 +253,7 @@ get_usage(zpool_help_t idx)
|
||||
case HELP_REOPEN:
|
||||
return (gettext("\treopen <pool>\n"));
|
||||
case HELP_SCRUB:
|
||||
return (gettext("\tscrub [-s] <pool> ...\n"));
|
||||
return (gettext("\tscrub [-s | -p] <pool> ...\n"));
|
||||
case HELP_STATUS:
|
||||
return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
|
||||
"[count]]\n"));
|
||||
@ -3825,6 +3826,7 @@ typedef struct scrub_cbdata {
|
||||
int cb_type;
|
||||
int cb_argc;
|
||||
char **cb_argv;
|
||||
pool_scrub_cmd_t cb_scrub_cmd;
|
||||
} scrub_cbdata_t;
|
||||
|
||||
int
|
||||
@ -3842,15 +3844,16 @@ scrub_callback(zpool_handle_t *zhp, void *data)
|
||||
return (1);
|
||||
}
|
||||
|
||||
err = zpool_scan(zhp, cb->cb_type);
|
||||
err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
|
||||
|
||||
return (err != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* zpool scrub [-s] <pool> ...
|
||||
* zpool scrub [-s | -p] <pool> ...
|
||||
*
|
||||
* -s Stop. Stops any in-progress scrub.
|
||||
* -p Pause. Pause in-progress scrub.
|
||||
*/
|
||||
int
|
||||
zpool_do_scrub(int argc, char **argv)
|
||||
@ -3859,13 +3862,17 @@ zpool_do_scrub(int argc, char **argv)
|
||||
scrub_cbdata_t cb;
|
||||
|
||||
cb.cb_type = POOL_SCAN_SCRUB;
|
||||
cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "s")) != -1) {
|
||||
while ((c = getopt(argc, argv, "sp")) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
cb.cb_type = POOL_SCAN_NONE;
|
||||
break;
|
||||
case 'p':
|
||||
cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
|
||||
break;
|
||||
case '?':
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
optopt);
|
||||
@ -3873,6 +3880,13 @@ zpool_do_scrub(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (cb.cb_type == POOL_SCAN_NONE &&
|
||||
cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
|
||||
(void) fprintf(stderr, gettext("invalid option combination: "
|
||||
"-s and -p are mutually exclusive\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
cb.cb_argc = argc;
|
||||
cb.cb_argv = argv;
|
||||
argc -= optind;
|
||||
@ -3901,7 +3915,7 @@ typedef struct status_cbdata {
|
||||
void
|
||||
print_scan_status(pool_scan_stat_t *ps)
|
||||
{
|
||||
time_t start, end;
|
||||
time_t start, end, pause;
|
||||
uint64_t elapsed, mins_left, hours_left;
|
||||
uint64_t pass_exam, examined, total;
|
||||
uint_t rate;
|
||||
@ -3919,6 +3933,7 @@ print_scan_status(pool_scan_stat_t *ps)
|
||||
|
||||
start = ps->pss_start_time;
|
||||
end = ps->pss_end_time;
|
||||
pause = ps->pss_pass_scrub_pause;
|
||||
zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
|
||||
|
||||
assert(ps->pss_func == POOL_SCAN_SCRUB ||
|
||||
@ -3961,8 +3976,17 @@ print_scan_status(pool_scan_stat_t *ps)
|
||||
* Scan is in progress.
|
||||
*/
|
||||
if (ps->pss_func == POOL_SCAN_SCRUB) {
|
||||
(void) printf(gettext("scrub in progress since %s"),
|
||||
ctime(&start));
|
||||
if (pause == 0) {
|
||||
(void) printf(gettext("scrub in progress since %s"),
|
||||
ctime(&start));
|
||||
} else {
|
||||
char buf[32];
|
||||
struct tm *p = localtime(&pause);
|
||||
(void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p);
|
||||
(void) printf(gettext("scrub paused since %s\n"), buf);
|
||||
(void) printf(gettext("\tscrub started on %s"),
|
||||
ctime(&start));
|
||||
}
|
||||
} else if (ps->pss_func == POOL_SCAN_RESILVER) {
|
||||
(void) printf(gettext("resilver in progress since %s"),
|
||||
ctime(&start));
|
||||
@ -3974,6 +3998,7 @@ print_scan_status(pool_scan_stat_t *ps)
|
||||
|
||||
/* elapsed time for this pass */
|
||||
elapsed = time(NULL) - ps->pss_pass_start;
|
||||
elapsed -= ps->pss_pass_scrub_spent_paused;
|
||||
elapsed = elapsed ? elapsed : 1;
|
||||
pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
|
||||
rate = pass_exam / elapsed;
|
||||
@ -3983,19 +4008,25 @@ print_scan_status(pool_scan_stat_t *ps)
|
||||
|
||||
zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
|
||||
zfs_nicenum(total, total_buf, sizeof (total_buf));
|
||||
zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
|
||||
|
||||
/*
|
||||
* do not print estimated time if hours_left is more than 30 days
|
||||
* or we have a paused scrub
|
||||
*/
|
||||
(void) printf(gettext(" %s scanned out of %s at %s/s"),
|
||||
examined_buf, total_buf, rate_buf);
|
||||
if (hours_left < (30 * 24)) {
|
||||
(void) printf(gettext(", %lluh%um to go\n"),
|
||||
(u_longlong_t)hours_left, (uint_t)(mins_left % 60));
|
||||
if (pause == 0) {
|
||||
zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
|
||||
(void) printf(gettext("\t%s scanned out of %s at %s/s"),
|
||||
examined_buf, total_buf, rate_buf);
|
||||
if (hours_left < (30 * 24)) {
|
||||
(void) printf(gettext(", %lluh%um to go\n"),
|
||||
(u_longlong_t)hours_left, (uint_t)(mins_left % 60));
|
||||
} else {
|
||||
(void) printf(gettext(
|
||||
", (scan is slow, no estimated time)\n"));
|
||||
}
|
||||
} else {
|
||||
(void) printf(gettext(
|
||||
", (scan is slow, no estimated time)\n"));
|
||||
(void) printf(gettext("\t%s scanned out of %s\n"),
|
||||
examined_buf, total_buf);
|
||||
}
|
||||
|
||||
if (ps->pss_func == POOL_SCAN_RESILVER) {
|
||||
|
@ -1503,7 +1503,7 @@ dt_compile_agg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
|
||||
"divide a power of the factor\n");
|
||||
}
|
||||
|
||||
for (i = 0, order = 1; i < args[2].value; i++) {
|
||||
for (i = 0, order = 1; i <= args[2].value + 1; i++) {
|
||||
if (order * args[0].value > order) {
|
||||
order *= args[0].value;
|
||||
continue;
|
||||
@ -1511,7 +1511,7 @@ dt_compile_agg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
|
||||
|
||||
dnerror(dnp, D_LLQUANT_MAGTOOBIG, "llquantize( ) "
|
||||
"factor (%d) raised to power of high magnitude "
|
||||
"(%d) overflows 64-bits\n", args[0].value,
|
||||
"(%d) plus 1 overflows 64-bits\n", args[0].value,
|
||||
args[2].value);
|
||||
}
|
||||
|
||||
|
@ -963,7 +963,7 @@ dt_provmod_open(dt_provmod_t **provmod, dt_fdlist_t *dfp)
|
||||
|
||||
(void) snprintf(path, sizeof (path), "/dev/dtrace/%s", p1);
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
if ((fd = open(path, O_RDONLY | O_CLOEXEC)) == -1)
|
||||
continue; /* failed to open driver; just skip it */
|
||||
|
||||
if (((prov = malloc(sizeof (dt_provmod_t))) == NULL) ||
|
||||
@ -1100,7 +1100,7 @@ dt_vopen(int version, int flags, int *errp,
|
||||
*/
|
||||
dt_provmod_open(&provmod, &df);
|
||||
|
||||
dtfd = open("/dev/dtrace/dtrace", O_RDWR);
|
||||
dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
|
||||
err = errno; /* save errno from opening dtfd */
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
@ -1109,14 +1109,14 @@ dt_vopen(int version, int flags, int *errp,
|
||||
*/
|
||||
if (err == ENOENT && modfind("dtraceall") < 0) {
|
||||
kldload("dtraceall"); /* ignore the error */
|
||||
dtfd = open("/dev/dtrace/dtrace", O_RDWR);
|
||||
dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
|
||||
err = errno;
|
||||
}
|
||||
#endif
|
||||
#ifdef illumos
|
||||
ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
|
||||
#else
|
||||
ftfd = open("/dev/dtrace/fasttrap", O_RDWR);
|
||||
ftfd = open("/dev/dtrace/fasttrap", O_RDWR | O_CLOEXEC);
|
||||
#endif
|
||||
fterr = ftfd == -1 ? errno : 0; /* save errno from open ftfd */
|
||||
|
||||
@ -1146,9 +1146,6 @@ dt_vopen(int version, int flags, int *errp,
|
||||
return (set_open_errno(dtp, errp, err));
|
||||
}
|
||||
|
||||
(void) fcntl(dtfd, F_SETFD, FD_CLOEXEC);
|
||||
(void) fcntl(ftfd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
alloc:
|
||||
if ((dtp = malloc(sizeof (dtrace_hdl_t))) == NULL) {
|
||||
dt_provmod_destroy(&provmod);
|
||||
|
@ -28,6 +28,7 @@
|
||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||
* Copyright (c) 2014 Integros [integros.com]
|
||||
* Copyright 2016 Nexenta Systems, Inc.
|
||||
* Copyright (c) 2017 Datto Inc.
|
||||
*/
|
||||
|
||||
#ifndef _LIBZFS_H
|
||||
@ -129,6 +130,7 @@ typedef enum zfs_error {
|
||||
EZFS_DIFF, /* general failure of zfs diff */
|
||||
EZFS_DIFFDATA, /* bad zfs diff data */
|
||||
EZFS_POOLREADONLY, /* pool is in read-only mode */
|
||||
EZFS_SCRUB_PAUSED, /* scrub currently paused */
|
||||
EZFS_UNKNOWN
|
||||
} zfs_error_t;
|
||||
|
||||
@ -241,7 +243,7 @@ typedef struct splitflags {
|
||||
/*
|
||||
* Functions to manipulate pool and vdev state
|
||||
*/
|
||||
extern int zpool_scan(zpool_handle_t *, pool_scan_func_t);
|
||||
extern int zpool_scan(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t);
|
||||
extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
|
||||
extern int zpool_reguid(zpool_handle_t *);
|
||||
extern int zpool_reopen(zpool_handle_t *);
|
||||
@ -772,6 +774,7 @@ extern int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **,
|
||||
* Label manipulation.
|
||||
*/
|
||||
extern int zpool_read_label(int, nvlist_t **);
|
||||
extern int zpool_read_all_labels(int, nvlist_t **);
|
||||
extern int zpool_clear_label(int);
|
||||
|
||||
/* is this zvol valid for use as a dump device? */
|
||||
|
@ -914,6 +914,65 @@ zpool_read_label(int fd, nvlist_t **config)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a file descriptor, read the label information and return an nvlist
|
||||
* describing the configuration, if there is one.
|
||||
* returns the number of valid labels found
|
||||
*/
|
||||
int
|
||||
zpool_read_all_labels(int fd, nvlist_t **config)
|
||||
{
|
||||
struct stat64 statbuf;
|
||||
int l;
|
||||
vdev_label_t *label;
|
||||
uint64_t state, txg, size;
|
||||
int nlabels = 0;
|
||||
|
||||
*config = NULL;
|
||||
|
||||
if (fstat64(fd, &statbuf) == -1)
|
||||
return (0);
|
||||
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
|
||||
|
||||
if ((label = malloc(sizeof (vdev_label_t))) == NULL)
|
||||
return (0);
|
||||
|
||||
for (l = 0; l < VDEV_LABELS; l++) {
|
||||
nvlist_t *temp = NULL;
|
||||
|
||||
/* TODO: use aio_read so we can read al 4 labels in parallel */
|
||||
if (pread64(fd, label, sizeof (vdev_label_t),
|
||||
label_offset(size, l)) != sizeof (vdev_label_t))
|
||||
continue;
|
||||
|
||||
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
|
||||
sizeof (label->vl_vdev_phys.vp_nvlist), &temp, 0) != 0)
|
||||
continue;
|
||||
|
||||
if (nvlist_lookup_uint64(temp, ZPOOL_CONFIG_POOL_STATE,
|
||||
&state) != 0 || state > POOL_STATE_L2CACHE) {
|
||||
nvlist_free(temp);
|
||||
temp = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
|
||||
(nvlist_lookup_uint64(temp, ZPOOL_CONFIG_POOL_TXG,
|
||||
&txg) != 0 || txg == 0)) {
|
||||
nvlist_free(temp);
|
||||
temp = NULL;
|
||||
continue;
|
||||
}
|
||||
if (temp)
|
||||
*config = temp;
|
||||
|
||||
nlabels++;
|
||||
}
|
||||
|
||||
free(label);
|
||||
return (nlabels);
|
||||
}
|
||||
|
||||
typedef struct rdsk_node {
|
||||
char *rn_name;
|
||||
int rn_dfd;
|
||||
|
@ -20,9 +20,11 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014 by Delphix. All rights reserved.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
* Copyright 2017 RackTop Systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -87,7 +89,7 @@ zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **,
|
||||
zfs_share_proto_t);
|
||||
|
||||
/*
|
||||
* The share protocols table must be in the same order as the zfs_share_prot_t
|
||||
* The share protocols table must be in the same order as the zfs_share_proto_t
|
||||
* enum in libzfs_impl.h
|
||||
*/
|
||||
typedef struct {
|
||||
@ -872,7 +874,7 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
|
||||
/* make sure libshare initialized */
|
||||
if ((err = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
|
||||
free(mntpt); /* don't need the copy anymore */
|
||||
return (zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
|
||||
return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
|
||||
dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
|
||||
name, _sa_errorstr(err)));
|
||||
}
|
||||
@ -883,12 +885,13 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
|
||||
if (share != NULL) {
|
||||
err = zfs_sa_disable_share(share, proto_table[proto].p_name);
|
||||
if (err != SA_OK) {
|
||||
return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
|
||||
return (zfs_error_fmt(hdl,
|
||||
proto_table[proto].p_unshare_err,
|
||||
dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
|
||||
name, _sa_errorstr(err)));
|
||||
}
|
||||
} else {
|
||||
return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
|
||||
return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
|
||||
dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
|
||||
name));
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright 2016 Nexenta Systems, Inc.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
* Copyright (c) 2017 Datto Inc.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -1841,22 +1842,39 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
|
||||
* Scan the pool.
|
||||
*/
|
||||
int
|
||||
zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
|
||||
zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
|
||||
{
|
||||
zfs_cmd_t zc = { 0 };
|
||||
char msg[1024];
|
||||
int err;
|
||||
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
||||
zc.zc_cookie = func;
|
||||
zc.zc_flags = cmd;
|
||||
|
||||
if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0 ||
|
||||
(errno == ENOENT && func != POOL_SCAN_NONE))
|
||||
if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0)
|
||||
return (0);
|
||||
|
||||
err = errno;
|
||||
|
||||
/* ECANCELED on a scrub means we resumed a paused scrub */
|
||||
if (err == ECANCELED && func == POOL_SCAN_SCRUB &&
|
||||
cmd == POOL_SCRUB_NORMAL)
|
||||
return (0);
|
||||
|
||||
if (err == ENOENT && func != POOL_SCAN_NONE && cmd == POOL_SCRUB_NORMAL)
|
||||
return (0);
|
||||
|
||||
if (func == POOL_SCAN_SCRUB) {
|
||||
(void) snprintf(msg, sizeof (msg),
|
||||
dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
|
||||
if (cmd == POOL_SCRUB_PAUSE) {
|
||||
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
|
||||
"cannot pause scrubbing %s"), zc.zc_name);
|
||||
} else {
|
||||
assert(cmd == POOL_SCRUB_NORMAL);
|
||||
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
|
||||
"cannot scrub %s"), zc.zc_name);
|
||||
}
|
||||
} else if (func == POOL_SCAN_NONE) {
|
||||
(void) snprintf(msg, sizeof (msg),
|
||||
dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
|
||||
@ -1865,7 +1883,7 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
|
||||
assert(!"unexpected result");
|
||||
}
|
||||
|
||||
if (errno == EBUSY) {
|
||||
if (err == EBUSY) {
|
||||
nvlist_t *nvroot;
|
||||
pool_scan_stat_t *ps = NULL;
|
||||
uint_t psc;
|
||||
@ -1874,14 +1892,18 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
|
||||
ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
|
||||
(void) nvlist_lookup_uint64_array(nvroot,
|
||||
ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
|
||||
if (ps && ps->pss_func == POOL_SCAN_SCRUB)
|
||||
return (zfs_error(hdl, EZFS_SCRUBBING, msg));
|
||||
else
|
||||
if (ps && ps->pss_func == POOL_SCAN_SCRUB) {
|
||||
if (cmd == POOL_SCRUB_PAUSE)
|
||||
return (zfs_error(hdl, EZFS_SCRUB_PAUSED, msg));
|
||||
else
|
||||
return (zfs_error(hdl, EZFS_SCRUBBING, msg));
|
||||
} else {
|
||||
return (zfs_error(hdl, EZFS_RESILVERING, msg));
|
||||
} else if (errno == ENOENT) {
|
||||
}
|
||||
} else if (err == ENOENT) {
|
||||
return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
|
||||
} else {
|
||||
return (zpool_standard_error(hdl, errno, msg));
|
||||
return (zpool_standard_error(hdl, err, msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
* Copyright (c) 2017 Datto Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -224,6 +225,9 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
||||
case EZFS_POSTSPLIT_ONLINE:
|
||||
return (dgettext(TEXT_DOMAIN, "disk was split from this pool "
|
||||
"into a new one"));
|
||||
case EZFS_SCRUB_PAUSED:
|
||||
return (dgettext(TEXT_DOMAIN, "scrub is paused; "
|
||||
"use 'zpool scrub' to resume"));
|
||||
case EZFS_SCRUBBING:
|
||||
return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
|
||||
"use 'zpool scrub -s' to cancel current scrub"));
|
||||
|
@ -735,11 +735,9 @@ static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
|
||||
void
|
||||
vpanic(const char *fmt, va_list adx)
|
||||
{
|
||||
(void) fprintf(stderr, "error: ");
|
||||
(void) vfprintf(stderr, fmt, adx);
|
||||
(void) fprintf(stderr, "\n");
|
||||
|
||||
abort(); /* think of it as a "user-level crash dump" */
|
||||
char buf[512];
|
||||
(void) vsnprintf(buf, 512, fmt, adx);
|
||||
assfail(buf, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -54,6 +54,7 @@ DSRCS= errno.d \
|
||||
siftr.d \
|
||||
signal.d \
|
||||
tcp.d \
|
||||
socket.d \
|
||||
udp.d \
|
||||
unistd.d
|
||||
|
||||
|
301
cddl/lib/libdtrace/socket.d
Normal file
301
cddl/lib/libdtrace/socket.d
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2017 George V. Neville-Neil
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
* Translators and flags for the socket structure. FreeBSD specific code.
|
||||
*/
|
||||
|
||||
#pragma D depends_on module kernel
|
||||
|
||||
/*
|
||||
* Option flags per-socket.
|
||||
*/
|
||||
#pragma D binding "1.13" SO_DEBUG
|
||||
inline int SO_DEBUG = 0x0001; /* turn on debugging info recording */
|
||||
#pragma D binding "1.13" SO_ACCEPTCONN
|
||||
inline int SO_ACCEPTCONN = 0x0002; /* socket has had listen() */
|
||||
#pragma D binding "1.13" SO_REUSEADDR
|
||||
inline int SO_REUSEADDR = 0x0004; /* allow local address reuse */
|
||||
#pragma D binding "1.13" SO_KEEPALIVE
|
||||
inline int SO_KEEPALIVE = 0x0008; /* keep connections alive */
|
||||
#pragma D binding "1.13" SO_DONTROUTE
|
||||
inline int SO_DONTROUTE = 0x0010; /* just use interface addresses */
|
||||
#pragma D binding "1.13" SO_BROADCAST
|
||||
inline int SO_BROADCAST = 0x0020; /* permit sending of broadcast msgs */
|
||||
#pragma D binding "1.13" SO_USELOOPBACK
|
||||
inline int SO_USELOOPBACK = 0x0040; /* bypass hardware when possible */
|
||||
#pragma D binding "1.13" SO_LINGER
|
||||
inline int SO_LINGER = 0x0080; /* linger on close if data present */
|
||||
#pragma D binding "1.13" SO_OOBINLINE
|
||||
inline int SO_OOBINLINE = 0x0100; /* leave received OOB data in line */
|
||||
#pragma D binding "1.13" SO_REUSEPORT
|
||||
inline int SO_REUSEPORT = 0x0200; /* allow local address & port reuse */
|
||||
#pragma D binding "1.13" SO_TIMESTAMP
|
||||
inline int SO_TIMESTAMP = 0x0400; /* timestamp received dgram traffic */
|
||||
#pragma D binding "1.13" SO_NOSIGPIPE
|
||||
inline int SO_NOSIGPIPE = 0x0800; /* no SIGPIPE from EPIPE */
|
||||
#pragma D binding "1.13" SO_ACCEPTFILTER
|
||||
inline int SO_ACCEPTFILTER = 0x1000; /* there is an accept filter */
|
||||
#pragma D binding "1.13" SO_BINTIME
|
||||
inline int SO_BINTIME = 0x2000; /* timestamp received dgram traffic */
|
||||
#pragma D binding "1.13" SO_NO_OFFLOAD
|
||||
inline int SO_NO_OFFLOAD = 0x4000; /* socket cannot be offloaded */
|
||||
#pragma D binding "1.13" SO_NO_DDP
|
||||
inline int SO_NO_DDP = 0x8000; /* disable direct data placement */
|
||||
|
||||
/*
|
||||
* Additional options, not kept in so_options.
|
||||
*/
|
||||
#pragma D binding "1.13" SO_SNDBUF
|
||||
inline int SO_SNDBUF = 0x1001; /* send buffer size */
|
||||
#pragma D binding "1.13" SO_RCVBUF
|
||||
inline int SO_RCVBUF = 0x1002; /* receive buffer size */
|
||||
#pragma D binding "1.13" SO_SNDLOWAT
|
||||
inline int SO_SNDLOWAT = 0x1003; /* send low-water mark */
|
||||
#pragma D binding "1.13" SO_RCVLOWAT
|
||||
inline int SO_RCVLOWAT = 0x1004; /* receive low-water mark */
|
||||
#pragma D binding "1.13" SO_SNDTIMEO
|
||||
inline int SO_SNDTIMEO = 0x1005; /* send timeout */
|
||||
#pragma D binding "1.13" SO_RCVTIMEO
|
||||
inline int SO_RCVTIMEO = 0x1006; /* receive timeout */
|
||||
#pragma D binding "1.13" SO_ERROR
|
||||
inline int SO_ERROR = 0x1007; /* get error status and clear */
|
||||
#pragma D binding "1.13" SO_TYPE
|
||||
inline int SO_TYPE = 0x1008; /* get socket type */
|
||||
#pragma D binding "1.13" SO_LABEL
|
||||
inline int SO_LABEL = 0x1009; /* socket's MAC label */
|
||||
#pragma D binding "1.13" SO_PEERLABEL
|
||||
inline int SO_PEERLABEL = 0x1010; /* socket's peer's MAC label */
|
||||
#pragma D binding "1.13" SO_LISTENQLIMIT
|
||||
inline int SO_LISTENQLIMIT = 0x1011; /* socket's backlog limit */
|
||||
#pragma D binding "1.13" SO_LISTENQLEN
|
||||
inline int SO_LISTENQLEN = 0x1012; /* socket's complete queue length */
|
||||
#pragma D binding "1.13" SO_LISTENINCQLEN
|
||||
inline int SO_LISTENINCQLEN = 0x1013; /* socket's incomplete queue length */
|
||||
#pragma D binding "1.13" SO_SETFIB
|
||||
inline int SO_SETFIB = 0x1014; /* use this FIB to route */
|
||||
#pragma D binding "1.13" SO_USER_COOKIE
|
||||
inline int SO_USER_COOKIE = 0x1015; /* user cookie (dummynet etc.) */
|
||||
#pragma D binding "1.13" SO_PROTOCOL
|
||||
inline int SO_PROTOCOL = 0x1016; /* get socket protocol (Linux name) */
|
||||
#pragma D binding "1.13" SO_PROTOTYPE
|
||||
inline int SO_PROTOTYPE = SO_PROTOCOL; /* alias for SO_PROTOCOL (SunOS name) */
|
||||
#pragma D binding "1.13" SO_TS_CLOCK
|
||||
inline int SO_TS_CLOCK = 0x1017; /* clock type used for SO_TIMESTAMP */
|
||||
#pragma D binding "1.13" SO_MAX_PACING_RATE
|
||||
inline int SO_MAX_PACING_RATE = 0x1018; /* socket's max TX pacing rate (Linux name) */
|
||||
|
||||
#pragma D binding "1.13" SO_TS_REALTIME_MICRO
|
||||
inline int SO_TS_REALTIME_MICRO = 0; /* microsecond resolution, realtime */
|
||||
#pragma D binding "1.13" SO_TS_BINTIME
|
||||
inline int SO_TS_BINTIME = 1; /* sub-nanosecond resolution, realtime */
|
||||
#pragma D binding "1.13" SO_TS_REALTIME
|
||||
inline int SO_TS_REALTIME = 2; /* nanosecond resolution, realtime */
|
||||
#pragma D binding "1.13" SO_TS_MONOTONIC
|
||||
inline int SO_TS_MONOTONIC = 3; /* nanosecond resolution, monotonic */
|
||||
#pragma D binding "1.13" SO_TS_DEFAULT
|
||||
inline int SO_TS_DEFAULT = SO_TS_REALTIME_MICRO;
|
||||
#pragma D binding "1.13" SO_TS_CLOCK_MAX
|
||||
inline int SO_TS_CLOCK_MAX = SO_TS_MONOTONIC;
|
||||
|
||||
#pragma D binding "1.13" AF_UNSPEC
|
||||
inline int AF_UNSPEC = 0; /* unspecified */
|
||||
#pragma D binding "1.13" AF_UNIX
|
||||
inline int AF_UNIX = 1; /* standardized name for AF_LOCAL */
|
||||
#pragma D binding "1.13" AF_LOCAL
|
||||
inline int AF_LOCAL = AF_UNIX; /* local to host (pipes, portals) */
|
||||
#pragma D binding "1.13" AF_INET
|
||||
inline int AF_INET = 2; /* internetwork: UDP, TCP, etc. */
|
||||
#pragma D binding "1.13" AF_IMPLINK
|
||||
inline int AF_IMPLINK = 3; /* arpanet imp addresses */
|
||||
#pragma D binding "1.13" AF_PUP
|
||||
inline int AF_PUP = 4; /* pup protocols: e.g. BSP */
|
||||
#pragma D binding "1.13" AF_CHAOS
|
||||
inline int AF_CHAOS = 5; /* mit CHAOS protocols */
|
||||
#pragma D binding "1.13" AF_NETBIOS
|
||||
inline int AF_NETBIOS = 6; /* SMB protocols */
|
||||
#pragma D binding "1.13" AF_ISO
|
||||
inline int AF_ISO = 7; /* ISO protocols */
|
||||
#pragma D binding "1.13" AF_OSI
|
||||
inline int AF_OSI = AF_ISO;
|
||||
#pragma D binding "1.13" AF_ECMA
|
||||
inline int AF_ECMA = 8; /* European computer manufacturers */
|
||||
#pragma D binding "1.13" AF_DATAKIT
|
||||
inline int AF_DATAKIT = 9; /* datakit protocols */
|
||||
#pragma D binding "1.13" AF_CCITT
|
||||
inline int AF_CCITT = 10; /* CCITT protocols, X.25 etc */
|
||||
#pragma D binding "1.13" AF_SNA
|
||||
inline int AF_SNA = 11; /* IBM SNA */
|
||||
#pragma D binding "1.13" AF_DECnet
|
||||
inline int AF_DECnet = 12; /* DECnet */
|
||||
#pragma D binding "1.13" AF_DLI
|
||||
inline int AF_DLI = 13; /* DEC Direct data link interface */
|
||||
#pragma D binding "1.13" AF_LAT
|
||||
inline int AF_LAT = 14; /* LAT */
|
||||
#pragma D binding "1.13" AF_HYLINK
|
||||
inline int AF_HYLINK = 15; /* NSC Hyperchannel */
|
||||
#pragma D binding "1.13" AF_APPLETALK
|
||||
inline int AF_APPLETALK = 16; /* Apple Talk */
|
||||
#pragma D binding "1.13" AF_ROUTE
|
||||
inline int AF_ROUTE = 17; /* Internal Routing Protocol */
|
||||
#pragma D binding "1.13" AF_LINK
|
||||
inline int AF_LINK = 18; /* Link layer interface */
|
||||
#pragma D binding "1.13" pseudo_AF_XTP
|
||||
inline int pseudo_AF_XTP = 19; /* eXpress Transfer Protocol (no AF) */
|
||||
#pragma D binding "1.13" AF_COIP
|
||||
inline int AF_COIP = 20; /* connection-oriented IP, aka ST II */
|
||||
#pragma D binding "1.13" AF_CNT
|
||||
inline int AF_CNT = 21; /* Computer Network Technology */
|
||||
#pragma D binding "1.13" pseudo_AF_RTIP
|
||||
inline int pseudo_AF_RTIP = 22; /* Help Identify RTIP packets */
|
||||
#pragma D binding "1.13" AF_IPX
|
||||
inline int AF_IPX = 23; /* Novell Internet Protocol */
|
||||
#pragma D binding "1.13" AF_SIP
|
||||
inline int AF_SIP = 24; /* Simple Internet Protocol */
|
||||
#pragma D binding "1.13" pseudo_AF_PIP
|
||||
inline int pseudo_AF_PIP = 25; /* Help Identify PIP packets */
|
||||
#pragma D binding "1.13" AF_ISDN
|
||||
inline int AF_ISDN = 26; /* Integrated Services Digital Network*/
|
||||
#pragma D binding "1.13" AF_E164
|
||||
inline int AF_E164 = AF_ISDN; /* CCITT E.164 recommendation */
|
||||
#pragma D binding "1.13" pseudo_AF_KEY
|
||||
inline int pseudo_AF_KEY = 27; /* Internal key-management function */
|
||||
#pragma D binding "1.13" AF_INET6
|
||||
inline int AF_INET6 = 28; /* IPv6 */
|
||||
#pragma D binding "1.13" AF_NATM
|
||||
inline int AF_NATM = 29; /* native ATM access */
|
||||
#pragma D binding "1.13" AF_ATM
|
||||
inline int AF_ATM = 30; /* ATM */
|
||||
#pragma D binding "1.13" pseudo_AF_HDRCMPLT
|
||||
inline int pseudo_AF_HDRCMPLT = 31; /* Used by BPF to not rewrite headers
|
||||
* in interface output routine
|
||||
*/
|
||||
#pragma D binding "1.13" AF_NETGRAPH
|
||||
inline int AF_NETGRAPH = 32; /* Netgraph sockets */
|
||||
#pragma D binding "1.13" AF_SLOW
|
||||
inline int AF_SLOW = 33; /* 802.3ad slow protocol */
|
||||
#pragma D binding "1.13" AF_SCLUSTER
|
||||
inline int AF_SCLUSTER = 34; /* Sitara cluster protocol */
|
||||
#pragma D binding "1.13" AF_ARP
|
||||
inline int AF_ARP = 35; /* Address Resolution Protocol */
|
||||
#pragma D binding "1.13" AF_BLUETOOTH
|
||||
inline int AF_BLUETOOTH = 36; /* Bluetooth sockets */
|
||||
#pragma D binding "1.13" AF_IEEE80211
|
||||
inline int AF_IEEE80211 = 37; /* IEEE 802.11 protocol */
|
||||
#pragma D binding "1.13" AF_INET_SDP
|
||||
inline int AF_INET_SDP = 40; /* OFED Socket Direct Protocol ipv4 */
|
||||
#pragma D binding "1.13" AF_INET6_SDP
|
||||
inline int AF_INET6_SDP = 42; /* OFED Socket Direct Protocol ipv6 */
|
||||
#pragma D binding "1.13" AF_MAX
|
||||
inline int AF_MAX = 42;
|
||||
|
||||
/*
|
||||
* Protocol families, same as address families for now.
|
||||
*/
|
||||
#pragma D binding "1.13" PF_UNSPEC
|
||||
inline int PF_UNSPEC = AF_UNSPEC;
|
||||
#pragma D binding "1.13" PF_LOCAL
|
||||
inline int PF_LOCAL = AF_LOCAL;
|
||||
#pragma D binding "1.13" PF_UNIX
|
||||
inline int PF_UNIX = PF_LOCAL; /* backward compatibility */
|
||||
#pragma D binding "1.13" PF_INET
|
||||
inline int PF_INET = AF_INET;
|
||||
#pragma D binding "1.13" PF_IMPLINK
|
||||
inline int PF_IMPLINK = AF_IMPLINK;
|
||||
#pragma D binding "1.13" PF_PUP
|
||||
inline int PF_PUP = AF_PUP;
|
||||
#pragma D binding "1.13" PF_CHAOS
|
||||
inline int PF_CHAOS = AF_CHAOS;
|
||||
#pragma D binding "1.13" PF_NETBIOS
|
||||
inline int PF_NETBIOS = AF_NETBIOS;
|
||||
#pragma D binding "1.13" PF_ISO
|
||||
inline int PF_ISO = AF_ISO;
|
||||
#pragma D binding "1.13" PF_OSI
|
||||
inline int PF_OSI = AF_ISO;
|
||||
#pragma D binding "1.13" PF_ECMA
|
||||
inline int PF_ECMA = AF_ECMA;
|
||||
#pragma D binding "1.13" PF_DATAKIT
|
||||
inline int PF_DATAKIT = AF_DATAKIT;
|
||||
#pragma D binding "1.13" PF_CCITT
|
||||
inline int PF_CCITT = AF_CCITT;
|
||||
#pragma D binding "1.13" PF_SNA
|
||||
inline int PF_SNA = AF_SNA;
|
||||
#pragma D binding "1.13" PF_DECnet
|
||||
inline int PF_DECnet = AF_DECnet;
|
||||
#pragma D binding "1.13" PF_DLI
|
||||
inline int PF_DLI = AF_DLI;
|
||||
#pragma D binding "1.13" PF_LAT
|
||||
inline int PF_LAT = AF_LAT;
|
||||
#pragma D binding "1.13" PF_HYLINK
|
||||
inline int PF_HYLINK = AF_HYLINK;
|
||||
#pragma D binding "1.13" PF_APPLETALK
|
||||
inline int PF_APPLETALK = AF_APPLETALK;
|
||||
#pragma D binding "1.13" PF_ROUTE
|
||||
inline int PF_ROUTE = AF_ROUTE;
|
||||
#pragma D binding "1.13" PF_LINK
|
||||
inline int PF_LINK = AF_LINK;
|
||||
#pragma D binding "1.13" PF_XTP
|
||||
inline int PF_XTP = pseudo_AF_XTP; /* really just proto family, no AF */
|
||||
#pragma D binding "1.13" PF_COIP
|
||||
inline int PF_COIP = AF_COIP;
|
||||
#pragma D binding "1.13" PF_CNT
|
||||
inline int PF_CNT = AF_CNT;
|
||||
#pragma D binding "1.13" PF_SIP
|
||||
inline int PF_SIP = AF_SIP;
|
||||
#pragma D binding "1.13" PF_IPX
|
||||
inline int PF_IPX = AF_IPX;
|
||||
#pragma D binding "1.13" PF_RTIP
|
||||
inline int PF_RTIP = pseudo_AF_RTIP; /* same format as AF_INET */
|
||||
#pragma D binding "1.13" PF_PIP
|
||||
inline int PF_PIP = pseudo_AF_PIP;
|
||||
#pragma D binding "1.13" PF_ISDN
|
||||
inline int PF_ISDN = AF_ISDN;
|
||||
#pragma D binding "1.13" PF_KEY
|
||||
inline int PF_KEY = pseudo_AF_KEY;
|
||||
#pragma D binding "1.13" PF_INET6
|
||||
inline int PF_INET6 = AF_INET6;
|
||||
#pragma D binding "1.13" PF_NATM
|
||||
inline int PF_NATM = AF_NATM;
|
||||
#pragma D binding "1.13" PF_ATM
|
||||
inline int PF_ATM = AF_ATM;
|
||||
#pragma D binding "1.13" PF_NETGRAPH
|
||||
inline int PF_NETGRAPH = AF_NETGRAPH;
|
||||
#pragma D binding "1.13" PF_SLOW
|
||||
inline int PF_SLOW = AF_SLOW;
|
||||
#pragma D binding "1.13" PF_SCLUSTER
|
||||
inline int PF_SCLUSTER = AF_SCLUSTER;
|
||||
#pragma D binding "1.13" PF_ARP
|
||||
inline int PF_ARP = AF_ARP;
|
||||
#pragma D binding "1.13" PF_BLUETOOTH
|
||||
inline int PF_BLUETOOTH = AF_BLUETOOTH;
|
||||
#pragma D binding "1.13" PF_IEEE80211
|
||||
inline int PF_IEEE80211 = AF_IEEE80211;
|
||||
#pragma D binding "1.13" PF_INET_SDP
|
||||
inline int PF_INET_SDP= AF_INET_SDP;
|
||||
#pragma D binding "1.13" PF_INET6_SDP
|
||||
inline int PF_INET6_SDP= AF_INET6_SDP;
|
||||
#pragma D binding "1.13" PF_MAX
|
||||
inline int PF_MAX = AF_MAX;
|
@ -26,7 +26,7 @@ ATOMIC_SRCS= opensolaris_atomic.c
|
||||
|
||||
LIB= zpool
|
||||
|
||||
ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} vdev_file.c trim_map.c
|
||||
ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} trim_map.c
|
||||
ZFS_SHARED_SRCS= ${ZFS_SHARED_OBJS:C/.o$/.c/}
|
||||
KERNEL_SRCS= kernel.c taskq.c util.c
|
||||
LIST_SRCS= list.c
|
||||
|
@ -22,6 +22,7 @@ ${PACKAGE}FILES= \
|
||||
err.D_LLQUANT_LOWVAL.d \
|
||||
err.D_LLQUANT_MAGRANGE.d \
|
||||
err.D_LLQUANT_MAGTOOBIG.d \
|
||||
err.D_LLQUANT_MAGTOOBIG.offbyone.d \
|
||||
err.D_LLQUANT_NSTEPMATCH.d \
|
||||
err.D_LLQUANT_NSTEPTYPE.d \
|
||||
err.D_LLQUANT_NSTEPVAL.d \
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <sys/vdev_impl.h>
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
@ -93,6 +94,7 @@ DevfsEvent::ReadLabel(int devFd, bool &inUse, bool °raded)
|
||||
pool_state_t poolState;
|
||||
char *poolName;
|
||||
boolean_t b_inuse;
|
||||
int nlabels;
|
||||
|
||||
inUse = false;
|
||||
degraded = false;
|
||||
@ -105,8 +107,16 @@ DevfsEvent::ReadLabel(int devFd, bool &inUse, bool °raded)
|
||||
if (poolName != NULL)
|
||||
free(poolName);
|
||||
|
||||
if (zpool_read_label(devFd, &devLabel) != 0
|
||||
|| devLabel == NULL)
|
||||
nlabels = zpool_read_all_labels(devFd, &devLabel);
|
||||
/*
|
||||
* If we find a disk with fewer than the maximum number of
|
||||
* labels, it might be the whole disk of a partitioned disk
|
||||
* where ZFS resides on a partition. In that case, we should do
|
||||
* nothing and wait for the partition to appear. Or, the disk
|
||||
* might be damaged. In that case, zfsd should do nothing and
|
||||
* wait for the sysadmin to decide.
|
||||
*/
|
||||
if (nlabels != VDEV_LABELS || devLabel == NULL)
|
||||
return (NULL);
|
||||
|
||||
try {
|
||||
|
@ -1302,7 +1302,7 @@ static const unsigned char twobyte_uses_REPZ_prefix[256] = {
|
||||
/* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
|
||||
/* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
|
||||
/* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
|
||||
/* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
|
||||
/* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* af */
|
||||
/* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
|
||||
/* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
|
||||
/* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
|
||||
@ -1793,10 +1793,10 @@ static const struct dis386 grps[][8] = {
|
||||
},
|
||||
/* GRP15 */
|
||||
{
|
||||
{ "fxsave", { Ev } },
|
||||
{ "fxrstor", { Ev } },
|
||||
{ "ldmxcsr", { Ev } },
|
||||
{ "stmxcsr", { Ev } },
|
||||
{ "fxsave", { { OP_0fae, v_mode } } },
|
||||
{ "fxrstor", { { OP_0fae, v_mode } } },
|
||||
{ "ldmxcsr", { { OP_0fae, v_mode } } },
|
||||
{ "stmxcsr", { { OP_0fae, v_mode } } },
|
||||
{ "xsave", { Ev } },
|
||||
{ "xrstor", { { OP_0fae, v_mode } } },
|
||||
{ "xsaveopt", { { OP_0fae, v_mode } } },
|
||||
@ -5997,19 +5997,34 @@ OP_0fae (int bytemode, int sizeflag)
|
||||
{
|
||||
if (modrm.mod == 3)
|
||||
{
|
||||
if (modrm.reg == 7)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
|
||||
else if (modrm.reg == 6)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
|
||||
else if (modrm.reg == 5)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
|
||||
|
||||
if (modrm.reg < 5 || modrm.rm != 0)
|
||||
if (modrm.reg >= 5 && modrm.reg <= 7 && modrm.rm == 0)
|
||||
{
|
||||
BadOp (); /* bad sfence, mfence, or lfence */
|
||||
if (modrm.reg == 7)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
|
||||
else if (modrm.reg == 6)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
|
||||
else if (modrm.reg == 5)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
|
||||
bytemode = 0;
|
||||
}
|
||||
else if (modrm.reg <= 3 && (prefixes & PREFIX_REPZ) != 0)
|
||||
{
|
||||
if (modrm.reg == 0)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("fxsave") + 1, "rdfsbase");
|
||||
else if (modrm.reg == 1)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("fxrstor") + 1, "rdgsbase");
|
||||
else if (modrm.reg == 2)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("ldmxcsr") + 1, "wrfsbase");
|
||||
else if (modrm.reg == 3)
|
||||
strcpy (obuf + strlen (obuf) - sizeof ("stmxcsr") + 1, "wrgsbase");
|
||||
used_prefixes |= PREFIX_REPZ;
|
||||
bytemode = dq_mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
BadOp ();
|
||||
return;
|
||||
}
|
||||
bytemode = 0;
|
||||
}
|
||||
|
||||
OP_E (bytemode, sizeflag);
|
||||
|
@ -81,6 +81,7 @@ typedef struct template
|
||||
#define CpuPCLMUL 0x10000000 /* Carry-less Multiplication extensions */
|
||||
#define CpuRdRnd 0x20000000 /* Intel Random Number Generator extensions */
|
||||
#define CpuSMAP 0x40000000 /* Intel Supervisor Mode Access Prevention */
|
||||
#define CpuFSGSBase 0x80000000 /* Read/write fs/gs segment base registers */
|
||||
|
||||
/* SSE4.1/4.2 Instructions required */
|
||||
#define CpuSSE4 (CpuSSE4_1|CpuSSE4_2)
|
||||
@ -89,7 +90,8 @@ typedef struct template
|
||||
#define CpuUnknownFlags (Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \
|
||||
|CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuVMX \
|
||||
|Cpu3dnow|Cpu3dnowA|CpuK6|CpuPadLock|CpuSVME|CpuSSSE3|CpuSSE4_1 \
|
||||
|CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP)
|
||||
|CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP \
|
||||
|CpuFSGSBase)
|
||||
|
||||
/* the bits in opcode_modifier are used to generate the final opcode from
|
||||
the base_opcode. These bits also are used to detect alternate forms of
|
||||
|
@ -1525,3 +1525,13 @@ pclmulhqhqdq, 2, 0x660f3a44, 0x11, CpuPCLMUL, Modrm|IgnoreSize|No_bSuf|No_wSuf|N
|
||||
// Intel Random Number Generator extensions
|
||||
rdrand, 1, 0x0fc7, 0x6, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 }
|
||||
rdseed, 1, 0x0fc7, 0x7, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 }
|
||||
|
||||
// Intel Supervisor Mode Access Prevention extensions
|
||||
clac, 0, 0x0f01, 0xca, CpuSMAP, NoSuf|ImmExt, { 0 }
|
||||
stac, 0, 0x0f01, 0xcb, CpuSMAP, NoSuf|ImmExt, { 0 }
|
||||
|
||||
// Read/write fs/gs segment base registers
|
||||
rdfsbase, 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
|
||||
rdgsbase, 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
|
||||
wrfsbase, 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
|
||||
wrgsbase, 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
|
||||
|
@ -4400,6 +4400,20 @@ const template i386_optab[] =
|
||||
NoSuf|ImmExt, { 0, 0, 0 } },
|
||||
{"stac", 0, 0x0f01, 0xcb, CpuSMAP,
|
||||
NoSuf|ImmExt, { 0, 0, 0 } },
|
||||
|
||||
/* Read/write fs/gs segment base registers */
|
||||
{"rdfsbase", 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64,
|
||||
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
|
||||
{ Reg32|Reg64 } },
|
||||
{"rdgsbase", 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64,
|
||||
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
|
||||
{ Reg32|Reg64 } },
|
||||
{"wrfsbase", 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64,
|
||||
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
|
||||
{ Reg32|Reg64 } },
|
||||
{"wrgsbase", 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64,
|
||||
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
|
||||
{ Reg32|Reg64 } },
|
||||
|
||||
{ NULL, 0, 0, 0, 0, 0, { 0 } }
|
||||
};
|
||||
|
@ -18,11 +18,20 @@
|
||||
// }
|
||||
// }
|
||||
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
# define CONVERT_DCMP_ARGS_TO_DF2_ARGS \
|
||||
vmov d0, r0, r1 SEPARATOR \
|
||||
vmov d1, r2, r3
|
||||
#else
|
||||
# define CONVERT_DCMP_ARGS_TO_DF2_ARGS
|
||||
#endif
|
||||
|
||||
#define DEFINE_AEABI_DCMP(cond) \
|
||||
.syntax unified SEPARATOR \
|
||||
.p2align 2 SEPARATOR \
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \
|
||||
push { r4, lr } SEPARATOR \
|
||||
CONVERT_DCMP_ARGS_TO_DF2_ARGS SEPARATOR \
|
||||
bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \
|
||||
cmp r0, #0 SEPARATOR \
|
||||
b ## cond 1f SEPARATOR \
|
||||
|
@ -18,11 +18,20 @@
|
||||
// }
|
||||
// }
|
||||
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
# define CONVERT_FCMP_ARGS_TO_SF2_ARGS \
|
||||
vmov s0, r0 SEPARATOR \
|
||||
vmov s1, r1
|
||||
#else
|
||||
# define CONVERT_FCMP_ARGS_TO_SF2_ARGS
|
||||
#endif
|
||||
|
||||
#define DEFINE_AEABI_FCMP(cond) \
|
||||
.syntax unified SEPARATOR \
|
||||
.p2align 2 SEPARATOR \
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
|
||||
push { r4, lr } SEPARATOR \
|
||||
CONVERT_FCMP_ARGS_TO_SF2_ARGS SEPARATOR \
|
||||
bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
|
||||
cmp r0, #0 SEPARATOR \
|
||||
b ## cond 1f SEPARATOR \
|
||||
|
@ -92,12 +92,13 @@
|
||||
* does not have dedicated bit counting instructions.
|
||||
*/
|
||||
#if defined(__FreeBSD__) && (defined(__sparc64__) || \
|
||||
defined(__mips_n64) || defined(__mips_o64) || defined(__riscv))
|
||||
defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) || \
|
||||
defined(__riscv))
|
||||
si_int __clzsi2(si_int);
|
||||
si_int __ctzsi2(si_int);
|
||||
#define __builtin_clz __clzsi2
|
||||
#define __builtin_ctz __ctzsi2
|
||||
#endif /* FreeBSD && (sparc64 || mips_n64 || mips_o64) */
|
||||
#endif /* FreeBSD && (sparc64 || mips_n32 || mips_n64 || mips_o64 || riscv) */
|
||||
|
||||
COMPILER_RT_ABI si_int __paritysi2(si_int a);
|
||||
COMPILER_RT_ABI si_int __paritydi2(di_int a);
|
||||
|
@ -70,7 +70,7 @@ int SidelineThread::runSideline(void *Arg) {
|
||||
|
||||
// Set up a signal handler on an alternate stack for safety.
|
||||
InternalScopedBuffer<char> StackMap(SigAltStackSize);
|
||||
struct sigaltstack SigAltStack;
|
||||
stack_t SigAltStack;
|
||||
SigAltStack.ss_sp = StackMap.data();
|
||||
SigAltStack.ss_size = SigAltStackSize;
|
||||
SigAltStack.ss_flags = 0;
|
||||
|
@ -1,11 +1,11 @@
|
||||
//===- InstrProfilingNameVar.c - profile name variable setup --------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/*===- InstrProfilingNameVar.c - profile name variable setup -------------===*\
|
||||
|*
|
||||
|* The LLVM Compiler Infrastructure
|
||||
|*
|
||||
|* This file is distributed under the University of Illinois Open Source
|
||||
|* License. See LICENSE.TXT for details.
|
||||
|*
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "InstrProfiling.h"
|
||||
|
||||
|
@ -77,8 +77,8 @@
|
||||
#define D_h x13
|
||||
#define E_l src
|
||||
#define E_h count
|
||||
#define F_l srcend
|
||||
#define F_h dst
|
||||
#define F_l dst
|
||||
#define F_h srcend
|
||||
#define tmp1 x9
|
||||
|
||||
#define L(l) .L ## l
|
||||
|
@ -509,7 +509,7 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
|
||||
size_t noff, size_t doff, int *flags)
|
||||
{
|
||||
if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
|
||||
type == NT_GNU_BUILD_ID && (descsz >= 4 || descsz <= 20)) {
|
||||
type == NT_GNU_BUILD_ID && (descsz >= 4 && descsz <= 20)) {
|
||||
uint8_t desc[20];
|
||||
const char *btype;
|
||||
uint32_t i;
|
||||
|
@ -85,7 +85,10 @@ namespace ISD {
|
||||
|
||||
/// If N is a BUILD_VECTOR node whose elements are all the same constant or
|
||||
/// undefined, return true and return the constant value in \p SplatValue.
|
||||
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
|
||||
/// This sets \p SplatValue to the smallest possible splat unless AllowShrink
|
||||
/// is set to false.
|
||||
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue,
|
||||
bool AllowShrink = true);
|
||||
|
||||
/// Return true if the specified node is a BUILD_VECTOR where all of the
|
||||
/// elements are ~0 or undef.
|
||||
@ -798,7 +801,8 @@ public:
|
||||
/// if DAG changes.
|
||||
static bool hasPredecessorHelper(const SDNode *N,
|
||||
SmallPtrSetImpl<const SDNode *> &Visited,
|
||||
SmallVectorImpl<const SDNode *> &Worklist) {
|
||||
SmallVectorImpl<const SDNode *> &Worklist,
|
||||
unsigned int MaxSteps = 0) {
|
||||
if (Visited.count(N))
|
||||
return true;
|
||||
while (!Worklist.empty()) {
|
||||
@ -813,6 +817,8 @@ public:
|
||||
}
|
||||
if (Found)
|
||||
return true;
|
||||
if (MaxSteps != 0 && Visited.size() >= MaxSteps)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "postdomtree"
|
||||
|
||||
template class llvm::DominatorTreeBase<BasicBlock, true>; // PostDomTreeBase
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PostDominatorTree Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1118,22 +1118,30 @@ SDValue DAGCombiner::PromoteIntBinOp(SDValue Op) {
|
||||
SDValue RV =
|
||||
DAG.getNode(ISD::TRUNCATE, DL, VT, DAG.getNode(Opc, DL, PVT, NN0, NN1));
|
||||
|
||||
// New replace instances of N0 and N1
|
||||
if (Replace0 && N0 && N0.getOpcode() != ISD::DELETED_NODE && NN0 &&
|
||||
NN0.getOpcode() != ISD::DELETED_NODE) {
|
||||
// We are always replacing N0/N1's use in N and only need
|
||||
// additional replacements if there are additional uses.
|
||||
Replace0 &= !N0->hasOneUse();
|
||||
Replace1 &= (N0 != N1) && !N1->hasOneUse();
|
||||
|
||||
// Combine Op here so it is presreved past replacements.
|
||||
CombineTo(Op.getNode(), RV);
|
||||
|
||||
// If operands have a use ordering, make sur we deal with
|
||||
// predecessor first.
|
||||
if (Replace0 && Replace1 && N0.getNode()->isPredecessorOf(N1.getNode())) {
|
||||
std::swap(N0, N1);
|
||||
std::swap(NN0, NN1);
|
||||
}
|
||||
|
||||
if (Replace0) {
|
||||
AddToWorklist(NN0.getNode());
|
||||
ReplaceLoadWithPromotedLoad(N0.getNode(), NN0.getNode());
|
||||
}
|
||||
|
||||
if (Replace1 && N1 && N1.getOpcode() != ISD::DELETED_NODE && NN1 &&
|
||||
NN1.getOpcode() != ISD::DELETED_NODE) {
|
||||
if (Replace1) {
|
||||
AddToWorklist(NN1.getNode());
|
||||
ReplaceLoadWithPromotedLoad(N1.getNode(), NN1.getNode());
|
||||
}
|
||||
|
||||
// Deal with Op being deleted.
|
||||
if (Op && Op.getOpcode() != ISD::DELETED_NODE)
|
||||
return RV;
|
||||
return Op;
|
||||
}
|
||||
return SDValue();
|
||||
}
|
||||
@ -12599,25 +12607,37 @@ void DAGCombiner::getStoreMergeCandidates(
|
||||
}
|
||||
}
|
||||
|
||||
// We need to check that merging these stores does not cause a loop
|
||||
// in the DAG. Any store candidate may depend on another candidate
|
||||
// We need to check that merging these stores does not cause a loop in
|
||||
// the DAG. Any store candidate may depend on another candidate
|
||||
// indirectly through its operand (we already consider dependencies
|
||||
// through the chain). Check in parallel by searching up from
|
||||
// non-chain operands of candidates.
|
||||
|
||||
bool DAGCombiner::checkMergeStoreCandidatesForDependencies(
|
||||
SmallVectorImpl<MemOpLink> &StoreNodes, unsigned NumStores) {
|
||||
|
||||
// FIXME: We should be able to truncate a full search of
|
||||
// predecessors by doing a BFS and keeping tabs the originating
|
||||
// stores from which worklist nodes come from in a similar way to
|
||||
// TokenFactor simplfication.
|
||||
|
||||
SmallPtrSet<const SDNode *, 16> Visited;
|
||||
SmallVector<const SDNode *, 8> Worklist;
|
||||
// search ops of store candidates
|
||||
unsigned int Max = 8192;
|
||||
// Search Ops of store candidates.
|
||||
for (unsigned i = 0; i < NumStores; ++i) {
|
||||
SDNode *n = StoreNodes[i].MemNode;
|
||||
// Potential loops may happen only through non-chain operands
|
||||
for (unsigned j = 1; j < n->getNumOperands(); ++j)
|
||||
Worklist.push_back(n->getOperand(j).getNode());
|
||||
}
|
||||
// search through DAG. We can stop early if we find a storenode
|
||||
// Search through DAG. We can stop early if we find a store node.
|
||||
for (unsigned i = 0; i < NumStores; ++i) {
|
||||
if (SDNode::hasPredecessorHelper(StoreNodes[i].MemNode, Visited, Worklist))
|
||||
if (SDNode::hasPredecessorHelper(StoreNodes[i].MemNode, Visited, Worklist,
|
||||
Max))
|
||||
return false;
|
||||
// Check if we ended early, failing conservatively if so.
|
||||
if (Visited.size() >= Max)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -627,6 +627,7 @@ private:
|
||||
SDValue ScalarizeVecOp_CONCAT_VECTORS(SDNode *N);
|
||||
SDValue ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
|
||||
SDValue ScalarizeVecOp_VSELECT(SDNode *N);
|
||||
SDValue ScalarizeVecOp_VSETCC(SDNode *N);
|
||||
SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo);
|
||||
SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo);
|
||||
|
||||
|
@ -484,6 +484,9 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::VSELECT:
|
||||
Res = ScalarizeVecOp_VSELECT(N);
|
||||
break;
|
||||
case ISD::SETCC:
|
||||
Res = ScalarizeVecOp_VSETCC(N);
|
||||
break;
|
||||
case ISD::STORE:
|
||||
Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
|
||||
break;
|
||||
@ -560,6 +563,36 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode *N) {
|
||||
N->getOperand(2));
|
||||
}
|
||||
|
||||
/// If the operand is a vector that needs to be scalarized then the
|
||||
/// result must be v1i1, so just convert to a scalar SETCC and wrap
|
||||
/// with a scalar_to_vector since the res type is legal if we got here
|
||||
SDValue DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode *N) {
|
||||
assert(N->getValueType(0).isVector() &&
|
||||
N->getOperand(0).getValueType().isVector() &&
|
||||
"Operand types must be vectors");
|
||||
assert(N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type");
|
||||
|
||||
EVT VT = N->getValueType(0);
|
||||
SDValue LHS = GetScalarizedVector(N->getOperand(0));
|
||||
SDValue RHS = GetScalarizedVector(N->getOperand(1));
|
||||
|
||||
EVT OpVT = N->getOperand(0).getValueType();
|
||||
EVT NVT = VT.getVectorElementType();
|
||||
SDLoc DL(N);
|
||||
// Turn it into a scalar SETCC.
|
||||
SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS,
|
||||
N->getOperand(2));
|
||||
|
||||
// Vectors may have a different boolean contents to scalars. Promote the
|
||||
// value appropriately.
|
||||
ISD::NodeType ExtendCode =
|
||||
TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
|
||||
|
||||
Res = DAG.getNode(ExtendCode, DL, NVT, Res);
|
||||
|
||||
return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Res);
|
||||
}
|
||||
|
||||
/// If the value to store is a vector that needs to be scalarized, it must be
|
||||
/// <1 x ty>. Just store the element.
|
||||
SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
|
||||
|
@ -116,7 +116,8 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
|
||||
// ISD Namespace
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
|
||||
bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal,
|
||||
bool AllowShrink) {
|
||||
auto *BV = dyn_cast<BuildVectorSDNode>(N);
|
||||
if (!BV)
|
||||
return false;
|
||||
@ -124,9 +125,11 @@ bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
|
||||
APInt SplatUndef;
|
||||
unsigned SplatBitSize;
|
||||
bool HasUndefs;
|
||||
EVT EltVT = N->getValueType(0).getVectorElementType();
|
||||
return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs) &&
|
||||
EltVT.getSizeInBits() >= SplatBitSize;
|
||||
unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits();
|
||||
unsigned MinSplatBits = AllowShrink ? 0 : EltSize;
|
||||
return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs,
|
||||
MinSplatBits) &&
|
||||
EltSize >= SplatBitSize;
|
||||
}
|
||||
|
||||
// FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be
|
||||
|
@ -2239,14 +2239,14 @@ bool llvm::UpgradeDebugInfo(Module &M) {
|
||||
}
|
||||
|
||||
bool llvm::UpgradeModuleFlags(Module &M) {
|
||||
const NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
|
||||
NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
|
||||
if (!ModFlags)
|
||||
return false;
|
||||
|
||||
bool HasObjCFlag = false, HasClassProperties = false;
|
||||
bool HasObjCFlag = false, HasClassProperties = false, Changed = false;
|
||||
for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
|
||||
MDNode *Op = ModFlags->getOperand(I);
|
||||
if (Op->getNumOperands() < 2)
|
||||
if (Op->getNumOperands() != 3)
|
||||
continue;
|
||||
MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
|
||||
if (!ID)
|
||||
@ -2255,7 +2255,24 @@ bool llvm::UpgradeModuleFlags(Module &M) {
|
||||
HasObjCFlag = true;
|
||||
if (ID->getString() == "Objective-C Class Properties")
|
||||
HasClassProperties = true;
|
||||
// Upgrade PIC/PIE Module Flags. The module flag behavior for these two
|
||||
// field was Error and now they are Max.
|
||||
if (ID->getString() == "PIC Level" || ID->getString() == "PIE Level") {
|
||||
if (auto *Behavior =
|
||||
mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) {
|
||||
if (Behavior->getLimitedValue() == Module::Error) {
|
||||
Type *Int32Ty = Type::getInt32Ty(M.getContext());
|
||||
Metadata *Ops[3] = {
|
||||
ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Max)),
|
||||
MDString::get(M.getContext(), ID->getString()),
|
||||
Op->getOperand(2)};
|
||||
ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "Objective-C Class Properties" is recently added for Objective-C. We
|
||||
// upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module
|
||||
// flag of value 0, so we can correclty downgrade this flag when trying to
|
||||
@ -2264,9 +2281,10 @@ bool llvm::UpgradeModuleFlags(Module &M) {
|
||||
if (HasObjCFlag && !HasClassProperties) {
|
||||
M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties",
|
||||
(uint32_t)0);
|
||||
return true;
|
||||
Changed = true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
static bool isOldLoopArgument(Metadata *MD) {
|
||||
|
@ -232,7 +232,13 @@ private:
|
||||
for (;;) {
|
||||
read();
|
||||
if (Tok.K == Identifier && Tok.Value[0] == '@') {
|
||||
Tok.Value.drop_front().getAsInteger(10, E.Ordinal);
|
||||
if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) {
|
||||
// Not an ordinal modifier at all, but the next export (fastcall
|
||||
// decorated) - complete the current one.
|
||||
unget();
|
||||
Info.Exports.push_back(E);
|
||||
return Error::success();
|
||||
}
|
||||
read();
|
||||
if (Tok.K == KwNoname) {
|
||||
E.Noname = true;
|
||||
|
@ -5901,7 +5901,10 @@ static bool isVUZPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < M.size(); i += NumElts) {
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
if (M.size() == NumElts * 2)
|
||||
WhichResult = i / NumElts;
|
||||
else
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
for (unsigned j = 0; j < NumElts; ++j) {
|
||||
if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult)
|
||||
return false;
|
||||
@ -5932,7 +5935,10 @@ static bool isVUZP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
|
||||
|
||||
unsigned Half = NumElts / 2;
|
||||
for (unsigned i = 0; i < M.size(); i += NumElts) {
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
if (M.size() == NumElts * 2)
|
||||
WhichResult = i / NumElts;
|
||||
else
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
for (unsigned j = 0; j < NumElts; j += Half) {
|
||||
unsigned Idx = WhichResult;
|
||||
for (unsigned k = 0; k < Half; ++k) {
|
||||
@ -5972,7 +5978,10 @@ static bool isVZIPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < M.size(); i += NumElts) {
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
if (M.size() == NumElts * 2)
|
||||
WhichResult = i / NumElts;
|
||||
else
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
unsigned Idx = WhichResult * NumElts / 2;
|
||||
for (unsigned j = 0; j < NumElts; j += 2) {
|
||||
if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
|
||||
@ -6005,7 +6014,10 @@ static bool isVZIP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < M.size(); i += NumElts) {
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
if (M.size() == NumElts * 2)
|
||||
WhichResult = i / NumElts;
|
||||
else
|
||||
WhichResult = M[i] == 0 ? 0 : 1;
|
||||
unsigned Idx = WhichResult * NumElts / 2;
|
||||
for (unsigned j = 0; j < NumElts; j += 2) {
|
||||
if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
|
||||
@ -8793,6 +8805,8 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
|
||||
.addReg(ARM::R4, RegState::Implicit | RegState::Kill)
|
||||
.addReg(ARM::R4, RegState::Implicit | RegState::Define)
|
||||
.addReg(ARM::R12,
|
||||
RegState::Implicit | RegState::Define | RegState::Dead)
|
||||
.addReg(ARM::CPSR,
|
||||
RegState::Implicit | RegState::Define | RegState::Dead);
|
||||
break;
|
||||
case CodeModel::Large:
|
||||
@ -8808,6 +8822,8 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
|
||||
.addReg(ARM::R4, RegState::Implicit | RegState::Kill)
|
||||
.addReg(ARM::R4, RegState::Implicit | RegState::Define)
|
||||
.addReg(ARM::R12,
|
||||
RegState::Implicit | RegState::Define | RegState::Dead)
|
||||
.addReg(ARM::CPSR,
|
||||
RegState::Implicit | RegState::Define | RegState::Dead);
|
||||
break;
|
||||
}
|
||||
|
@ -29540,8 +29540,9 @@ static bool detectZextAbsDiff(const SDValue &Select, SDValue &Op0,
|
||||
// In SetLT case, The second operand of the comparison can be either 1 or 0.
|
||||
APInt SplatVal;
|
||||
if ((CC == ISD::SETLT) &&
|
||||
!((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal) &&
|
||||
SplatVal == 1) ||
|
||||
!((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal,
|
||||
/*AllowShrink*/false) &&
|
||||
SplatVal.isOneValue()) ||
|
||||
(ISD::isBuildVectorAllZeros(SetCC.getOperand(1).getNode()))))
|
||||
return false;
|
||||
|
||||
@ -30628,6 +30629,9 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
|
||||
// Byte blends are only available in AVX2
|
||||
if (VT == MVT::v32i8 && !Subtarget.hasAVX2())
|
||||
return SDValue();
|
||||
// There are no 512-bit blend instructions that use sign bits.
|
||||
if (VT.is512BitVector())
|
||||
return SDValue();
|
||||
|
||||
assert(BitWidth >= 8 && BitWidth <= 64 && "Invalid mask size");
|
||||
APInt DemandedMask(APInt::getSignMask(BitWidth));
|
||||
@ -30938,11 +30942,40 @@ static bool checkBoolTestAndOrSetCCCombine(SDValue Cond, X86::CondCode &CC0,
|
||||
return true;
|
||||
}
|
||||
|
||||
// When legalizing carry, we create carries via add X, -1
|
||||
// If that comes from an actual carry, via setcc, we use the
|
||||
// carry directly.
|
||||
static SDValue combineCarryThroughADD(SDValue EFLAGS) {
|
||||
if (EFLAGS.getOpcode() == X86ISD::ADD) {
|
||||
if (isAllOnesConstant(EFLAGS.getOperand(1))) {
|
||||
SDValue Carry = EFLAGS.getOperand(0);
|
||||
while (Carry.getOpcode() == ISD::TRUNCATE ||
|
||||
Carry.getOpcode() == ISD::ZERO_EXTEND ||
|
||||
Carry.getOpcode() == ISD::SIGN_EXTEND ||
|
||||
Carry.getOpcode() == ISD::ANY_EXTEND ||
|
||||
(Carry.getOpcode() == ISD::AND &&
|
||||
isOneConstant(Carry.getOperand(1))))
|
||||
Carry = Carry.getOperand(0);
|
||||
if (Carry.getOpcode() == X86ISD::SETCC ||
|
||||
Carry.getOpcode() == X86ISD::SETCC_CARRY) {
|
||||
if (Carry.getConstantOperandVal(0) == X86::COND_B)
|
||||
return Carry.getOperand(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
/// Optimize an EFLAGS definition used according to the condition code \p CC
|
||||
/// into a simpler EFLAGS value, potentially returning a new \p CC and replacing
|
||||
/// uses of chain values.
|
||||
static SDValue combineSetCCEFLAGS(SDValue EFLAGS, X86::CondCode &CC,
|
||||
SelectionDAG &DAG) {
|
||||
if (CC == X86::COND_B)
|
||||
if (SDValue Flags = combineCarryThroughADD(EFLAGS))
|
||||
return Flags;
|
||||
|
||||
if (SDValue R = checkBoolTestSetCCCombine(EFLAGS, CC))
|
||||
return R;
|
||||
return combineSetCCAtomicArith(EFLAGS, CC, DAG);
|
||||
@ -32058,7 +32091,8 @@ static SDValue combineAndMaskToShift(SDNode *N, SelectionDAG &DAG,
|
||||
return SDValue();
|
||||
|
||||
APInt SplatVal;
|
||||
if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) ||
|
||||
if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal,
|
||||
/*AllowShrink*/false) ||
|
||||
!SplatVal.isMask())
|
||||
return SDValue();
|
||||
|
||||
@ -32642,7 +32676,8 @@ static SDValue detectUSatPattern(SDValue In, EVT VT) {
|
||||
"Unexpected types for truncate operation");
|
||||
|
||||
APInt C;
|
||||
if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C)) {
|
||||
if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C,
|
||||
/*AllowShrink*/false)) {
|
||||
// C should be equal to UINT32_MAX / UINT16_MAX / UINT8_MAX according
|
||||
// the element size of the destination type.
|
||||
return C.isMask(VT.getScalarSizeInBits()) ? In.getOperand(0) :
|
||||
@ -34983,27 +35018,13 @@ static SDValue combineSIntToFP(SDNode *N, SelectionDAG &DAG,
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// Optimize RES, EFLAGS = X86ISD::ADD LHS, RHS
|
||||
static SDValue combineX86ADD(SDNode *N, SelectionDAG &DAG,
|
||||
X86TargetLowering::DAGCombinerInfo &DCI) {
|
||||
// When legalizing carry, we create carries via add X, -1
|
||||
// If that comes from an actual carry, via setcc, we use the
|
||||
// carry directly.
|
||||
if (isAllOnesConstant(N->getOperand(1)) && N->hasAnyUseOfValue(1)) {
|
||||
SDValue Carry = N->getOperand(0);
|
||||
while (Carry.getOpcode() == ISD::TRUNCATE ||
|
||||
Carry.getOpcode() == ISD::ZERO_EXTEND ||
|
||||
Carry.getOpcode() == ISD::SIGN_EXTEND ||
|
||||
Carry.getOpcode() == ISD::ANY_EXTEND ||
|
||||
(Carry.getOpcode() == ISD::AND &&
|
||||
isOneConstant(Carry.getOperand(1))))
|
||||
Carry = Carry.getOperand(0);
|
||||
|
||||
if (Carry.getOpcode() == X86ISD::SETCC ||
|
||||
Carry.getOpcode() == X86ISD::SETCC_CARRY) {
|
||||
if (Carry.getConstantOperandVal(0) == X86::COND_B)
|
||||
return DCI.CombineTo(N, SDValue(N, 0), Carry.getOperand(1));
|
||||
}
|
||||
static SDValue combineSBB(SDNode *N, SelectionDAG &DAG) {
|
||||
if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
|
||||
MVT VT = N->getSimpleValueType(0);
|
||||
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
|
||||
return DAG.getNode(X86ISD::SBB, SDLoc(N), VTs,
|
||||
N->getOperand(0), N->getOperand(1),
|
||||
Flags);
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
@ -35032,6 +35053,14 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
|
||||
return DCI.CombineTo(N, Res1, CarryOut);
|
||||
}
|
||||
|
||||
if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
|
||||
MVT VT = N->getSimpleValueType(0);
|
||||
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
|
||||
return DAG.getNode(X86ISD::ADC, SDLoc(N), VTs,
|
||||
N->getOperand(0), N->getOperand(1),
|
||||
Flags);
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
@ -35346,7 +35375,8 @@ static SDValue combineIncDecVector(SDNode *N, SelectionDAG &DAG) {
|
||||
|
||||
SDNode *N1 = N->getOperand(1).getNode();
|
||||
APInt SplatVal;
|
||||
if (!ISD::isConstantSplatVector(N1, SplatVal) || !SplatVal.isOneValue())
|
||||
if (!ISD::isConstantSplatVector(N1, SplatVal, /*AllowShrink*/false) ||
|
||||
!SplatVal.isOneValue())
|
||||
return SDValue();
|
||||
|
||||
SDValue AllOnesVec = getOnesVector(VT, DAG, SDLoc(N));
|
||||
@ -35670,7 +35700,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
|
||||
case X86ISD::CMOV: return combineCMov(N, DAG, DCI, Subtarget);
|
||||
case ISD::ADD: return combineAdd(N, DAG, Subtarget);
|
||||
case ISD::SUB: return combineSub(N, DAG, Subtarget);
|
||||
case X86ISD::ADD: return combineX86ADD(N, DAG, DCI);
|
||||
case X86ISD::SBB: return combineSBB(N, DAG);
|
||||
case X86ISD::ADC: return combineADC(N, DAG, DCI);
|
||||
case ISD::MUL: return combineMul(N, DAG, DCI, Subtarget);
|
||||
case ISD::SHL:
|
||||
|
@ -3619,8 +3619,8 @@ let Predicates = [HasVLX] in {
|
||||
def : Pat<(alignedstore256 (v4f64 (extract_subvector
|
||||
(v8f64 VR512:$src), (iPTR 0))), addr:$dst),
|
||||
(VMOVAPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
|
||||
def : Pat<(alignedstore (v8f32 (extract_subvector
|
||||
(v16f32 VR512:$src), (iPTR 0))), addr:$dst),
|
||||
def : Pat<(alignedstore256 (v8f32 (extract_subvector
|
||||
(v16f32 VR512:$src), (iPTR 0))), addr:$dst),
|
||||
(VMOVAPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
|
||||
def : Pat<(alignedstore256 (v4i64 (extract_subvector
|
||||
(v8i64 VR512:$src), (iPTR 0))), addr:$dst),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -161,6 +161,22 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
|
||||
if (Path.empty())
|
||||
Path = getImplibPath(Def->OutputFile);
|
||||
|
||||
if (Machine == IMAGE_FILE_MACHINE_I386 && Args.getLastArg(OPT_k)) {
|
||||
for (COFFShortExport& E : Def->Exports) {
|
||||
if (E.isWeak() || (!E.Name.empty() && E.Name[0] == '?'))
|
||||
continue;
|
||||
E.SymbolName = E.Name;
|
||||
// Trim off the trailing decoration. Symbols will always have a
|
||||
// starting prefix here (either _ for cdecl/stdcall, @ for fastcall
|
||||
// or ? for C++ functions). (Vectorcall functions also will end up having
|
||||
// a prefix here, even if they shouldn't.)
|
||||
E.Name = E.Name.substr(0, E.Name.find('@', 1));
|
||||
// By making sure E.SymbolName != E.Name for decorated symbols,
|
||||
// writeImportLibrary writes these symbols with the type
|
||||
// IMPORT_NAME_UNDECORATE.
|
||||
}
|
||||
}
|
||||
|
||||
if (writeImportLibrary(Def->OutputFile, Path, Def->Exports, Machine, true))
|
||||
return 1;
|
||||
return 0;
|
||||
|
@ -12,13 +12,13 @@ def D_long : JoinedOrSeparate<["--"], "dllname">, Alias<D>;
|
||||
def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">;
|
||||
def d_long : JoinedOrSeparate<["--"], "input-def">, Alias<d>;
|
||||
|
||||
def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
|
||||
def k_alias: Flag<["--"], "kill-at">, Alias<k>;
|
||||
|
||||
//==============================================================================
|
||||
// The flags below do nothing. They are defined only for dlltool compatibility.
|
||||
//==============================================================================
|
||||
|
||||
def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
|
||||
def k_alias: Flag<["--"], "kill-at">, Alias<k>;
|
||||
|
||||
def S: JoinedOrSeparate<["-"], "S">, HelpText<"Assembler">;
|
||||
def S_alias: JoinedOrSeparate<["--"], "as">, Alias<S>;
|
||||
|
||||
|
@ -155,8 +155,7 @@ public:
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) override {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
// Don't skip optnone functions; atomics still need to be lowered.
|
||||
FunctionAnalysisManager DummyFAM;
|
||||
auto PA = Impl.run(F, DummyFAM);
|
||||
return !PA.areAllPreserved();
|
||||
|
@ -1941,6 +1941,12 @@ Instruction *ReassociatePass::canonicalizeNegConstExpr(Instruction *I) {
|
||||
if (!User->isCommutative() && User->getOperand(1) != I)
|
||||
return nullptr;
|
||||
|
||||
// Don't canonicalize x + (-Constant * y) -> x - (Constant * y), if the
|
||||
// resulting subtract will be broken up later. This can get us into an
|
||||
// infinite loop during reassociation.
|
||||
if (UserOpcode == Instruction::FAdd && ShouldBreakUpSubtract(User))
|
||||
return nullptr;
|
||||
|
||||
// Change the sign of the constant.
|
||||
APFloat Val = CF->getValueAPF();
|
||||
Val.changeSign();
|
||||
|
@ -341,8 +341,9 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
|
||||
SimplifyInstruction(NewInst, BB->getModule()->getDataLayout())) {
|
||||
// On the off-chance that this simplifies to an instruction in the old
|
||||
// function, map it back into the new function.
|
||||
if (Value *MappedV = VMap.lookup(V))
|
||||
V = MappedV;
|
||||
if (NewFunc != OldFunc)
|
||||
if (Value *MappedV = VMap.lookup(V))
|
||||
V = MappedV;
|
||||
|
||||
if (!NewInst->mayHaveSideEffects()) {
|
||||
VMap[&*II] = V;
|
||||
|
@ -375,6 +375,7 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// \brief These flags are \c true if a defaulted corresponding special
|
||||
/// member can't be fully analyzed without performing overload resolution.
|
||||
/// @{
|
||||
unsigned NeedOverloadResolutionForCopyConstructor : 1;
|
||||
unsigned NeedOverloadResolutionForMoveConstructor : 1;
|
||||
unsigned NeedOverloadResolutionForMoveAssignment : 1;
|
||||
unsigned NeedOverloadResolutionForDestructor : 1;
|
||||
@ -383,6 +384,7 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// \brief These flags are \c true if an implicit defaulted corresponding
|
||||
/// special member would be defined as deleted.
|
||||
/// @{
|
||||
unsigned DefaultedCopyConstructorIsDeleted : 1;
|
||||
unsigned DefaultedMoveConstructorIsDeleted : 1;
|
||||
unsigned DefaultedMoveAssignmentIsDeleted : 1;
|
||||
unsigned DefaultedDestructorIsDeleted : 1;
|
||||
@ -415,6 +417,12 @@ class CXXRecordDecl : public RecordDecl {
|
||||
/// constructor.
|
||||
unsigned HasDefaultedDefaultConstructor : 1;
|
||||
|
||||
/// \brief True if this class can be passed in a non-address-preserving
|
||||
/// fashion (such as in registers) according to the C++ language rules.
|
||||
/// This does not imply anything about how the ABI in use will actually
|
||||
/// pass an object of this class.
|
||||
unsigned CanPassInRegisters : 1;
|
||||
|
||||
/// \brief True if a defaulted default constructor for this class would
|
||||
/// be constexpr.
|
||||
unsigned DefaultedDefaultConstructorIsConstexpr : 1;
|
||||
@ -811,18 +819,50 @@ public:
|
||||
return data().FirstFriend.isValid();
|
||||
}
|
||||
|
||||
/// \brief \c true if a defaulted copy constructor for this class would be
|
||||
/// deleted.
|
||||
bool defaultedCopyConstructorIsDeleted() const {
|
||||
assert((!needsOverloadResolutionForCopyConstructor() ||
|
||||
(data().DeclaredSpecialMembers & SMF_CopyConstructor)) &&
|
||||
"this property has not yet been computed by Sema");
|
||||
return data().DefaultedCopyConstructorIsDeleted;
|
||||
}
|
||||
|
||||
/// \brief \c true if a defaulted move constructor for this class would be
|
||||
/// deleted.
|
||||
bool defaultedMoveConstructorIsDeleted() const {
|
||||
assert((!needsOverloadResolutionForMoveConstructor() ||
|
||||
(data().DeclaredSpecialMembers & SMF_MoveConstructor)) &&
|
||||
"this property has not yet been computed by Sema");
|
||||
return data().DefaultedMoveConstructorIsDeleted;
|
||||
}
|
||||
|
||||
/// \brief \c true if a defaulted destructor for this class would be deleted.
|
||||
bool defaultedDestructorIsDeleted() const {
|
||||
return !data().DefaultedDestructorIsDeleted;
|
||||
}
|
||||
|
||||
/// \brief \c true if we know for sure that this class has a single,
|
||||
/// accessible, unambiguous copy constructor that is not deleted.
|
||||
bool hasSimpleCopyConstructor() const {
|
||||
return !hasUserDeclaredCopyConstructor() &&
|
||||
!data().DefaultedCopyConstructorIsDeleted;
|
||||
}
|
||||
|
||||
/// \brief \c true if we know for sure that this class has a single,
|
||||
/// accessible, unambiguous move constructor that is not deleted.
|
||||
bool hasSimpleMoveConstructor() const {
|
||||
return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
|
||||
!data().DefaultedMoveConstructorIsDeleted;
|
||||
}
|
||||
|
||||
/// \brief \c true if we know for sure that this class has a single,
|
||||
/// accessible, unambiguous move assignment operator that is not deleted.
|
||||
bool hasSimpleMoveAssignment() const {
|
||||
return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
|
||||
!data().DefaultedMoveAssignmentIsDeleted;
|
||||
}
|
||||
|
||||
/// \brief \c true if we know for sure that this class has an accessible
|
||||
/// destructor that is not deleted.
|
||||
bool hasSimpleDestructor() const {
|
||||
@ -878,7 +918,16 @@ public:
|
||||
/// \brief Determine whether we need to eagerly declare a defaulted copy
|
||||
/// constructor for this class.
|
||||
bool needsOverloadResolutionForCopyConstructor() const {
|
||||
return data().HasMutableFields;
|
||||
// C++17 [class.copy.ctor]p6:
|
||||
// If the class definition declares a move constructor or move assignment
|
||||
// operator, the implicitly declared copy constructor is defined as
|
||||
// deleted.
|
||||
// In MSVC mode, sometimes a declared move assignment does not delete an
|
||||
// implicit copy constructor, so defer this choice to Sema.
|
||||
if (data().UserDeclaredSpecialMembers &
|
||||
(SMF_MoveConstructor | SMF_MoveAssignment))
|
||||
return true;
|
||||
return data().NeedOverloadResolutionForCopyConstructor;
|
||||
}
|
||||
|
||||
/// \brief Determine whether an implicit copy constructor for this type
|
||||
@ -919,7 +968,16 @@ public:
|
||||
needsImplicitMoveConstructor();
|
||||
}
|
||||
|
||||
/// \brief Set that we attempted to declare an implicitly move
|
||||
/// \brief Set that we attempted to declare an implicit copy
|
||||
/// constructor, but overload resolution failed so we deleted it.
|
||||
void setImplicitCopyConstructorIsDeleted() {
|
||||
assert((data().DefaultedCopyConstructorIsDeleted ||
|
||||
needsOverloadResolutionForCopyConstructor()) &&
|
||||
"Copy constructor should not be deleted");
|
||||
data().DefaultedCopyConstructorIsDeleted = true;
|
||||
}
|
||||
|
||||
/// \brief Set that we attempted to declare an implicit move
|
||||
/// constructor, but overload resolution failed so we deleted it.
|
||||
void setImplicitMoveConstructorIsDeleted() {
|
||||
assert((data().DefaultedMoveConstructorIsDeleted ||
|
||||
@ -1316,6 +1374,18 @@ public:
|
||||
return data().HasIrrelevantDestructor;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has at least one trivial, non-deleted
|
||||
/// copy or move constructor.
|
||||
bool canPassInRegisters() const {
|
||||
return data().CanPassInRegisters;
|
||||
}
|
||||
|
||||
/// \brief Set that we can pass this RecordDecl in registers.
|
||||
// FIXME: This should be set as part of completeDefinition.
|
||||
void setCanPassInRegisters(bool CanPass) {
|
||||
data().CanPassInRegisters = CanPass;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has a non-literal or/ volatile type
|
||||
/// non-static data member or base class.
|
||||
bool hasNonLiteralTypeFieldsOrBases() const {
|
||||
@ -1958,7 +2028,10 @@ public:
|
||||
|
||||
/// \brief Returns the type of the \c this pointer.
|
||||
///
|
||||
/// Should only be called for instance (i.e., non-static) methods.
|
||||
/// Should only be called for instance (i.e., non-static) methods. Note
|
||||
/// that for the call operator of a lambda closure type, this returns the
|
||||
/// desugared 'this' type (a pointer to the closure type), not the captured
|
||||
/// 'this' type.
|
||||
QualType getThisType(ASTContext &C) const;
|
||||
|
||||
unsigned getTypeQualifiers() const {
|
||||
|
@ -694,6 +694,9 @@ def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>;
|
||||
def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,
|
||||
Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">;
|
||||
def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
|
||||
def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Group>,
|
||||
Flags<[CC1Option]>, MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
|
||||
HelpText<"Attempt to match the ABI of Clang <version>">;
|
||||
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
|
||||
def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
|
||||
Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">;
|
||||
|
@ -120,6 +120,10 @@ CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
|
||||
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
|
||||
CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
|
||||
///< enabled.
|
||||
|
||||
/// A version of Clang that we should attempt to be ABI-compatible with.
|
||||
ENUM_CODEGENOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest)
|
||||
|
||||
VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
|
||||
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
|
||||
|
||||
|
@ -69,6 +69,23 @@ public:
|
||||
LocalExecTLSModel
|
||||
};
|
||||
|
||||
/// Clang versions with different platform ABI conformance.
|
||||
enum class ClangABI {
|
||||
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
|
||||
/// (SVN r257626). This causes <1 x long long> to be passed in an
|
||||
/// integer register instead of an SSE register on x64_64.
|
||||
Ver3_8,
|
||||
|
||||
/// Attempt to be ABI-compatible with code generated by Clang 4.0.x
|
||||
/// (SVN r291814). This causes move operations to be ignored when
|
||||
/// determining whether a class type can be passed or returned directly.
|
||||
Ver4,
|
||||
|
||||
/// Conform to the underlying platform's C and C++ ABIs as closely
|
||||
/// as we can.
|
||||
Latest
|
||||
};
|
||||
|
||||
enum StructReturnConventionKind {
|
||||
SRCK_Default, // No special option was passed.
|
||||
SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return).
|
||||
|
@ -1048,10 +1048,6 @@ public:
|
||||
/// which implicitly adds the builtin defines etc.
|
||||
void EnterMainSourceFile();
|
||||
|
||||
/// \brief After parser warm-up, initialize the conditional stack from
|
||||
/// the preamble.
|
||||
void replayPreambleConditionalStack();
|
||||
|
||||
/// \brief Inform the preprocessor callbacks that processing is complete.
|
||||
void EndSourceFile();
|
||||
|
||||
@ -2025,6 +2021,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief After processing predefined file, initialize the conditional stack from
|
||||
/// the preamble.
|
||||
void replayPreambleConditionalStack();
|
||||
|
||||
// Macro handling.
|
||||
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
|
||||
void HandleUndefDirective();
|
||||
|
@ -956,12 +956,16 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
|
||||
ToData.HasUninitializedFields = FromData.HasUninitializedFields;
|
||||
ToData.HasInheritedConstructor = FromData.HasInheritedConstructor;
|
||||
ToData.HasInheritedAssignment = FromData.HasInheritedAssignment;
|
||||
ToData.NeedOverloadResolutionForCopyConstructor
|
||||
= FromData.NeedOverloadResolutionForCopyConstructor;
|
||||
ToData.NeedOverloadResolutionForMoveConstructor
|
||||
= FromData.NeedOverloadResolutionForMoveConstructor;
|
||||
ToData.NeedOverloadResolutionForMoveAssignment
|
||||
= FromData.NeedOverloadResolutionForMoveAssignment;
|
||||
ToData.NeedOverloadResolutionForDestructor
|
||||
= FromData.NeedOverloadResolutionForDestructor;
|
||||
ToData.DefaultedCopyConstructorIsDeleted
|
||||
= FromData.DefaultedCopyConstructorIsDeleted;
|
||||
ToData.DefaultedMoveConstructorIsDeleted
|
||||
= FromData.DefaultedMoveConstructorIsDeleted;
|
||||
ToData.DefaultedMoveAssignmentIsDeleted
|
||||
@ -973,6 +977,7 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
|
||||
= FromData.HasConstexprNonCopyMoveConstructor;
|
||||
ToData.HasDefaultedDefaultConstructor
|
||||
= FromData.HasDefaultedDefaultConstructor;
|
||||
ToData.CanPassInRegisters = FromData.CanPassInRegisters;
|
||||
ToData.DefaultedDefaultConstructorIsConstexpr
|
||||
= FromData.DefaultedDefaultConstructorIsConstexpr;
|
||||
ToData.HasConstexprDefaultConstructor
|
||||
|
@ -55,15 +55,18 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
|
||||
HasOnlyCMembers(true), HasInClassInitializer(false),
|
||||
HasUninitializedReferenceMember(false), HasUninitializedFields(false),
|
||||
HasInheritedConstructor(false), HasInheritedAssignment(false),
|
||||
NeedOverloadResolutionForCopyConstructor(false),
|
||||
NeedOverloadResolutionForMoveConstructor(false),
|
||||
NeedOverloadResolutionForMoveAssignment(false),
|
||||
NeedOverloadResolutionForDestructor(false),
|
||||
DefaultedCopyConstructorIsDeleted(false),
|
||||
DefaultedMoveConstructorIsDeleted(false),
|
||||
DefaultedMoveAssignmentIsDeleted(false),
|
||||
DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
|
||||
DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true),
|
||||
HasConstexprNonCopyMoveConstructor(false),
|
||||
HasDefaultedDefaultConstructor(false),
|
||||
CanPassInRegisters(true),
|
||||
DefaultedDefaultConstructorIsConstexpr(true),
|
||||
HasConstexprDefaultConstructor(false),
|
||||
HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
|
||||
@ -352,8 +355,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
|
||||
setHasVolatileMember(true);
|
||||
|
||||
// Keep track of the presence of mutable fields.
|
||||
if (BaseClassDecl->hasMutableFields())
|
||||
if (BaseClassDecl->hasMutableFields()) {
|
||||
data().HasMutableFields = true;
|
||||
data().NeedOverloadResolutionForCopyConstructor = true;
|
||||
}
|
||||
|
||||
if (BaseClassDecl->hasUninitializedReferenceMember())
|
||||
data().HasUninitializedReferenceMember = true;
|
||||
@ -406,6 +411,8 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
|
||||
// -- a direct or virtual base class B that cannot be copied/moved [...]
|
||||
// -- a non-static data member of class type M (or array thereof)
|
||||
// that cannot be copied or moved [...]
|
||||
if (!Subobj->hasSimpleCopyConstructor())
|
||||
data().NeedOverloadResolutionForCopyConstructor = true;
|
||||
if (!Subobj->hasSimpleMoveConstructor())
|
||||
data().NeedOverloadResolutionForMoveConstructor = true;
|
||||
|
||||
@ -426,6 +433,7 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
|
||||
// -- any non-static data member has a type with a destructor
|
||||
// that is deleted or inaccessible from the defaulted [ctor or dtor].
|
||||
if (!Subobj->hasSimpleDestructor()) {
|
||||
data().NeedOverloadResolutionForCopyConstructor = true;
|
||||
data().NeedOverloadResolutionForMoveConstructor = true;
|
||||
data().NeedOverloadResolutionForDestructor = true;
|
||||
}
|
||||
@ -711,8 +719,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
data().IsStandardLayout = false;
|
||||
|
||||
// Keep track of the presence of mutable fields.
|
||||
if (Field->isMutable())
|
||||
if (Field->isMutable()) {
|
||||
data().HasMutableFields = true;
|
||||
data().NeedOverloadResolutionForCopyConstructor = true;
|
||||
}
|
||||
|
||||
// C++11 [class.union]p8, DR1460:
|
||||
// If X is a union, a non-static data member of X that is not an anonymous
|
||||
@ -756,6 +766,12 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
// A standard-layout class is a class that:
|
||||
// -- has no non-static data members of type [...] reference,
|
||||
data().IsStandardLayout = false;
|
||||
|
||||
// C++1z [class.copy.ctor]p10:
|
||||
// A defaulted copy constructor for a class X is defined as deleted if X has:
|
||||
// -- a non-static data member of rvalue reference type
|
||||
if (T->isRValueReferenceType())
|
||||
data().DefaultedCopyConstructorIsDeleted = true;
|
||||
}
|
||||
|
||||
if (!Field->hasInClassInitializer() && !Field->isMutable()) {
|
||||
@ -809,6 +825,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
// We may need to perform overload resolution to determine whether a
|
||||
// field can be moved if it's const or volatile qualified.
|
||||
if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
|
||||
// We need to care about 'const' for the copy constructor because an
|
||||
// implicit copy constructor might be declared with a non-const
|
||||
// parameter.
|
||||
data().NeedOverloadResolutionForCopyConstructor = true;
|
||||
data().NeedOverloadResolutionForMoveConstructor = true;
|
||||
data().NeedOverloadResolutionForMoveAssignment = true;
|
||||
}
|
||||
@ -819,6 +839,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
// -- X is a union-like class that has a variant member with a
|
||||
// non-trivial [corresponding special member]
|
||||
if (isUnion()) {
|
||||
if (FieldRec->hasNonTrivialCopyConstructor())
|
||||
data().DefaultedCopyConstructorIsDeleted = true;
|
||||
if (FieldRec->hasNonTrivialMoveConstructor())
|
||||
data().DefaultedMoveConstructorIsDeleted = true;
|
||||
if (FieldRec->hasNonTrivialMoveAssignment())
|
||||
@ -830,6 +852,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
// For an anonymous union member, our overload resolution will perform
|
||||
// overload resolution for its members.
|
||||
if (Field->isAnonymousStructOrUnion()) {
|
||||
data().NeedOverloadResolutionForCopyConstructor |=
|
||||
FieldRec->data().NeedOverloadResolutionForCopyConstructor;
|
||||
data().NeedOverloadResolutionForMoveConstructor |=
|
||||
FieldRec->data().NeedOverloadResolutionForMoveConstructor;
|
||||
data().NeedOverloadResolutionForMoveAssignment |=
|
||||
@ -915,8 +939,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
}
|
||||
|
||||
// Keep track of the presence of mutable fields.
|
||||
if (FieldRec->hasMutableFields())
|
||||
if (FieldRec->hasMutableFields()) {
|
||||
data().HasMutableFields = true;
|
||||
data().NeedOverloadResolutionForCopyConstructor = true;
|
||||
}
|
||||
|
||||
// C++11 [class.copy]p13:
|
||||
// If the implicitly-defined constructor would satisfy the
|
||||
@ -1450,7 +1476,7 @@ void CXXRecordDecl::completeDefinition() {
|
||||
|
||||
void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
|
||||
RecordDecl::completeDefinition();
|
||||
|
||||
|
||||
// If the class may be abstract (but hasn't been marked as such), check for
|
||||
// any pure final overriders.
|
||||
if (mayBeAbstract()) {
|
||||
|
@ -36,7 +36,7 @@ std::string getClangRepositoryPath() {
|
||||
|
||||
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
|
||||
// pick up a tag in an SVN export, for example.
|
||||
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_50/lib/Basic/Version.cpp $");
|
||||
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_500/final/lib/Basic/Version.cpp $");
|
||||
if (URL.empty()) {
|
||||
URL = SVNRepository.slice(SVNRepository.find(':'),
|
||||
SVNRepository.find("/lib/Basic"));
|
||||
|
@ -24,6 +24,7 @@ namespace llvm {
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CodeGenOptions;
|
||||
class TargetInfo;
|
||||
|
||||
namespace CodeGen {
|
||||
@ -68,6 +69,7 @@ namespace swiftcall {
|
||||
llvm::LLVMContext &getVMContext() const;
|
||||
const llvm::DataLayout &getDataLayout() const;
|
||||
const TargetInfo &getTarget() const;
|
||||
const CodeGenOptions &getCodeGenOpts() const;
|
||||
|
||||
/// Return the calling convention to use for system runtime
|
||||
/// functions.
|
||||
|
@ -30,38 +30,9 @@ void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
|
||||
}
|
||||
|
||||
bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
|
||||
// If RD has a non-trivial move or copy constructor, we cannot copy the
|
||||
// argument.
|
||||
if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialMoveConstructor())
|
||||
return false;
|
||||
|
||||
// If RD has a non-trivial destructor, we cannot copy the argument.
|
||||
if (RD->hasNonTrivialDestructor())
|
||||
return false;
|
||||
|
||||
// We can only copy the argument if there exists at least one trivial,
|
||||
// non-deleted copy or move constructor.
|
||||
// FIXME: This assumes that all lazily declared copy and move constructors are
|
||||
// not deleted. This assumption might not be true in some corner cases.
|
||||
bool CopyDeleted = false;
|
||||
bool MoveDeleted = false;
|
||||
for (const CXXConstructorDecl *CD : RD->ctors()) {
|
||||
if (CD->isCopyConstructor() || CD->isMoveConstructor()) {
|
||||
assert(CD->isTrivial());
|
||||
// We had at least one undeleted trivial copy or move ctor. Return
|
||||
// directly.
|
||||
if (!CD->isDeleted())
|
||||
return true;
|
||||
if (CD->isCopyConstructor())
|
||||
CopyDeleted = true;
|
||||
else
|
||||
MoveDeleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If all trivial copy and move constructors are deleted, we cannot copy the
|
||||
// argument.
|
||||
return !(CopyDeleted && MoveDeleted);
|
||||
return RD->canPassInRegisters();
|
||||
}
|
||||
|
||||
llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
|
||||
|
@ -3260,7 +3260,7 @@ void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
|
||||
llvm::DISubprogram *SP = nullptr;
|
||||
if (FI != SPCache.end())
|
||||
SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
|
||||
if (!SP)
|
||||
if (!SP || !SP->isDefinition())
|
||||
SP = getFunctionStub(GD);
|
||||
FnBeginRegionCount.push_back(LexicalBlockStack.size());
|
||||
LexicalBlockStack.emplace_back(SP);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "CodeGenPGO.h"
|
||||
#include "TargetInfo.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/ASTLambda.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
@ -983,11 +984,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
|
||||
}
|
||||
|
||||
// Check the 'this' pointer once per function, if it's available.
|
||||
if (CXXThisValue) {
|
||||
if (CXXABIThisValue) {
|
||||
SanitizerSet SkippedChecks;
|
||||
SkippedChecks.set(SanitizerKind::ObjectSize, true);
|
||||
QualType ThisTy = MD->getThisType(getContext());
|
||||
EmitTypeCheck(TCK_Load, Loc, CXXThisValue, ThisTy,
|
||||
|
||||
// If this is the call operator of a lambda with no capture-default, it
|
||||
// may have a static invoker function, which may call this operator with
|
||||
// a null 'this' pointer.
|
||||
if (isLambdaCallOperator(MD) &&
|
||||
cast<CXXRecordDecl>(MD->getParent())->getLambdaCaptureDefault() ==
|
||||
LCD_None)
|
||||
SkippedChecks.set(SanitizerKind::Null, true);
|
||||
|
||||
EmitTypeCheck(isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall
|
||||
: TCK_MemberCall,
|
||||
Loc, CXXABIThisValue, ThisTy,
|
||||
getContext().getTypeAlignInChars(ThisTy->getPointeeType()),
|
||||
SkippedChecks);
|
||||
}
|
||||
|
@ -44,6 +44,10 @@ CodeGenTypes::~CodeGenTypes() {
|
||||
delete &*I++;
|
||||
}
|
||||
|
||||
const CodeGenOptions &CodeGenTypes::getCodeGenOpts() const {
|
||||
return CGM.getCodeGenOpts();
|
||||
}
|
||||
|
||||
void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
|
||||
llvm::StructType *Ty,
|
||||
StringRef suffix) {
|
||||
|
@ -178,6 +178,7 @@ public:
|
||||
const TargetInfo &getTarget() const { return Target; }
|
||||
CGCXXABI &getCXXABI() const { return TheCXXABI; }
|
||||
llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }
|
||||
const CodeGenOptions &getCodeGenOpts() const;
|
||||
|
||||
/// ConvertType - Convert type T into a llvm::Type.
|
||||
llvm::Type *ConvertType(QualType T);
|
||||
|
@ -62,12 +62,20 @@ public:
|
||||
|
||||
bool classifyReturnType(CGFunctionInfo &FI) const override;
|
||||
|
||||
bool passClassIndirect(const CXXRecordDecl *RD) const {
|
||||
// Clang <= 4 used the pre-C++11 rule, which ignores move operations.
|
||||
// The PS4 platform ABI follows the behavior of Clang 3.2.
|
||||
if (CGM.getCodeGenOpts().getClangABICompat() <=
|
||||
CodeGenOptions::ClangABI::Ver4 ||
|
||||
CGM.getTriple().getOS() == llvm::Triple::PS4)
|
||||
return RD->hasNonTrivialDestructor() ||
|
||||
RD->hasNonTrivialCopyConstructor();
|
||||
return !canCopyArgument(RD);
|
||||
}
|
||||
|
||||
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
|
||||
// Structures with either a non-trivial destructor or a non-trivial
|
||||
// copy constructor are always indirect.
|
||||
// FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
|
||||
// special members.
|
||||
if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
|
||||
// If C++ prohibits us from making a copy, pass by address.
|
||||
if (passClassIndirect(RD))
|
||||
return RAA_Indirect;
|
||||
return RAA_Default;
|
||||
}
|
||||
@ -998,10 +1006,8 @@ bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
|
||||
if (!RD)
|
||||
return false;
|
||||
|
||||
// Return indirectly if we have a non-trivial copy ctor or non-trivial dtor.
|
||||
// FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
|
||||
// special members.
|
||||
if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) {
|
||||
// If C++ prohibits us from making a copy, return by address.
|
||||
if (passClassIndirect(RD)) {
|
||||
auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
|
||||
FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
|
||||
return true;
|
||||
|
@ -819,46 +819,44 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
|
||||
return RAA_Default;
|
||||
|
||||
case llvm::Triple::x86_64:
|
||||
// Win64 passes objects with non-trivial copy ctors indirectly.
|
||||
if (RD->hasNonTrivialCopyConstructor())
|
||||
return RAA_Indirect;
|
||||
|
||||
// If an object has a destructor, we'd really like to pass it indirectly
|
||||
// If a class has a destructor, we'd really like to pass it indirectly
|
||||
// because it allows us to elide copies. Unfortunately, MSVC makes that
|
||||
// impossible for small types, which it will pass in a single register or
|
||||
// stack slot. Most objects with dtors are large-ish, so handle that early.
|
||||
// We can't call out all large objects as being indirect because there are
|
||||
// multiple x64 calling conventions and the C++ ABI code shouldn't dictate
|
||||
// how we pass large POD types.
|
||||
//
|
||||
// Note: This permits small classes with nontrivial destructors to be
|
||||
// passed in registers, which is non-conforming.
|
||||
if (RD->hasNonTrivialDestructor() &&
|
||||
getContext().getTypeSize(RD->getTypeForDecl()) > 64)
|
||||
return RAA_Indirect;
|
||||
|
||||
// If this is true, the implicit copy constructor that Sema would have
|
||||
// created would not be deleted. FIXME: We should provide a more direct way
|
||||
// for CodeGen to ask whether the constructor was deleted.
|
||||
if (!RD->hasUserDeclaredCopyConstructor() &&
|
||||
!RD->hasUserDeclaredMoveConstructor() &&
|
||||
!RD->needsOverloadResolutionForMoveConstructor() &&
|
||||
!RD->hasUserDeclaredMoveAssignment() &&
|
||||
!RD->needsOverloadResolutionForMoveAssignment())
|
||||
return RAA_Default;
|
||||
|
||||
// Otherwise, Sema should have created an implicit copy constructor if
|
||||
// needed.
|
||||
assert(!RD->needsImplicitCopyConstructor());
|
||||
|
||||
// We have to make sure the trivial copy constructor isn't deleted.
|
||||
for (const CXXConstructorDecl *CD : RD->ctors()) {
|
||||
if (CD->isCopyConstructor()) {
|
||||
assert(CD->isTrivial());
|
||||
// We had at least one undeleted trivial copy ctor. Return directly.
|
||||
if (!CD->isDeleted())
|
||||
return RAA_Default;
|
||||
// If a class has at least one non-deleted, trivial copy constructor, it
|
||||
// is passed according to the C ABI. Otherwise, it is passed indirectly.
|
||||
//
|
||||
// Note: This permits classes with non-trivial copy or move ctors to be
|
||||
// passed in registers, so long as they *also* have a trivial copy ctor,
|
||||
// which is non-conforming.
|
||||
if (RD->needsImplicitCopyConstructor()) {
|
||||
// If the copy ctor has not yet been declared, we can read its triviality
|
||||
// off the AST.
|
||||
if (!RD->defaultedCopyConstructorIsDeleted() &&
|
||||
RD->hasTrivialCopyConstructor())
|
||||
return RAA_Default;
|
||||
} else {
|
||||
// Otherwise, we need to find the copy constructor(s) and ask.
|
||||
for (const CXXConstructorDecl *CD : RD->ctors()) {
|
||||
if (CD->isCopyConstructor()) {
|
||||
// We had at least one nondeleted trivial copy ctor. Return directly.
|
||||
if (!CD->isDeleted() && CD->isTrivial())
|
||||
return RAA_Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The trivial copy constructor was deleted. Return indirectly.
|
||||
// We have no trivial, non-deleted copy constructor.
|
||||
return RAA_Indirect;
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,11 @@ const TargetInfo &ABIInfo::getTarget() const {
|
||||
return CGT.getTarget();
|
||||
}
|
||||
|
||||
bool ABIInfo:: isAndroid() const { return getTarget().getTriple().isAndroid(); }
|
||||
const CodeGenOptions &ABIInfo::getCodeGenOpts() const {
|
||||
return CGT.getCodeGenOpts();
|
||||
}
|
||||
|
||||
bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }
|
||||
|
||||
bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
|
||||
return false;
|
||||
@ -2095,9 +2099,14 @@ class X86_64ABIInfo : public SwiftABIInfo {
|
||||
return !getTarget().getTriple().isOSDarwin();
|
||||
}
|
||||
|
||||
/// GCC classifies <1 x long long> as SSE but compatibility with older clang
|
||||
// compilers require us to classify it as INTEGER.
|
||||
/// GCC classifies <1 x long long> as SSE but some platform ABIs choose to
|
||||
/// classify it as INTEGER (for compatibility with older clang compilers).
|
||||
bool classifyIntegerMMXAsSSE() const {
|
||||
// Clang <= 3.8 did not do this.
|
||||
if (getCodeGenOpts().getClangABICompat() <=
|
||||
CodeGenOptions::ClangABI::Ver3_8)
|
||||
return false;
|
||||
|
||||
const llvm::Triple &Triple = getTarget().getTriple();
|
||||
if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::PS4)
|
||||
return false;
|
||||
|
@ -2855,6 +2855,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
|
||||
addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
|
||||
|
||||
if (auto *ABICompatArg = Args.getLastArg(options::OPT_fclang_abi_compat_EQ))
|
||||
ABICompatArg->render(Args, CmdArgs);
|
||||
|
||||
// Add runtime flag for PS4 when PGO or Coverage are enabled.
|
||||
if (getToolChain().getTriple().isPS4CPU())
|
||||
PS4cpu::addProfileRTArgs(getToolChain(), Args, CmdArgs);
|
||||
|
@ -1837,7 +1837,12 @@ Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
|
||||
}
|
||||
|
||||
bool MachO::IsUnwindTablesDefault(const ArgList &Args) const {
|
||||
return !UseSjLjExceptions(Args);
|
||||
// Unwind tables are not emitted if -fno-exceptions is supplied (except when
|
||||
// targeting x86_64).
|
||||
return getArch() == llvm::Triple::x86_64 ||
|
||||
(!UseSjLjExceptions(Args) &&
|
||||
Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
|
||||
true));
|
||||
}
|
||||
|
||||
bool MachO::UseDwarfDebugFlags() const {
|
||||
|
@ -76,7 +76,7 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName,
|
||||
|
||||
// Check various environment variables to try and find a toolchain.
|
||||
static bool findVCToolChainViaEnvironment(std::string &Path,
|
||||
bool &IsVS2017OrNewer) {
|
||||
MSVCToolChain::ToolsetLayout &VSLayout) {
|
||||
// These variables are typically set by vcvarsall.bat
|
||||
// when launching a developer command prompt.
|
||||
if (llvm::Optional<std::string> VCToolsInstallDir =
|
||||
@ -84,7 +84,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
|
||||
// This is only set by newer Visual Studios, and it leads straight to
|
||||
// the toolchain directory.
|
||||
Path = std::move(*VCToolsInstallDir);
|
||||
IsVS2017OrNewer = true;
|
||||
VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
|
||||
return true;
|
||||
}
|
||||
if (llvm::Optional<std::string> VCInstallDir =
|
||||
@ -94,7 +94,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
|
||||
// so this check has to appear second.
|
||||
// In older Visual Studios, the VC directory is the toolchain.
|
||||
Path = std::move(*VCInstallDir);
|
||||
IsVS2017OrNewer = false;
|
||||
VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -134,9 +134,16 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
|
||||
}
|
||||
if (IsBin) {
|
||||
llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
|
||||
if (llvm::sys::path::filename(ParentPath) == "VC") {
|
||||
llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
|
||||
if (ParentFilename == "VC") {
|
||||
Path = ParentPath;
|
||||
IsVS2017OrNewer = false;
|
||||
VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
|
||||
return true;
|
||||
}
|
||||
if (ParentFilename == "x86ret" || ParentFilename == "x86chk"
|
||||
|| ParentFilename == "amd64ret" || ParentFilename == "amd64chk") {
|
||||
Path = ParentPath;
|
||||
VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -165,7 +172,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
|
||||
ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
|
||||
|
||||
Path = ToolChainPath;
|
||||
IsVS2017OrNewer = true;
|
||||
VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -181,7 +188,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
|
||||
// This is the preferred way to discover new Visual Studios, as they're no
|
||||
// longer listed in the registry.
|
||||
static bool findVCToolChainViaSetupConfig(std::string &Path,
|
||||
bool &IsVS2017OrNewer) {
|
||||
MSVCToolChain::ToolsetLayout &VSLayout) {
|
||||
#if !defined(USE_MSVC_SETUP_API)
|
||||
return false;
|
||||
#else
|
||||
@ -263,7 +270,7 @@ static bool findVCToolChainViaSetupConfig(std::string &Path,
|
||||
return false;
|
||||
|
||||
Path = ToolchainPath.str();
|
||||
IsVS2017OrNewer = true;
|
||||
VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
@ -272,7 +279,7 @@ static bool findVCToolChainViaSetupConfig(std::string &Path,
|
||||
// a toolchain path. VS2017 and newer don't get added to the registry.
|
||||
// So if we find something here, we know that it's an older version.
|
||||
static bool findVCToolChainViaRegistry(std::string &Path,
|
||||
bool &IsVS2017OrNewer) {
|
||||
MSVCToolChain::ToolsetLayout &VSLayout) {
|
||||
std::string VSInstallPath;
|
||||
if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
|
||||
"InstallDir", VSInstallPath, nullptr) ||
|
||||
@ -284,7 +291,7 @@ static bool findVCToolChainViaRegistry(std::string &Path,
|
||||
llvm::sys::path::append(VCPath, "VC");
|
||||
|
||||
Path = VCPath.str();
|
||||
IsVS2017OrNewer = false;
|
||||
VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -475,6 +482,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
// native target bin directory.
|
||||
// e.g. when compiling for x86 on an x64 host, PATH should start with:
|
||||
// /bin/HostX64/x86;/bin/HostX64/x64
|
||||
// This doesn't attempt to handle ToolsetLayout::DevDivInternal.
|
||||
if (TC.getIsVS2017OrNewer() &&
|
||||
llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
|
||||
auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
|
||||
@ -677,9 +685,9 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
|
||||
// what they want to use.
|
||||
// Failing that, just try to find the newest Visual Studio version we can
|
||||
// and use its default VC toolchain.
|
||||
findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) ||
|
||||
findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) ||
|
||||
findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer);
|
||||
findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) ||
|
||||
findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) ||
|
||||
findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
|
||||
}
|
||||
|
||||
Tool *MSVCToolChain::buildLinker() const {
|
||||
@ -766,6 +774,21 @@ static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
|
||||
}
|
||||
}
|
||||
|
||||
// Similar to the above function, but for DevDiv internal builds.
|
||||
static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
|
||||
using ArchType = llvm::Triple::ArchType;
|
||||
switch (Arch) {
|
||||
case ArchType::x86:
|
||||
return "i386";
|
||||
case ArchType::x86_64:
|
||||
return "amd64";
|
||||
case ArchType::arm:
|
||||
return "arm";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// Get the path to a specific subdirectory in the current toolchain for
|
||||
// a given target architecture.
|
||||
// VS2017 changed the VC toolchain layout, so this should be used instead
|
||||
@ -773,26 +796,40 @@ static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
|
||||
std::string
|
||||
MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
|
||||
llvm::Triple::ArchType TargetArch) const {
|
||||
const char *SubdirName;
|
||||
const char *IncludeName;
|
||||
switch (VSLayout) {
|
||||
case ToolsetLayout::OlderVS:
|
||||
SubdirName = llvmArchToLegacyVCArch(TargetArch);
|
||||
IncludeName = "include";
|
||||
break;
|
||||
case ToolsetLayout::VS2017OrNewer:
|
||||
SubdirName = llvmArchToWindowsSDKArch(TargetArch);
|
||||
IncludeName = "include";
|
||||
break;
|
||||
case ToolsetLayout::DevDivInternal:
|
||||
SubdirName = llvmArchToDevDivInternalArch(TargetArch);
|
||||
IncludeName = "inc";
|
||||
break;
|
||||
}
|
||||
|
||||
llvm::SmallString<256> Path(VCToolChainPath);
|
||||
switch (Type) {
|
||||
case SubDirectoryType::Bin:
|
||||
if (IsVS2017OrNewer) {
|
||||
bool HostIsX64 =
|
||||
if (VSLayout == ToolsetLayout::VS2017OrNewer) {
|
||||
const bool HostIsX64 =
|
||||
llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
|
||||
llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"),
|
||||
llvmArchToWindowsSDKArch(TargetArch));
|
||||
|
||||
} else {
|
||||
llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch));
|
||||
const char *const HostName = HostIsX64 ? "HostX64" : "HostX86";
|
||||
llvm::sys::path::append(Path, "bin", HostName, SubdirName);
|
||||
} else { // OlderVS or DevDivInternal
|
||||
llvm::sys::path::append(Path, "bin", SubdirName);
|
||||
}
|
||||
break;
|
||||
case SubDirectoryType::Include:
|
||||
llvm::sys::path::append(Path, "include");
|
||||
llvm::sys::path::append(Path, IncludeName);
|
||||
break;
|
||||
case SubDirectoryType::Lib:
|
||||
llvm::sys::path::append(
|
||||
Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch)
|
||||
: llvmArchToLegacyVCArch(TargetArch));
|
||||
llvm::sys::path::append(Path, "lib", SubdirName);
|
||||
break;
|
||||
}
|
||||
return Path.str();
|
||||
|
@ -92,7 +92,12 @@ public:
|
||||
return getSubDirectoryPath(Type, getArch());
|
||||
}
|
||||
|
||||
bool getIsVS2017OrNewer() const { return IsVS2017OrNewer; }
|
||||
enum class ToolsetLayout {
|
||||
OlderVS,
|
||||
VS2017OrNewer,
|
||||
DevDivInternal,
|
||||
};
|
||||
bool getIsVS2017OrNewer() const { return VSLayout == ToolsetLayout::VS2017OrNewer; }
|
||||
|
||||
void
|
||||
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
|
||||
@ -130,7 +135,7 @@ protected:
|
||||
Tool *buildAssembler() const override;
|
||||
private:
|
||||
std::string VCToolChainPath;
|
||||
bool IsVS2017OrNewer = false;
|
||||
ToolsetLayout VSLayout = ToolsetLayout::OlderVS;
|
||||
CudaInstallationDetector CudaInstallation;
|
||||
};
|
||||
|
||||
|
@ -246,12 +246,12 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
|
||||
|
||||
for (unsigned i = Start; i != End; ++i) {
|
||||
if (ScopeStack.size() != 0 &&
|
||||
Changes[i].nestingAndIndentLevel() <
|
||||
Changes[ScopeStack.back()].nestingAndIndentLevel())
|
||||
Changes[i].indentAndNestingLevel() <
|
||||
Changes[ScopeStack.back()].indentAndNestingLevel())
|
||||
ScopeStack.pop_back();
|
||||
|
||||
if (i != Start && Changes[i].nestingAndIndentLevel() >
|
||||
Changes[i - 1].nestingAndIndentLevel())
|
||||
if (i != Start && Changes[i].indentAndNestingLevel() >
|
||||
Changes[i - 1].indentAndNestingLevel())
|
||||
ScopeStack.push_back(i);
|
||||
|
||||
bool InsideNestedScope = ScopeStack.size() != 0;
|
||||
@ -327,8 +327,8 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
|
||||
|
||||
// Measure the scope level (i.e. depth of (), [], {}) of the first token, and
|
||||
// abort when we hit any token in a higher scope than the starting one.
|
||||
auto NestingAndIndentLevel = StartAt < Changes.size()
|
||||
? Changes[StartAt].nestingAndIndentLevel()
|
||||
auto IndentAndNestingLevel = StartAt < Changes.size()
|
||||
? Changes[StartAt].indentAndNestingLevel()
|
||||
: std::pair<unsigned, unsigned>(0, 0);
|
||||
|
||||
// Keep track of the number of commas before the matching tokens, we will only
|
||||
@ -359,7 +359,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
|
||||
|
||||
unsigned i = StartAt;
|
||||
for (unsigned e = Changes.size(); i != e; ++i) {
|
||||
if (Changes[i].nestingAndIndentLevel() < NestingAndIndentLevel)
|
||||
if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
|
||||
break;
|
||||
|
||||
if (Changes[i].NewlinesBefore != 0) {
|
||||
@ -375,7 +375,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
|
||||
|
||||
if (Changes[i].Tok->is(tok::comma)) {
|
||||
++CommasBeforeMatch;
|
||||
} else if (Changes[i].nestingAndIndentLevel() > NestingAndIndentLevel) {
|
||||
} else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
|
||||
// Call AlignTokens recursively, skipping over this scope block.
|
||||
unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
|
||||
i = StoppedAt - 1;
|
||||
@ -472,9 +472,14 @@ void WhitespaceManager::alignTrailingComments() {
|
||||
continue;
|
||||
|
||||
unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
|
||||
unsigned ChangeMaxColumn = Style.ColumnLimit >= Changes[i].TokenLength
|
||||
? Style.ColumnLimit - Changes[i].TokenLength
|
||||
: ChangeMinColumn;
|
||||
unsigned ChangeMaxColumn;
|
||||
|
||||
if (Style.ColumnLimit == 0)
|
||||
ChangeMaxColumn = UINT_MAX;
|
||||
else if (Style.ColumnLimit >= Changes[i].TokenLength)
|
||||
ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
|
||||
else
|
||||
ChangeMaxColumn = ChangeMinColumn;
|
||||
|
||||
// If we don't create a replacement for this change, we have to consider
|
||||
// it to be immovable.
|
||||
|
@ -154,12 +154,11 @@ public:
|
||||
const Change *StartOfBlockComment;
|
||||
int IndentationOffset;
|
||||
|
||||
// A combination of nesting level and indent level, which are used in
|
||||
// A combination of indent level and nesting level, which are used in
|
||||
// tandem to compute lexical scope, for the purposes of deciding
|
||||
// when to stop consecutive alignment runs.
|
||||
std::pair<unsigned, unsigned>
|
||||
nestingAndIndentLevel() const {
|
||||
return std::make_pair(Tok->NestingLevel, Tok->IndentLevel);
|
||||
std::pair<unsigned, unsigned> indentAndNestingLevel() const {
|
||||
return std::make_pair(Tok->IndentLevel, Tok->NestingLevel);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -573,6 +573,33 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
|
||||
if (!Opts.ProfileInstrumentUsePath.empty())
|
||||
setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
|
||||
|
||||
if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
|
||||
Opts.setClangABICompat(CodeGenOptions::ClangABI::Latest);
|
||||
|
||||
StringRef Ver = A->getValue();
|
||||
std::pair<StringRef, StringRef> VerParts = Ver.split('.');
|
||||
unsigned Major, Minor = 0;
|
||||
|
||||
// Check the version number is valid: either 3.x (0 <= x <= 9) or
|
||||
// y or y.0 (4 <= y <= current version).
|
||||
if (!VerParts.first.startswith("0") &&
|
||||
!VerParts.first.getAsInteger(10, Major) &&
|
||||
3 <= Major && Major <= CLANG_VERSION_MAJOR &&
|
||||
(Major == 3 ? VerParts.second.size() == 1 &&
|
||||
!VerParts.second.getAsInteger(10, Minor)
|
||||
: VerParts.first.size() == Ver.size() ||
|
||||
VerParts.second == "0")) {
|
||||
// Got a valid version number.
|
||||
if (Major == 3 && Minor <= 8)
|
||||
Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver3_8);
|
||||
else if (Major <= 4)
|
||||
Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver4);
|
||||
} else if (Ver != "latest") {
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getAsString(Args) << A->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
Opts.CoverageMapping =
|
||||
Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
|
||||
Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
|
||||
|
@ -76,13 +76,7 @@ typedef intptr_t _sleb128_t;
|
||||
typedef uintptr_t _uleb128_t;
|
||||
|
||||
struct _Unwind_Context;
|
||||
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
|
||||
struct _Unwind_Control_Block;
|
||||
typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
|
||||
#else
|
||||
struct _Unwind_Exception;
|
||||
typedef struct _Unwind_Exception _Unwind_Exception;
|
||||
#endif
|
||||
typedef enum {
|
||||
_URC_NO_REASON = 0,
|
||||
#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
|
||||
@ -115,42 +109,8 @@ typedef enum {
|
||||
} _Unwind_Action;
|
||||
|
||||
typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
|
||||
_Unwind_Exception *);
|
||||
struct _Unwind_Exception *);
|
||||
|
||||
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
|
||||
typedef struct _Unwind_Control_Block _Unwind_Control_Block;
|
||||
typedef uint32_t _Unwind_EHT_Header;
|
||||
|
||||
struct _Unwind_Control_Block {
|
||||
uint64_t exception_class;
|
||||
void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *);
|
||||
/* unwinder cache (private fields for the unwinder's use) */
|
||||
struct {
|
||||
uint32_t reserved1; /* forced unwind stop function, 0 if not forced */
|
||||
uint32_t reserved2; /* personality routine */
|
||||
uint32_t reserved3; /* callsite */
|
||||
uint32_t reserved4; /* forced unwind stop argument */
|
||||
uint32_t reserved5;
|
||||
} unwinder_cache;
|
||||
/* propagation barrier cache (valid after phase 1) */
|
||||
struct {
|
||||
uint32_t sp;
|
||||
uint32_t bitpattern[5];
|
||||
} barrier_cache;
|
||||
/* cleanup cache (preserved over cleanup) */
|
||||
struct {
|
||||
uint32_t bitpattern[4];
|
||||
} cleanup_cache;
|
||||
/* personality cache (for personality's benefit) */
|
||||
struct {
|
||||
uint32_t fnstart; /* function start address */
|
||||
_Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */
|
||||
uint32_t additional; /* additional data */
|
||||
uint32_t reserved1;
|
||||
} pr_cache;
|
||||
long long int : 0; /* force alignment of next item to 8-byte boundary */
|
||||
};
|
||||
#else
|
||||
struct _Unwind_Exception {
|
||||
_Unwind_Exception_Class exception_class;
|
||||
_Unwind_Exception_Cleanup_Fn exception_cleanup;
|
||||
@ -160,24 +120,23 @@ struct _Unwind_Exception {
|
||||
* aligned". GCC has interpreted this to mean "use the maximum useful
|
||||
* alignment for the target"; so do we. */
|
||||
} __attribute__((__aligned__));
|
||||
#endif
|
||||
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action,
|
||||
_Unwind_Exception_Class,
|
||||
_Unwind_Exception *,
|
||||
struct _Unwind_Exception *,
|
||||
struct _Unwind_Context *,
|
||||
void *);
|
||||
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(int, _Unwind_Action,
|
||||
_Unwind_Exception_Class,
|
||||
_Unwind_Exception *,
|
||||
struct _Unwind_Context *);
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(
|
||||
int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
|
||||
struct _Unwind_Context *);
|
||||
typedef _Unwind_Personality_Fn __personality_routine;
|
||||
|
||||
typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
|
||||
void *);
|
||||
|
||||
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
|
||||
#if defined(__arm__) && !defined(__APPLE__)
|
||||
|
||||
typedef enum {
|
||||
_UVRSC_CORE = 0, /* integer register */
|
||||
_UVRSC_VFP = 1, /* vfp */
|
||||
@ -199,12 +158,14 @@ typedef enum {
|
||||
_UVRSR_FAILED = 2
|
||||
} _Unwind_VRS_Result;
|
||||
|
||||
#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__ARM_DWARF_EH__)
|
||||
typedef uint32_t _Unwind_State;
|
||||
#define _US_VIRTUAL_UNWIND_FRAME ((_Unwind_State)0)
|
||||
#define _US_UNWIND_FRAME_STARTING ((_Unwind_State)1)
|
||||
#define _US_UNWIND_FRAME_RESUME ((_Unwind_State)2)
|
||||
#define _US_ACTION_MASK ((_Unwind_State)3)
|
||||
#define _US_FORCE_UNWIND ((_Unwind_State)8)
|
||||
#endif
|
||||
|
||||
_Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context,
|
||||
_Unwind_VRS_RegClass __regclass,
|
||||
@ -263,12 +224,13 @@ _Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *);
|
||||
|
||||
/* DWARF EH functions; currently not available on Darwin/ARM */
|
||||
#if !defined(__APPLE__) || !defined(__arm__)
|
||||
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Exception *, _Unwind_Stop_Fn,
|
||||
void *);
|
||||
void _Unwind_DeleteException(_Unwind_Exception *);
|
||||
void _Unwind_Resume(_Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception *);
|
||||
|
||||
_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *,
|
||||
_Unwind_Stop_Fn, void *);
|
||||
void _Unwind_DeleteException(struct _Unwind_Exception *);
|
||||
void _Unwind_Resume(struct _Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *);
|
||||
|
||||
#endif
|
||||
|
||||
@ -279,11 +241,11 @@ typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t;
|
||||
|
||||
void _Unwind_SjLj_Register(_Unwind_FunctionContext_t);
|
||||
void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t);
|
||||
_Unwind_Reason_Code _Unwind_SjLj_RaiseException(_Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *,
|
||||
_Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *,
|
||||
_Unwind_Stop_Fn, void *);
|
||||
void _Unwind_SjLj_Resume(_Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *);
|
||||
void _Unwind_SjLj_Resume(struct _Unwind_Exception *);
|
||||
_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *);
|
||||
|
||||
void *_Unwind_FindEnclosingFunction(void *);
|
||||
|
||||
|
@ -458,10 +458,16 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
|
||||
SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs);
|
||||
}
|
||||
|
||||
bool ExitedFromPredefinesFile = false;
|
||||
FileID ExitedFID;
|
||||
if (Callbacks && !isEndOfMacro && CurPPLexer)
|
||||
if (!isEndOfMacro && CurPPLexer) {
|
||||
ExitedFID = CurPPLexer->getFileID();
|
||||
|
||||
assert(PredefinesFileID.isValid() &&
|
||||
"HandleEndOfFile is called before PredefinesFileId is set");
|
||||
ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID);
|
||||
}
|
||||
|
||||
if (LeavingSubmodule) {
|
||||
// We're done with this submodule.
|
||||
Module *M = LeaveSubmodule(/*ForPragma*/false);
|
||||
@ -489,6 +495,11 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
|
||||
PPCallbacks::ExitFile, FileType, ExitedFID);
|
||||
}
|
||||
|
||||
// Restore conditional stack from the preamble right after exiting from the
|
||||
// predefines file.
|
||||
if (ExitedFromPredefinesFile)
|
||||
replayPreambleConditionalStack();
|
||||
|
||||
// Client should lex another token unless we generated an EOM.
|
||||
return LeavingSubmodule;
|
||||
}
|
||||
|
@ -540,6 +540,8 @@ void Preprocessor::EnterMainSourceFile() {
|
||||
void Preprocessor::replayPreambleConditionalStack() {
|
||||
// Restore the conditional stack from the preamble, if there is one.
|
||||
if (PreambleConditionalStack.isReplaying()) {
|
||||
assert(CurPPLexer &&
|
||||
"CurPPLexer is null when calling replayPreambleConditionalStack.");
|
||||
CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack());
|
||||
PreambleConditionalStack.doneReplaying();
|
||||
}
|
||||
|
@ -516,8 +516,6 @@ void Parser::Initialize() {
|
||||
|
||||
// Prime the lexer look-ahead.
|
||||
ConsumeToken();
|
||||
|
||||
PP.replayPreambleConditionalStack();
|
||||
}
|
||||
|
||||
void Parser::LateTemplateParserCleanupCallback(void *P) {
|
||||
|
@ -5726,6 +5726,53 @@ static void DefineImplicitSpecialMember(Sema &S, CXXMethodDecl *MD,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine whether a type is permitted to be passed or returned in
|
||||
/// registers, per C++ [class.temporary]p3.
|
||||
static bool computeCanPassInRegisters(Sema &S, CXXRecordDecl *D) {
|
||||
if (D->isDependentType() || D->isInvalidDecl())
|
||||
return false;
|
||||
|
||||
// Per C++ [class.temporary]p3, the relevant condition is:
|
||||
// each copy constructor, move constructor, and destructor of X is
|
||||
// either trivial or deleted, and X has at least one non-deleted copy
|
||||
// or move constructor
|
||||
bool HasNonDeletedCopyOrMove = false;
|
||||
|
||||
if (D->needsImplicitCopyConstructor() &&
|
||||
!D->defaultedCopyConstructorIsDeleted()) {
|
||||
if (!D->hasTrivialCopyConstructor())
|
||||
return false;
|
||||
HasNonDeletedCopyOrMove = true;
|
||||
}
|
||||
|
||||
if (S.getLangOpts().CPlusPlus11 && D->needsImplicitMoveConstructor() &&
|
||||
!D->defaultedMoveConstructorIsDeleted()) {
|
||||
if (!D->hasTrivialMoveConstructor())
|
||||
return false;
|
||||
HasNonDeletedCopyOrMove = true;
|
||||
}
|
||||
|
||||
if (D->needsImplicitDestructor() && !D->defaultedDestructorIsDeleted() &&
|
||||
!D->hasTrivialDestructor())
|
||||
return false;
|
||||
|
||||
for (const CXXMethodDecl *MD : D->methods()) {
|
||||
if (MD->isDeleted())
|
||||
continue;
|
||||
|
||||
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
|
||||
if (CD && CD->isCopyOrMoveConstructor())
|
||||
HasNonDeletedCopyOrMove = true;
|
||||
else if (!isa<CXXDestructorDecl>(MD))
|
||||
continue;
|
||||
|
||||
if (!MD->isTrivial())
|
||||
return false;
|
||||
}
|
||||
|
||||
return HasNonDeletedCopyOrMove;
|
||||
}
|
||||
|
||||
/// \brief Perform semantic checks on a class definition that has been
|
||||
/// completing, introducing implicitly-declared members, checking for
|
||||
/// abstract types, etc.
|
||||
@ -5870,6 +5917,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
|
||||
}
|
||||
|
||||
checkClassLevelDLLAttribute(Record);
|
||||
|
||||
Record->setCanPassInRegisters(computeCanPassInRegisters(*this, Record));
|
||||
}
|
||||
|
||||
/// Look up the special member function that would be called by a special
|
||||
@ -7496,8 +7545,7 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
|
||||
reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
|
||||
FieldCollector->getCurNumFields()), LBrac, RBrac, AttrList);
|
||||
|
||||
CheckCompletedCXXClass(
|
||||
dyn_cast_or_null<CXXRecordDecl>(TagDecl));
|
||||
CheckCompletedCXXClass(dyn_cast_or_null<CXXRecordDecl>(TagDecl));
|
||||
}
|
||||
|
||||
/// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared
|
||||
@ -11929,8 +11977,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
|
||||
Scope *S = getScopeForContext(ClassDecl);
|
||||
CheckImplicitSpecialMemberDeclaration(S, CopyConstructor);
|
||||
|
||||
if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor))
|
||||
if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) {
|
||||
ClassDecl->setImplicitCopyConstructorIsDeleted();
|
||||
SetDeclDeleted(CopyConstructor, ClassLoc);
|
||||
}
|
||||
|
||||
if (S)
|
||||
PushOnScopeChains(CopyConstructor, S, false);
|
||||
|
@ -872,7 +872,7 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
|
||||
}
|
||||
|
||||
QualType RHSType = S.Context.getCanonicalType(Property->getType());
|
||||
unsigned OriginalAttributes = Property->getPropertyAttributes();
|
||||
unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
|
||||
enum MismatchKind {
|
||||
IncompatibleType = 0,
|
||||
HasNoExpectedAttribute,
|
||||
@ -890,7 +890,7 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
|
||||
SmallVector<MismatchingProperty, 4> Mismatches;
|
||||
for (ObjCPropertyDecl *Prop : Properties) {
|
||||
// Verify the property attributes.
|
||||
unsigned Attr = Prop->getPropertyAttributes();
|
||||
unsigned Attr = Prop->getPropertyAttributesAsWritten();
|
||||
if (Attr != OriginalAttributes) {
|
||||
auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
|
||||
MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
|
||||
|
@ -1559,9 +1559,11 @@ void ASTDeclReader::ReadCXXDefinitionData(
|
||||
Data.HasUninitializedFields = Record.readInt();
|
||||
Data.HasInheritedConstructor = Record.readInt();
|
||||
Data.HasInheritedAssignment = Record.readInt();
|
||||
Data.NeedOverloadResolutionForCopyConstructor = Record.readInt();
|
||||
Data.NeedOverloadResolutionForMoveConstructor = Record.readInt();
|
||||
Data.NeedOverloadResolutionForMoveAssignment = Record.readInt();
|
||||
Data.NeedOverloadResolutionForDestructor = Record.readInt();
|
||||
Data.DefaultedCopyConstructorIsDeleted = Record.readInt();
|
||||
Data.DefaultedMoveConstructorIsDeleted = Record.readInt();
|
||||
Data.DefaultedMoveAssignmentIsDeleted = Record.readInt();
|
||||
Data.DefaultedDestructorIsDeleted = Record.readInt();
|
||||
@ -1570,6 +1572,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
|
||||
Data.HasIrrelevantDestructor = Record.readInt();
|
||||
Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
|
||||
Data.HasDefaultedDefaultConstructor = Record.readInt();
|
||||
Data.CanPassInRegisters = Record.readInt();
|
||||
Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
|
||||
Data.HasConstexprDefaultConstructor = Record.readInt();
|
||||
Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
|
||||
@ -1697,9 +1700,11 @@ void ASTDeclReader::MergeDefinitionData(
|
||||
MATCH_FIELD(HasUninitializedFields)
|
||||
MATCH_FIELD(HasInheritedConstructor)
|
||||
MATCH_FIELD(HasInheritedAssignment)
|
||||
MATCH_FIELD(NeedOverloadResolutionForCopyConstructor)
|
||||
MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
|
||||
MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
|
||||
MATCH_FIELD(NeedOverloadResolutionForDestructor)
|
||||
MATCH_FIELD(DefaultedCopyConstructorIsDeleted)
|
||||
MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
|
||||
MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
|
||||
MATCH_FIELD(DefaultedDestructorIsDeleted)
|
||||
@ -1708,6 +1713,7 @@ void ASTDeclReader::MergeDefinitionData(
|
||||
MATCH_FIELD(HasIrrelevantDestructor)
|
||||
OR_FIELD(HasConstexprNonCopyMoveConstructor)
|
||||
OR_FIELD(HasDefaultedDefaultConstructor)
|
||||
MATCH_FIELD(CanPassInRegisters)
|
||||
MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
|
||||
OR_FIELD(HasConstexprDefaultConstructor)
|
||||
MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user