IFC @r271694

This commit is contained in:
Neel Natu 2014-09-17 18:46:51 +00:00
commit 4e27d36d38
1875 changed files with 137621 additions and 52394 deletions

View File

@ -1,5 +1,5 @@
{
"project.name": "S",
"phabricator.uri" : "https://phabric.freebsd.org/",
"phabricator.uri" : "https://reviews.freebsd.org/",
"history.immutable" : true
}

View File

@ -37,6 +37,8 @@
# xdev-build - Build cross-development tools.
# xdev-install - Install cross-development tools.
# xdev-links - Create traditional links in /usr/bin for cc, etc
# native-xtools - Create host binaries that produce target objects
# for use in qemu user-mode jails.
#
# "quick" way to test all kernel builds:
# _jflag=`sysctl -n hw.ncpu`
@ -111,7 +113,7 @@ TGTS= all all-man buildenv buildenvvars buildkernel buildworld \
_worldtmp _legacy _bootstrap-tools _cleanobj _obj \
_build-tools _cross-tools _includes _libraries _depend \
build32 builddtb distribute32 install32 xdev xdev-build xdev-install \
xdev-links \
xdev-links native-xtools \
TGTS+= ${SUBDIR_TARGETS}

View File

@ -246,7 +246,7 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \
${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= MK_PIE=no \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \
@ -258,7 +258,7 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= MK_PIE=no \
SSP_CFLAGS= \
-DNO_LINT \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no MK_CLANG_FULL=no MK_LLDB=no MK_TESTS=no
@ -276,7 +276,7 @@ KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \
${KTMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= MK_PIE=no \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no
@ -1239,11 +1239,11 @@ _lex= usr.bin/lex
_awk= usr.bin/awk
.endif
.if ${MK_BSNMP} != "no" && !exists(/usr/sbin/gensnmptree)
.if ${MK_BSNMP} != "no"
_gensnmptree= usr.sbin/bsnmpd/gensnmptree
.endif
# We need to build tlbgen when we're building clang either as
# We need to build tblgen when we're building clang either as
# the bootstrap compiler, or as the part of the normal build.
.if ${MK_CLANG_BOOTSTRAP} != "no" || ${MK_CLANG} != "no"
_clang_tblgen= \
@ -1418,6 +1418,48 @@ cross-tools: .MAKE
${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX} install
.endfor
NXBENV= MAKEOBJDIRPREFIX=${OBJTREE}/nxb \
INSTALL="sh ${.CURDIR}/tools/install.sh" \
VERSION="${VERSION}"
NXBMAKE= ${NXBENV} ${MAKE} \
TBLGEN=${OBJTREE}/nxb-bin/usr/bin/tblgen \
CLANG_TBLGEN=${OBJTREE}/nxb-bin/usr/bin/clang-tblgen \
MACHINE=${TARGET} MACHINE_ARCH=${TARGET_ARCH} \
MK_GDB=no MK_TESTS=no \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \
MK_CLANG_FULL=no MK_LLDB=no
native-xtools: .MAKE
mkdir -p ${OBJTREE}/nxb-bin/usr
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \
-p ${OBJTREE}/nxb-bin/usr >/dev/null
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \
-p ${OBJTREE}/nxb-bin/usr/include >/dev/null
.for _tool in \
${_clang_tblgen} \
usr.bin/ar \
${_binutils} \
${_cc} \
${_gcc_tools} \
${_clang_libs} \
${_clang} \
usr.bin/awk \
usr.bin/bmake \
usr.bin/lex \
usr.bin/lorder \
usr.bin/sed \
usr.bin/yacc
${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \
cd ${.CURDIR}/${_tool} && \
${NXBMAKE} DIRPRFX=${_tool}/ obj && \
${NXBMAKE} DIRPRFX=${_tool}/ depend && \
${NXBMAKE} DIRPRFX=${_tool}/ all && \
${NXBMAKE} DIRPRFX=${_tool}/ DESTDIR=${OBJTREE}/nxb-bin install
.endfor
#
# hierarchy - ensure that all the needed directories are present
#

View File

@ -3205,6 +3205,202 @@ OLD_FILES+=lib/geom/geom_concat.so.1
OLD_FILES+=lib/geom/geom_label.so.1
OLD_FILES+=lib/geom/geom_nop.so.1
OLD_FILES+=lib/geom/geom_stripe.so.1
# 20040728: GCC 3.4.2
OLD_DIRS+=usr/include/c++/3.3
OLD_FILES+=usr/include/c++/3.3/FlexLexer.h
OLD_FILES+=usr/include/c++/3.3/algorithm
OLD_FILES+=usr/include/c++/3.3/backward/algo.h
OLD_FILES+=usr/include/c++/3.3/backward/algobase.h
OLD_FILES+=usr/include/c++/3.3/backward/alloc.h
OLD_FILES+=usr/include/c++/3.3/backward/backward_warning.h
OLD_FILES+=usr/include/c++/3.3/backward/bvector.h
OLD_FILES+=usr/include/c++/3.3/backward/complex.h
OLD_FILES+=usr/include/c++/3.3/backward/defalloc.h
OLD_FILES+=usr/include/c++/3.3/backward/deque.h
OLD_FILES+=usr/include/c++/3.3/backward/fstream.h
OLD_FILES+=usr/include/c++/3.3/backward/function.h
OLD_FILES+=usr/include/c++/3.3/backward/hash_map.h
OLD_FILES+=usr/include/c++/3.3/backward/hash_set.h
OLD_FILES+=usr/include/c++/3.3/backward/hashtable.h
OLD_FILES+=usr/include/c++/3.3/backward/heap.h
OLD_FILES+=usr/include/c++/3.3/backward/iomanip.h
OLD_FILES+=usr/include/c++/3.3/backward/iostream.h
OLD_FILES+=usr/include/c++/3.3/backward/istream.h
OLD_FILES+=usr/include/c++/3.3/backward/iterator.h
OLD_FILES+=usr/include/c++/3.3/backward/list.h
OLD_FILES+=usr/include/c++/3.3/backward/map.h
OLD_FILES+=usr/include/c++/3.3/backward/multimap.h
OLD_FILES+=usr/include/c++/3.3/backward/multiset.h
OLD_FILES+=usr/include/c++/3.3/backward/new.h
OLD_FILES+=usr/include/c++/3.3/backward/ostream.h
OLD_FILES+=usr/include/c++/3.3/backward/pair.h
OLD_FILES+=usr/include/c++/3.3/backward/queue.h
OLD_FILES+=usr/include/c++/3.3/backward/rope.h
OLD_FILES+=usr/include/c++/3.3/backward/set.h
OLD_FILES+=usr/include/c++/3.3/backward/slist.h
OLD_FILES+=usr/include/c++/3.3/backward/stack.h
OLD_FILES+=usr/include/c++/3.3/backward/stream.h
OLD_FILES+=usr/include/c++/3.3/backward/streambuf.h
OLD_FILES+=usr/include/c++/3.3/backward/strstream
OLD_FILES+=usr/include/c++/3.3/backward/strstream.h
OLD_FILES+=usr/include/c++/3.3/backward/tempbuf.h
OLD_FILES+=usr/include/c++/3.3/backward/tree.h
OLD_FILES+=usr/include/c++/3.3/backward/vector.h
OLD_DIRS+=usr/include/c++/3.3/backward
OLD_FILES+=usr/include/c++/3.3/bits/atomicity.h
OLD_FILES+=usr/include/c++/3.3/bits/basic_file.h
OLD_FILES+=usr/include/c++/3.3/bits/basic_ios.h
OLD_FILES+=usr/include/c++/3.3/bits/basic_ios.tcc
OLD_FILES+=usr/include/c++/3.3/bits/basic_string.h
OLD_FILES+=usr/include/c++/3.3/bits/basic_string.tcc
OLD_FILES+=usr/include/c++/3.3/bits/boost_concept_check.h
OLD_FILES+=usr/include/c++/3.3/bits/c++config.h
OLD_FILES+=usr/include/c++/3.3/bits/c++io.h
OLD_FILES+=usr/include/c++/3.3/bits/c++locale.h
OLD_FILES+=usr/include/c++/3.3/bits/c++locale_internal.h
OLD_FILES+=usr/include/c++/3.3/bits/char_traits.h
OLD_FILES+=usr/include/c++/3.3/bits/cmath.tcc
OLD_FILES+=usr/include/c++/3.3/bits/codecvt.h
OLD_FILES+=usr/include/c++/3.3/bits/codecvt_specializations.h
OLD_FILES+=usr/include/c++/3.3/bits/concept_check.h
OLD_FILES+=usr/include/c++/3.3/bits/cpp_type_traits.h
OLD_FILES+=usr/include/c++/3.3/bits/ctype_base.h
OLD_FILES+=usr/include/c++/3.3/bits/ctype_inline.h
OLD_FILES+=usr/include/c++/3.3/bits/ctype_noninline.h
OLD_FILES+=usr/include/c++/3.3/bits/deque.tcc
OLD_FILES+=usr/include/c++/3.3/bits/fpos.h
OLD_FILES+=usr/include/c++/3.3/bits/fstream.tcc
OLD_FILES+=usr/include/c++/3.3/bits/functexcept.h
OLD_FILES+=usr/include/c++/3.3/bits/generic_shadow.h
OLD_FILES+=usr/include/c++/3.3/bits/gslice.h
OLD_FILES+=usr/include/c++/3.3/bits/gslice_array.h
OLD_FILES+=usr/include/c++/3.3/bits/gthr-default.h
OLD_FILES+=usr/include/c++/3.3/bits/gthr-posix.h
OLD_FILES+=usr/include/c++/3.3/bits/gthr-single.h
OLD_FILES+=usr/include/c++/3.3/bits/gthr.h
OLD_FILES+=usr/include/c++/3.3/bits/indirect_array.h
OLD_FILES+=usr/include/c++/3.3/bits/ios_base.h
OLD_FILES+=usr/include/c++/3.3/bits/istream.tcc
OLD_FILES+=usr/include/c++/3.3/bits/list.tcc
OLD_FILES+=usr/include/c++/3.3/bits/locale_classes.h
OLD_FILES+=usr/include/c++/3.3/bits/locale_facets.h
OLD_FILES+=usr/include/c++/3.3/bits/locale_facets.tcc
OLD_FILES+=usr/include/c++/3.3/bits/localefwd.h
OLD_FILES+=usr/include/c++/3.3/bits/mask_array.h
OLD_FILES+=usr/include/c++/3.3/bits/messages_members.h
OLD_FILES+=usr/include/c++/3.3/bits/os_defines.h
OLD_FILES+=usr/include/c++/3.3/bits/ostream.tcc
OLD_FILES+=usr/include/c++/3.3/bits/pthread_allocimpl.h
OLD_FILES+=usr/include/c++/3.3/bits/slice.h
OLD_FILES+=usr/include/c++/3.3/bits/slice_array.h
OLD_FILES+=usr/include/c++/3.3/bits/sstream.tcc
OLD_FILES+=usr/include/c++/3.3/bits/stl_algo.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_algobase.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_alloc.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_bvector.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_construct.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_deque.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_function.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_heap.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_iterator.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_iterator_base_funcs.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_iterator_base_types.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_list.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_map.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_multimap.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_multiset.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_numeric.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_pair.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_pthread_alloc.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_queue.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_raw_storage_iter.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_relops.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_set.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_stack.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_tempbuf.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_threads.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_tree.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_uninitialized.h
OLD_FILES+=usr/include/c++/3.3/bits/stl_vector.h
OLD_FILES+=usr/include/c++/3.3/bits/stream_iterator.h
OLD_FILES+=usr/include/c++/3.3/bits/streambuf.tcc
OLD_FILES+=usr/include/c++/3.3/bits/streambuf_iterator.h
OLD_FILES+=usr/include/c++/3.3/bits/stringfwd.h
OLD_FILES+=usr/include/c++/3.3/bits/time_members.h
OLD_FILES+=usr/include/c++/3.3/bits/type_traits.h
OLD_FILES+=usr/include/c++/3.3/bits/valarray_array.h
OLD_FILES+=usr/include/c++/3.3/bits/valarray_array.tcc
OLD_FILES+=usr/include/c++/3.3/bits/valarray_meta.h
OLD_FILES+=usr/include/c++/3.3/bits/vector.tcc
OLD_DIRS+=usr/include/c++/3.3/bits
OLD_FILES+=usr/include/c++/3.3/bitset
OLD_FILES+=usr/include/c++/3.3/cassert
OLD_FILES+=usr/include/c++/3.3/cctype
OLD_FILES+=usr/include/c++/3.3/cerrno
OLD_FILES+=usr/include/c++/3.3/cfloat
OLD_FILES+=usr/include/c++/3.3/ciso646
OLD_FILES+=usr/include/c++/3.3/climits
OLD_FILES+=usr/include/c++/3.3/clocale
OLD_FILES+=usr/include/c++/3.3/cmath
OLD_FILES+=usr/include/c++/3.3/complex
OLD_FILES+=usr/include/c++/3.3/csetjmp
OLD_FILES+=usr/include/c++/3.3/csignal
OLD_FILES+=usr/include/c++/3.3/cstdarg
OLD_FILES+=usr/include/c++/3.3/cstddef
OLD_FILES+=usr/include/c++/3.3/cstdio
OLD_FILES+=usr/include/c++/3.3/cstdlib
OLD_FILES+=usr/include/c++/3.3/cstring
OLD_FILES+=usr/include/c++/3.3/ctime
OLD_FILES+=usr/include/c++/3.3/cwchar
OLD_FILES+=usr/include/c++/3.3/cwctype
OLD_FILES+=usr/include/c++/3.3/cxxabi.h
OLD_FILES+=usr/include/c++/3.3/deque
OLD_FILES+=usr/include/c++/3.3/exception
OLD_FILES+=usr/include/c++/3.3/exception_defines.h
OLD_FILES+=usr/include/c++/3.3/ext/algorithm
OLD_FILES+=usr/include/c++/3.3/ext/enc_filebuf.h
OLD_FILES+=usr/include/c++/3.3/ext/functional
OLD_FILES+=usr/include/c++/3.3/ext/hash_map
OLD_FILES+=usr/include/c++/3.3/ext/hash_set
OLD_FILES+=usr/include/c++/3.3/ext/iterator
OLD_FILES+=usr/include/c++/3.3/ext/memory
OLD_FILES+=usr/include/c++/3.3/ext/numeric
OLD_FILES+=usr/include/c++/3.3/ext/rb_tree
OLD_FILES+=usr/include/c++/3.3/ext/rope
OLD_FILES+=usr/include/c++/3.3/ext/ropeimpl.h
OLD_FILES+=usr/include/c++/3.3/ext/slist
OLD_FILES+=usr/include/c++/3.3/ext/stdio_filebuf.h
OLD_FILES+=usr/include/c++/3.3/ext/stl_hash_fun.h
OLD_FILES+=usr/include/c++/3.3/ext/stl_hashtable.h
OLD_FILES+=usr/include/c++/3.3/ext/stl_rope.h
OLD_DIRS+=usr/include/c++/3.3/ext
OLD_FILES+=usr/include/c++/3.3/fstream
OLD_FILES+=usr/include/c++/3.3/functional
OLD_FILES+=usr/include/c++/3.3/iomanip
OLD_FILES+=usr/include/c++/3.3/ios
OLD_FILES+=usr/include/c++/3.3/iosfwd
OLD_FILES+=usr/include/c++/3.3/iostream
OLD_FILES+=usr/include/c++/3.3/istream
OLD_FILES+=usr/include/c++/3.3/iterator
OLD_FILES+=usr/include/c++/3.3/limits
OLD_FILES+=usr/include/c++/3.3/list
OLD_FILES+=usr/include/c++/3.3/locale
OLD_FILES+=usr/include/c++/3.3/map
OLD_FILES+=usr/include/c++/3.3/memory
OLD_FILES+=usr/include/c++/3.3/new
OLD_FILES+=usr/include/c++/3.3/numeric
OLD_FILES+=usr/include/c++/3.3/ostream
OLD_FILES+=usr/include/c++/3.3/queue
OLD_FILES+=usr/include/c++/3.3/set
OLD_FILES+=usr/include/c++/3.3/sstream
OLD_FILES+=usr/include/c++/3.3/stack
OLD_FILES+=usr/include/c++/3.3/stdexcept
OLD_FILES+=usr/include/c++/3.3/streambuf
OLD_FILES+=usr/include/c++/3.3/string
OLD_FILES+=usr/include/c++/3.3/typeinfo
OLD_FILES+=usr/include/c++/3.3/utility
OLD_FILES+=usr/include/c++/3.3/valarray
OLD_FILES+=usr/include/c++/3.3/vector
# 20040713: fla(4) removed.
OLD_FILES+=usr/share/man/man4/fla.4.gz
# 200407XX

View File

@ -32,7 +32,7 @@
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
.\" $FreeBSD$
.\"
.Dd April 2, 2014
.Dd August 28, 2014
.Dt DD 1
.Os
.Sh NAME
@ -408,6 +408,11 @@ To create an image of a Mode-1 CD-ROM, which is a commonly used format
for data CD-ROM disks, use a block size of 2048 bytes:
.Pp
.Dl "dd if=/dev/acd0 of=filename.iso bs=2048"
.Pp
Write a filesystem image to a memory stick, padding the end with zeros,
if necessary, to a 1MiB boundary:
.Pp
.Dl "dd if=memstick.img of=/dev/da0 bs=1m conv=noerror,sync"
.Sh SEE ALSO
.Xr cp 1 ,
.Xr mt 1 ,

View File

@ -237,7 +237,7 @@ expand_des_key(char *obuf, char *kbuf)
/*
* now translate it, bombing on any illegal hex digit
*/
for (i = 0; kbuf[i] && i < 16; i++)
for (i = 0; i < 16 && kbuf[i]; i++)
if ((nbuf[i] = hex_to_binary((int) kbuf[i], 16)) == -1)
des_error("bad hex digit in key");
while (i < 16)

View File

@ -14,6 +14,7 @@ TAP_TESTS_SH+= pgrep-g_test
TAP_TESTS_SH+= pgrep-i_test
TAP_TESTS_SH+= pgrep-j_test
TEST_METADATA.pgrep-j_test+= required_user="root"
TEST_METADATA.pgrep-j_test+= required_programs="jail jls"
TAP_TESTS_SH+= pgrep-l_test
TAP_TESTS_SH+= pgrep-n_test
TAP_TESTS_SH+= pgrep-o_test
@ -31,6 +32,7 @@ TAP_TESTS_SH+= pkill-g_test
TAP_TESTS_SH+= pkill-i_test
TAP_TESTS_SH+= pkill-j_test
TEST_METADATA.pkill-j_test+= required_user="root"
TEST_METADATA.pkill-j_test+= required_programs="jail jls"
TAP_TESTS_SH+= pkill-s_test
TAP_TESTS_SH+= pkill-t_test
TAP_TESTS_SH+= pkill-x_test

View File

@ -157,6 +157,7 @@ static VAR var[] = {
{"tdnam", "TDNAM", NULL, LJUST, tdnam, 0, CHAR, NULL, 0},
{"time", "TIME", NULL, USER, cputime, 0, CHAR, NULL, 0},
{"tpgid", "TPGID", NULL, 0, kvar, KOFF(ki_tpgid), UINT, PIDFMT, 0},
{"tracer", "TRACER", NULL, 0, kvar, KOFF(ki_tracer), UINT, PIDFMT, 0},
{"tsid", "TSID", NULL, 0, kvar, KOFF(ki_tsid), UINT, PIDFMT, 0},
{"tsiz", "TSIZ", NULL, 0, kvar, KOFF(ki_tsize), PGTOK, "ld", 0},
{"tt", "TT ", NULL, 0, tname, 0, CHAR, NULL, 0},

View File

@ -29,7 +29,7 @@
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd August 7, 2014
.Dd August 27, 2014
.Dt PS 1
.Os
.Sh NAME
@ -665,6 +665,8 @@ accumulated CPU time, user + system (alias
.Cm cputime )
.It Cm tpgid
control terminal process group ID
.It Cm tracer
tracer process ID
.\".It Cm trss
.\"text resident set size (in Kbytes)
.It Cm tsid

View File

@ -14,8 +14,6 @@ MAN= rmail.8
WARNS?= 2
CFLAGS+=-I${SENDMAIL_DIR}/include -I.
NO_PIE= yes
LIBSMDIR= ${.OBJDIR}/../../lib/libsm
LIBSM= ${LIBSMDIR}/libsm.a

View File

@ -139,9 +139,9 @@ static arith_t do_binop(int op, arith_t a, arith_t b)
case ARITH_SUB:
return (uintmax_t)a - (uintmax_t)b;
case ARITH_LSHIFT:
return (uintmax_t)a << b;
return (uintmax_t)a << (b & (sizeof(uintmax_t) * CHAR_BIT - 1));
case ARITH_RSHIFT:
return a >> b;
return a >> (b & (sizeof(uintmax_t) * CHAR_BIT - 1));
case ARITH_LT:
return a < b;
case ARITH_LE:

View File

@ -166,9 +166,10 @@ sethistsize(const char *hs)
HistEvent he;
if (hist != NULL) {
if (hs == NULL || *hs == '\0' ||
(histsize = atoi(hs)) < 0)
if (hs == NULL || !is_number(hs))
histsize = 100;
else
histsize = atoi(hs);
history(hist, &he, H_SETSIZE, histsize);
history(hist, &he, H_SETUNIQUE, 1);
}

View File

@ -116,33 +116,6 @@ resetinput(void)
}
/*
* Read a line from the script.
*/
char *
pfgets(char *line, int len)
{
char *p = line;
int nleft = len;
int c;
while (--nleft > 0) {
c = pgetc_macro();
if (c == PEOF) {
if (p == line)
return NULL;
break;
}
*p++ = c;
if (c == '\n')
break;
}
*p = '\0';
return line;
}
/*
* Read a character from the script, returning PEOF on end of file.
@ -338,7 +311,7 @@ pungetc(void)
* We handle aliases this way.
*/
void
pushstring(char *s, int len, struct alias *ap)
pushstring(const char *s, int len, struct alias *ap)
{
struct strpush *sp;

View File

@ -48,12 +48,11 @@ struct alias;
struct parsefile;
void resetinput(void);
char *pfgets(char *, int);
int pgetc(void);
int preadbuffer(void);
int preadateof(void);
void pungetc(void);
void pushstring(char *, int, struct alias *);
void pushstring(const char *, int, struct alias *);
void setinputfile(const char *, int);
void setinputfd(int, int);
void setinputstring(const char *, int);

View File

@ -118,6 +118,24 @@ static void showjob(struct job *, int);
static int jobctl;
#if JOBS
static void
jobctl_notty(void)
{
if (ttyfd >= 0) {
close(ttyfd);
ttyfd = -1;
}
if (!iflag) {
setsignal(SIGTSTP);
setsignal(SIGTTOU);
setsignal(SIGTTIN);
jobctl = 1;
return;
}
out2fmt_flush("sh: can't access tty; job control turned off\n");
mflag = 0;
}
void
setjobctl(int on)
{
@ -133,8 +151,10 @@ setjobctl(int on)
while (i <= 2 && !isatty(i))
i++;
if (i > 2 ||
(ttyfd = fcntl(i, F_DUPFD_CLOEXEC, 10)) < 0)
goto out;
(ttyfd = fcntl(i, F_DUPFD_CLOEXEC, 10)) < 0) {
jobctl_notty();
return;
}
}
if (ttyfd < 10) {
/*
@ -142,9 +162,8 @@ setjobctl(int on)
* the user's redirections.
*/
if ((i = fcntl(ttyfd, F_DUPFD_CLOEXEC, 10)) < 0) {
close(ttyfd);
ttyfd = -1;
goto out;
jobctl_notty();
return;
}
close(ttyfd);
ttyfd = i;
@ -152,11 +171,15 @@ setjobctl(int on)
do { /* while we are in the background */
initialpgrp = tcgetpgrp(ttyfd);
if (initialpgrp < 0) {
out: out2fmt_flush("sh: can't access tty; job control turned off\n");
mflag = 0;
jobctl_notty();
return;
}
if (initialpgrp != getpgrp()) {
if (!iflag) {
initialpgrp = -1;
jobctl_notty();
return;
}
kill(0, SIGTTIN);
continue;
}
@ -168,9 +191,11 @@ out: out2fmt_flush("sh: can't access tty; job control turned off\n");
tcsetpgrp(ttyfd, rootpid);
} else { /* turning job control off */
setpgid(0, initialpgrp);
tcsetpgrp(ttyfd, initialpgrp);
close(ttyfd);
ttyfd = -1;
if (ttyfd >= 0) {
tcsetpgrp(ttyfd, initialpgrp);
close(ttyfd);
ttyfd = -1;
}
setsignal(SIGTSTP);
setsignal(SIGTTOU);
setsignal(SIGTTIN);
@ -195,7 +220,8 @@ fgcmd(int argc __unused, char **argv __unused)
printjobcmd(jp);
flushout(&output);
pgrp = jp->ps[0].pid;
tcsetpgrp(ttyfd, pgrp);
if (ttyfd >= 0)
tcsetpgrp(ttyfd, pgrp);
restartjob(jp);
jp->foreground = 1;
INTOFF;
@ -847,7 +873,8 @@ forkshell(struct job *jp, union node *n, int mode)
pgrp = getpid();
else
pgrp = jp->ps[0].pid;
if (setpgid(0, pgrp) == 0 && mode == FORK_FG) {
if (setpgid(0, pgrp) == 0 && mode == FORK_FG &&
ttyfd >= 0) {
/*** this causes superfluous TIOCSPGRPS ***/
if (tcsetpgrp(ttyfd, pgrp) < 0)
error("tcsetpgrp failed, errno=%d", errno);
@ -1007,7 +1034,7 @@ waitforjob(struct job *jp, int *origstatus)
dotrap();
#if JOBS
if (jp->jobctl) {
if (tcsetpgrp(ttyfd, rootpid) < 0)
if (ttyfd >= 0 && tcsetpgrp(ttyfd, rootpid) < 0)
error("tcsetpgrp failed, errno=%d\n", errno);
}
if (jp->state == JOBSTOPPED)

View File

@ -82,9 +82,17 @@ number(const char *s)
int
is_number(const char *p)
{
do {
if (! is_digit(*p))
const char *q;
if (*p == '\0')
return 0;
while (*p == '0')
p++;
for (q = p; *q != '\0'; q++)
if (! is_digit(*q))
return 0;
} while (*++p != '\0');
if (q - p > 10 ||
(q - p == 10 && memcmp(p, "2147483647", 10) > 0))
return 0;
return 1;
}

View File

@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$");
* Shell command parser.
*/
#define EOFMARKLEN 79
#define PROMPTLEN 128
/* values of checkkwd variable */
@ -718,7 +717,6 @@ parsefname(void)
if (n->type == NHERE) {
struct heredoc *here = heredoc;
struct heredoc *p;
int i;
if (quoteflag == 0)
n->type = NXHERE;
@ -727,7 +725,7 @@ parsefname(void)
while (*wordtext == '\t')
wordtext++;
}
if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
if (! noexpand(wordtext))
synerror("Illegal eof marker for << redirection");
rmescapes(wordtext);
here->eofmark = wordtext;
@ -945,6 +943,41 @@ struct tokenstate
};
/*
* Check to see whether we are at the end of the here document. When this
* is called, c is set to the first character of the next input line. If
* we are at the end of the here document, this routine sets the c to PEOF.
* The new value of c is returned.
*/
static int
checkend(int c, const char *eofmark, int striptabs)
{
if (striptabs) {
while (c == '\t')
c = pgetc();
}
if (c == *eofmark) {
int c2;
const char *q;
for (q = eofmark + 1; c2 = pgetc(), *q != '\0' && c2 == *q; q++)
;
if ((c2 == PEOF || c2 == '\n') && *q == '\0') {
c = PEOF;
if (c2 == '\n') {
plinno++;
needprompt = doprompt;
}
} else {
pungetc();
pushstring(eofmark + 1, q - (eofmark + 1), NULL);
}
}
return (c);
}
/*
* Called to parse command substitutions.
*/
@ -1269,7 +1302,6 @@ readcstyleesc(char *out)
* will run code that appears at the end of readtoken1.
*/
#define CHECKEND() {goto checkend; checkend_return:;}
#define PARSEREDIR() {goto parseredir; parseredir_return:;}
#define PARSESUB() {goto parsesub; parsesub_return:;}
#define PARSEARITH() {goto parsearith; parsearith_return:;}
@ -1281,7 +1313,6 @@ readtoken1(int firstc, char const *initialsyntax, const char *eofmark,
int c = firstc;
char *out;
int len;
char line[EOFMARKLEN + 1];
struct nodelist *bqlist;
int quotef;
int newvarnest;
@ -1303,7 +1334,9 @@ readtoken1(int firstc, char const *initialsyntax, const char *eofmark,
STARTSTACKSTR(out);
loop: { /* for each line, until end of word */
CHECKEND(); /* set c to PEOF if at end of here document */
if (eofmark)
/* set c to PEOF if at end of here document */
c = checkend(c, eofmark, striptabs);
for (;;) { /* until end of line or end of word */
CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
@ -1483,40 +1516,6 @@ endword:
/* end of readtoken routine */
/*
* Check to see whether we are at the end of the here document. When this
* is called, c is set to the first character of the next input line. If
* we are at the end of the here document, this routine sets the c to PEOF.
*/
checkend: {
if (eofmark) {
if (striptabs) {
while (c == '\t')
c = pgetc();
}
if (c == *eofmark) {
if (pfgets(line, sizeof line) != NULL) {
const char *p, *q;
p = line;
for (q = eofmark + 1 ; *q && *p == *q ; p++, q++);
if ((*p == '\0' || *p == '\n') && *q == '\0') {
c = PEOF;
if (*p == '\n') {
plinno++;
needprompt = doprompt;
}
} else {
pushstring(line, strlen(line), NULL);
}
}
}
}
goto checkend_return;
}
/*
* Parse a redirection operator. The variable "out" points to a string
* specifying the fd to be redirected. The variable "c" contains the
@ -1915,7 +1914,7 @@ char *
getprompt(void *unused __unused)
{
static char ps[PROMPTLEN];
char *fmt;
const char *fmt;
const char *pwd;
int i, trim;
static char internal_error[] = "??";
@ -2029,7 +2028,7 @@ expandstr(const char *ps)
parser_temp = NULL;
setinputstring(ps, 1);
doprompt = 0;
readtoken1(pgetc(), DQSYNTAX, "\n\n", 0);
readtoken1(pgetc(), DQSYNTAX, "", 0);
if (backquotelist != NULL)
error("Command substitution not allowed here");

View File

@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd January 26, 2014
.Dd September 4, 2014
.Dt SH 1
.Os
.Sh NAME
@ -259,6 +259,12 @@ from input when in interactive mode.
Force the shell to behave interactively.
.It Fl m Li monitor
Turn on job control (set automatically when interactive).
A new process group is created for each pipeline (called a job).
It is possible to suspend jobs or to have them run in the foreground or
in the background.
In a non-interactive shell,
this option can be set even if no terminal is available
and is useful to place processes in separate process groups.
.It Fl n Li noexec
If not interactive, read commands but do not
execute them.

View File

@ -1,2 +1,2 @@
# $FreeBSD$
${}
eval '${}'

View File

@ -1 +1 @@
./bad-parm-exp2.2: ${}: Bad substitution
eval: ${}: Bad substitution

View File

@ -1,2 +1,2 @@
# $FreeBSD$
${foo/}
eval '${foo/}'

View File

@ -1 +1 @@
./bad-parm-exp3.2: ${foo/}: Bad substitution
eval: ${foo/}: Bad substitution

View File

@ -1,2 +1,2 @@
# $FreeBSD$
${foo:@abc}
eval '${foo:@abc}'

View File

@ -1 +1 @@
./bad-parm-exp4.2: ${foo:@...}: Bad substitution
eval: ${foo:@...}: Bad substitution

View File

@ -1,2 +1,2 @@
# $FreeBSD$
${/}
eval '${/}'

View File

@ -1 +1 @@
./bad-parm-exp5.2: ${/}: Bad substitution
eval: ${/}: Bad substitution

View File

@ -1,2 +1,2 @@
# $FreeBSD$
${#foo^}
eval '${#foo^}'

View File

@ -1 +1 @@
./bad-parm-exp6.2: ${foo...}: Bad substitution
eval: ${foo...}: Bad substitution

View File

@ -20,6 +20,7 @@ FILES+= arith10.0
FILES+= arith11.0
FILES+= arith12.0
FILES+= arith13.0
FILES+= arith14.0
FILES+= assign1.0
FILES+= cmdsubst1.0
FILES+= cmdsubst2.0

View File

@ -0,0 +1,40 @@
# $FreeBSD$
# Check that <</>> use the low bits of the shift count.
if [ $((1<<16<<16)) = 0 ]; then
width=32
elif [ $((1<<32<<32)) = 0 ]; then
width=64
elif [ $((1<<64<<64)) = 0 ]; then
width=128
elif [ $((1<<64>>64)) = 1 ]; then
# Integers are wider than 128 bits; assume arbitrary precision.
# Nothing to test here.
exit 0
else
echo "Cannot determine integer width"
exit 2
fi
twowidth=$((width * 2))
j=43 k=$((1 << (width - 2))) r=0
i=0
while [ $i -lt $twowidth ]; do
if [ "$((j << i))" != "$((j << (i + width)))" ]; then
echo "Problem with $j << $i"
r=2
fi
i=$((i + 1))
done
i=0
while [ $i -lt $twowidth ]; do
if [ "$((k >> i))" != "$((k >> (i + width)))" ]; then
echo "Problem with $k >> $i"
r=2
fi
i=$((i + 1))
done
exit $r

View File

@ -39,13 +39,7 @@ check()
local out_file="${SRCDIR}/${tc}.stdout"
[ -f "${out_file}" ] && out_flag="-o file:${out_file}"
# We need to copy the testcase scenario file because some of the
# testcases hardcode relative paths in the stderr/stdout.
#
# TODO: we might be able to generate this path at build time
cp ${SRCDIR}/${tc} .
atf_check -s exit:${tc##*.} ${err_flag} ${out_flag} ${SH} "./${tc}"
atf_check -s exit:${tc##*.} ${err_flag} ${out_flag} ${SH} "${SRCDIR}/${tc}"
}
add_testcase()

View File

@ -54,6 +54,7 @@ FILES+= heredoc8.0
FILES+= heredoc9.0
FILES+= heredoc10.0
FILES+= heredoc11.0
FILES+= heredoc12.0
FILES+= no-space1.0
FILES+= no-space2.0
FILES+= only-redir1.0

View File

@ -0,0 +1,47 @@
# $FreeBSD$
failures=0
check() {
if ! eval "[ $* ]"; then
echo "Failed: $*"
: $((failures += 1))
fi
}
longmark=`printf %01000d 4`
longmarkstripped=`printf %0999d 0`
check '"$(cat <<'"$longmark
$longmark"'
echo yes)" = "yes"'
check '"$(cat <<\'"$longmark
$longmark"'
echo yes)" = "yes"'
check '"$(cat <<'"$longmark
yes
$longmark"'
)" = "yes"'
check '"$(cat <<\'"$longmark
yes
$longmark"'
)" = "yes"'
check '"$(cat <<'"$longmark
$longmarkstripped
$longmark.
$longmark"'
)" = "'"$longmarkstripped
$longmark."'"'
check '"$(cat <<\'"$longmark
$longmarkstripped
$longmark.
$longmark"'
)" = "'"$longmarkstripped
$longmark."'"'
exit $((failures != 0))

View File

@ -8,7 +8,6 @@ IGNORE_PRAGMA= YES
CFLAGS+= -DNEED_SOLARIS_BOOLEAN
WARNS?= 6
CSTD?= gnu89
# Do not lint the CDDL stuff. It is all externally maintained and
# lint output is wasteful noise here.

View File

@ -31,7 +31,7 @@ dtrace=$1
t="zelda_info_t"
exe="tst.chasestrings.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -28,7 +28,7 @@ dtrace=$1
t="season_7_lisa_the_vegetrian_t *"
exe="tst.aouttype.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -29,7 +29,7 @@ dtrace=$1
t="zelda_info_t"
exe="tst.chasestrings.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -29,7 +29,7 @@ dtrace=$1
t="int"
exe="tst.libtype.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -eq 0 ]]; then
echo "CTF exists in $exe, that's a bug" >&2
exit 1

View File

@ -28,7 +28,7 @@ dtrace=$1
t="final_fantasy_info_t"
exe="tst.printtype.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -29,7 +29,7 @@ dtrace=$1
t="final_fantasy_info_t"
exe="tst.printtype.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -28,7 +28,7 @@ dtrace=$1
t="final_fantasy_info_t"
exe="tst.printtype.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -29,7 +29,7 @@ dtrace=$1
t="final_fantasy_info_t"
exe="tst.printtype.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -29,7 +29,7 @@ dtrace=$1
t="zelda_info_t"
exe="tst.chasestrings.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -28,7 +28,7 @@ fi
dtrace=$1
exe="tst.chasestrings.exe"
elfdump "./$exe" | grep -q '.SUNW_ctf'
elfdump -c "./$exe" | grep -Fq 'sh_name: .SUNW_ctf'
if [[ $? -ne 0 ]]; then
echo "CTF does not exist in $exe, that's a bug" >&2
exit 1

View File

@ -50,6 +50,9 @@
/* FreeBSD */
#include <sys/elf.h>
#include <sys/ksyms.h>
#include <sys/param.h>
#include <sys/module.h>
#include <sys/linker.h>
#endif
#include <sys/cpuvar.h>

View File

@ -414,7 +414,7 @@ or smaller can take advantage of this feature.
When this feature is enabled, the contents of highly-compressible blocks are
stored in the block "pointer" itself
.Po a misnomer in this case, as it contains
the compresseed data, rather than a pointer to its location on disk
the compressed data, rather than a pointer to its location on disk
.Pc .
Thus
the space of the block

View File

@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
/*
@ -1068,8 +1069,8 @@ is_spare(nvlist_t *config, const char *path)
* Go through and find any devices that are in use. We rely on libdiskmgt for
* the majority of this task.
*/
static int
check_in_use(nvlist_t *config, nvlist_t *nv, boolean_t force,
static boolean_t
is_device_in_use(nvlist_t *config, nvlist_t *nv, boolean_t force,
boolean_t replacing, boolean_t isspare)
{
nvlist_t **child;
@ -1078,6 +1079,7 @@ check_in_use(nvlist_t *config, nvlist_t *nv, boolean_t force,
int ret;
char buf[MAXPATHLEN];
uint64_t wholedisk;
boolean_t anyinuse = B_FALSE;
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
@ -1102,38 +1104,37 @@ check_in_use(nvlist_t *config, nvlist_t *nv, boolean_t force,
(void) strlcpy(buf, path, sizeof (buf));
if (is_spare(config, buf))
return (0);
return (B_FALSE);
}
if (strcmp(type, VDEV_TYPE_DISK) == 0)
ret = check_device(path, force, isspare);
if (strcmp(type, VDEV_TYPE_FILE) == 0)
else if (strcmp(type, VDEV_TYPE_FILE) == 0)
ret = check_file(path, force, isspare);
return (ret);
return (ret != 0);
}
for (c = 0; c < children; c++)
if ((ret = check_in_use(config, child[c], force,
replacing, B_FALSE)) != 0)
return (ret);
if (is_device_in_use(config, child[c], force, replacing,
B_FALSE))
anyinuse = B_TRUE;
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
&child, &children) == 0)
for (c = 0; c < children; c++)
if ((ret = check_in_use(config, child[c], force,
replacing, B_TRUE)) != 0)
return (ret);
if (is_device_in_use(config, child[c], force, replacing,
B_TRUE))
anyinuse = B_TRUE;
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
&child, &children) == 0)
for (c = 0; c < children; c++)
if ((ret = check_in_use(config, child[c], force,
replacing, B_FALSE)) != 0)
return (ret);
if (is_device_in_use(config, child[c], force, replacing,
B_FALSE))
anyinuse = B_TRUE;
return (0);
return (anyinuse);
}
static const char *
@ -1487,7 +1488,7 @@ make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
* uses (such as a dedicated dump device) that even '-f' cannot
* override.
*/
if (check_in_use(poolconfig, newroot, force, replacing, B_FALSE) != 0) {
if (is_device_in_use(poolconfig, newroot, force, replacing, B_FALSE)) {
nvlist_free(newroot);
return (NULL);
}

View File

@ -19,6 +19,8 @@
* CDDL HEADER END
*/
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -27,8 +29,6 @@
#ifndef _LIBINTL_H
#define _LIBINTL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/isa_defs.h>
#ifdef __cplusplus
@ -64,7 +64,6 @@ typedef long wchar_t;
#define __GNU_GETTEXT_SUPPORTED_REVISION(m) \
((((m) == 0) || ((m) == 1)) ? 1 : -1)
#ifdef __STDC__
extern char *dcgettext(const char *, const char *, const int);
extern char *dgettext(const char *, const char *);
extern char *gettext(const char *);
@ -91,33 +90,6 @@ extern wchar_t *wddelim(wchar_t, wchar_t, int);
extern wchar_t mcfiller(void);
extern int mcwrap(void);
#else
extern char *dcgettext();
extern char *dgettext();
extern char *gettext();
extern char *textdomain();
extern char *bindtextdomain();
/*
* LI18NUX 2000 Globalization Specification Version 1.0
* with Amendment 2
*/
extern char *dcngettext();
extern char *dngettext();
extern char *ngettext();
extern char *bind_textdomain_codeset();
/* Word handling functions --- requires dynamic linking */
/* Warning: these are experimental and subject to change. */
extern int wdinit();
extern int wdchkind();
extern int wdbindf();
extern wchar_t *wddelim();
extern wchar_t mcfiller();
extern int mcwrap();
#endif
#ifdef __cplusplus
}
#endif

View File

@ -19,6 +19,9 @@
*
* CDDL HEADER END
*/
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
@ -26,8 +29,6 @@
#ifndef _NLIST_H
#define _NLIST_H
#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.8.2.4 */
#ifdef __cplusplus
extern "C" {
#endif
@ -41,11 +42,7 @@ struct nlist {
char n_numaux; /* number of aux. entries */
};
#if defined(__STDC__)
extern int nlist(const char *, struct nlist *);
#else /* __STDC__ */
extern int nlist();
#endif /* __STDC__ */
#ifdef __cplusplus
}

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@ -86,7 +87,6 @@ typedef struct _rwlock {
cond_t writercv; /* used only to indicate ownership */
} rwlock_t;
#ifdef __STDC__
int _lwp_mutex_lock(lwp_mutex_t *);
int _lwp_mutex_unlock(lwp_mutex_t *);
int _lwp_mutex_trylock(lwp_mutex_t *);
@ -127,50 +127,6 @@ int sema_reltimedwait(sema_t *, const timespec_t *);
int sema_post(sema_t *);
int sema_trywait(sema_t *);
#else /* __STDC__ */
int _lwp_mutex_lock();
int _lwp_mutex_unlock();
int _lwp_mutex_trylock();
int _lwp_cond_wait();
int _lwp_cond_timedwait();
int _lwp_cond_reltimedwait();
int _lwp_cond_signal();
int _lwp_cond_broadcast();
int _lwp_sema_init();
int _lwp_sema_wait();
int _lwp_sema_trywait();
int _lwp_sema_post();
int cond_init();
int cond_destroy();
int cond_wait();
int cond_timedwait();
int cond_reltimedwait();
int cond_signal();
int cond_broadcast();
int mutex_init();
int mutex_destroy();
int mutex_consistent();
int mutex_lock();
int mutex_trylock();
int mutex_unlock();
int rwlock_init();
int rwlock_destroy();
int rw_rdlock();
int rw_wrlock();
int rw_unlock();
int rw_tryrdlock();
int rw_trywrlock();
int sema_init();
int sema_destroy();
int sema_wait();
int sema_timedwait();
int sema_reltimedwait();
int sema_post();
int sema_trywait();
#endif /* __STDC__ */
#endif /* _ASM */
/* "Magic numbers" tagging synchronization object types */
@ -238,8 +194,6 @@ int sema_trywait();
#ifndef _ASM
#ifdef __STDC__
/*
* The *_held() functions apply equally well to Solaris threads
* and to Posix threads synchronization objects, but the formal
@ -252,21 +206,8 @@ int _rw_read_held(void *); /* rwlock_t or pthread_rwlock_t */
int _rw_write_held(void *); /* rwlock_t or pthread_rwlock_t */
int _mutex_held(void *); /* mutex_t or pthread_mutex_t */
#else /* __STDC__ */
int _sema_held();
int _rw_read_held();
int _rw_write_held();
int _mutex_held();
#endif /* __STDC__ */
/* Pause API */
#ifdef __STDC__
void smt_pause(void);
#else /* __STDC__ */
void smt_pause();
#endif /* __STDC__ */
#endif /* _ASM */

View File

@ -20,6 +20,8 @@
*/
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -27,8 +29,6 @@
#ifndef _THREAD_H
#define _THREAD_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <pthread.h>
#include <pthread_np.h>
#include <assert.h>

View File

@ -90,36 +90,6 @@ dprintf(int debug, const char *fmt, ...)
va_end(ap);
}
#if !defined(sun)
static void
fixsymbol(Elf *e, Elf_Data *data, size_t idx, int nprobes, char *buf,
dof_sec_t *sec, int *fixedprobes, char *dofstrtab)
{
GElf_Sym sym;
char *s;
unsigned char *funcname;
dof_probe_t *prb;
int j = 0;
int ndx;
while (gelf_getsym(data, j++, &sym) != NULL) {
prb = (dof_probe_t *)(void *)(buf + sec->dofs_offset);
for (ndx = nprobes; ndx; ndx--, prb += 1) {
funcname = dofstrtab + prb->dofpr_func;
s = elf_strptr(e, idx, sym.st_name);
if (strcmp(s, funcname) == 0) {
dprintf(1, "fixing %s() symbol\n", s);
prb->dofpr_addr = sym.st_value;
(*fixedprobes)++;
}
}
if (*fixedprobes == nprobes)
break;
}
}
#endif
#if defined(sun)
#pragma init(dtrace_dof_init)
#else
@ -145,9 +115,6 @@ dtrace_dof_init(void)
Lmid_t lmid;
#else
u_long lmid = 0;
dof_sec_t *sec, *secstart, *dofstrtab, *dofprobes;
dof_provider_t *dofprovider;
size_t i;
#endif
int fd;
const char *p;
@ -157,12 +124,9 @@ dtrace_dof_init(void)
Elf_Data *symtabdata = NULL, *dynsymdata = NULL, *dofdata = NULL;
dof_hdr_t *dof_next = NULL;
GElf_Shdr shdr;
int efd, nprobes;
int efd;
char *s;
char *dofstrtabraw;
size_t shstridx, symtabidx = 0, dynsymidx = 0;
unsigned char *buf;
int fixedprobes;
#endif
if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
@ -183,7 +147,6 @@ dtrace_dof_init(void)
}
#endif
if ((modname = strrchr(lmp->l_name, '/')) == NULL)
modname = lmp->l_name;
else
@ -209,9 +172,9 @@ dtrace_dof_init(void)
} else if (shdr.sh_type == SHT_DYNSYM) {
dynsymidx = shdr.sh_link;
dynsymdata = elf_getdata(scn, NULL);
} else if (shdr.sh_type == SHT_PROGBITS) {
} else if (shdr.sh_type == SHT_SUNW_dof) {
s = elf_strptr(e, shstridx, shdr.sh_name);
if (s && strcmp(s, ".SUNW_dof") == 0) {
if (s != NULL && strcmp(s, ".SUNW_dof") == 0) {
dofdata = elf_getdata(scn, NULL);
dof = dofdata->d_buf;
}
@ -225,7 +188,6 @@ dtrace_dof_init(void)
}
while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) {
fixedprobes = 0;
dof_next = (void *) ((char *) dof + dof->dofh_filesz);
#endif
@ -273,76 +235,6 @@ dtrace_dof_init(void)
return;
#endif
}
#if !defined(sun)
/*
* We need to fix the base address of each probe since this wasn't
* done by ld(1). (ld(1) needs to grow support for parsing the
* SUNW_dof section).
*
* The complexity of this is not that great. The first for loop
* iterates over the sections inside the DOF file. There are usually
* 10 sections here. We asume the STRTAB section comes first and the
* PROBES section comes after. Since we are only interested in fixing
* data inside the PROBES section we quit the for loop after processing
* the PROBES section. It's usually the case that the first section
* is the STRTAB section and the second section is the PROBES section,
* so this for loop is not meaningful when doing complexity analysis.
*
* After finding the probes section, we iterate over the symbols
* in the symtab section. When we find a symbol name that matches
* the probe function name, we fix it. If we have fixed all the
* probes, we exit all the loops and we are done.
* The number of probes is given by the variable 'nprobes' and this
* depends entirely on the user, but some optimizations were done.
*
* We are assuming the number of probes is less than the number of
* symbols (libc can have 4k symbols, for example).
*/
secstart = sec = (dof_sec_t *)(dof + 1);
buf = (char *)dof;
for (i = 0; i < dof->dofh_secnum; i++, sec++) {
if (sec->dofs_type != DOF_SECT_PROVIDER)
continue;
dofprovider = (void *) (buf + sec->dofs_offset);
dofstrtab = secstart + dofprovider->dofpv_strtab;
dofprobes = secstart + dofprovider->dofpv_probes;
if (dofstrtab->dofs_type != DOF_SECT_STRTAB) {
fprintf(stderr, "WARNING: expected STRTAB section, but got %d\n",
dofstrtab->dofs_type);
break;
}
if (dofprobes->dofs_type != DOF_SECT_PROBES) {
fprintf(stderr, "WARNING: expected PROBES section, but got %d\n",
dofprobes->dofs_type);
break;
}
dprintf(1, "found provider %p\n", dofprovider);
dofstrtabraw = (char *)(buf + dofstrtab->dofs_offset);
nprobes = dofprobes->dofs_size / dofprobes->dofs_entsize;
fixsymbol(e, symtabdata, symtabidx, nprobes, buf, dofprobes, &fixedprobes,
dofstrtabraw);
if (fixedprobes != nprobes) {
/*
* If we haven't fixed all the probes using the
* symtab section, look inside the dynsym
* section.
*/
fixsymbol(e, dynsymdata, dynsymidx, nprobes, buf, dofprobes,
&fixedprobes, dofstrtabraw);
}
if (fixedprobes != nprobes) {
fprintf(stderr, "WARNING: number of probes "
"fixed does not match the number of "
"defined probes (%d != %d, "
"respectively)\n", fixedprobes, nprobes);
fprintf(stderr, "WARNING: some probes might "
"not fire or your program might crash\n");
}
}
#endif
if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1)
dprintf(1, "DTrace ioctl failed for DOF at %p", dof);
else {

View File

@ -723,6 +723,11 @@ extern int _dtrace_argmax; /* default maximum probe arguments */
extern const char *_dtrace_libdir; /* default library directory */
extern const char *_dtrace_moddir; /* default kernel module directory */
#ifdef __FreeBSD__
extern int gmatch(const char *, const char *);
extern int yylex(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -322,7 +322,11 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
char *strtab;
int i, j, nrel;
size_t strtabsz = 1;
#if defined(sun)
uint32_t count = 0;
#else
uint64_t count = 0;
#endif
size_t base;
Elf64_Sym *sym;
Elf64_Rela *rel;
@ -418,7 +422,6 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
s = &dofs[dofrh->dofr_tgtsec];
for (j = 0; j < nrel; j++) {
#ifdef DOODAD
#if defined(__arm__)
/* XXX */
#elif defined(__mips__)
@ -431,8 +434,13 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
#elif defined(__i386) || defined(__amd64)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
#if defined(sun)
rel->r_info = ELF64_R_INFO(count + dep->de_global,
R_AMD64_64);
#else
rel->r_info = ELF64_R_INFO(count + dep->de_global,
R_X86_64_RELATIVE);
#endif
#elif defined(__sparc)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
@ -440,7 +448,6 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
R_SPARC_64);
#else
#error unknown ISA
#endif
#endif
sym->st_name = base + dofr[j].dofr_name - 1;
@ -704,7 +711,11 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
shp = &elf_file.shdr[ESHDR_DOF];
shp->sh_name = 11; /* DTRACE_SHSTRTAB64[11] = ".SUNW_dof" */
#if defined(sun)
shp->sh_flags = SHF_ALLOC;
#else
shp->sh_flags = SHF_WRITE | SHF_ALLOC;
#endif
shp->sh_type = SHT_SUNW_dof;
shp->sh_offset = off;
shp->sh_size = dof->dofh_filesz;
@ -1662,19 +1673,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
{
#if !defined(sun)
char tfile[PATH_MAX];
Elf *e;
Elf_Scn *scn;
Elf_Data *data;
GElf_Shdr shdr;
int efd;
size_t stridx;
unsigned char *buf;
char *s;
int loc;
GElf_Ehdr ehdr;
Elf_Scn *scn0;
GElf_Shdr shdr0;
uint64_t off, rc;
#endif
char drti[PATH_MAX];
dof_hdr_t *dof;
@ -1810,21 +1808,22 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
(void) unlink(file);
#endif
#if defined(sun)
if (dtp->dt_oflags & DTRACE_O_LP64)
status = dump_elf64(dtp, dof, fd);
else
status = dump_elf32(dtp, dof, fd);
#if defined(sun)
if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) {
return (dt_link_error(dtp, NULL, -1, NULL,
"failed to write %s: %s", file, strerror(errno)));
}
#else
/* We don't write the ELF header, just the DOF section */
if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz)
(void)close(fd);
if (status != 0)
return (dt_link_error(dtp, NULL, -1, NULL,
"failed to write %s: %s", tfile, strerror(errno)));
"failed to write %s: %s", tfile,
strerror(dtrace_errno(dtp))));
#endif
if (!dtp->dt_lazyload) {
@ -1846,7 +1845,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
(void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti);
#else
const char *fmt = "%s -o %s -r %s";
const char *fmt = "%s -o %s -r %s %s";
#if defined(__amd64__)
/*
@ -1868,10 +1867,9 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile,
drti) + 1;
len *= 2;
cmd = alloca(len);
(void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file,
(void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile,
drti);
#endif
if ((status = system(cmd)) == -1) {
@ -1894,85 +1892,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
file, dtp->dt_ld_path, WEXITSTATUS(status));
goto done;
}
#if !defined(sun)
/*
* FreeBSD's ld(1) is not instructed to interpret and add
* correctly the SUNW_dof section present in tfile.
* We use libelf to add this section manually and hope the next
* ld invocation won't remove it.
*/
elf_version(EV_CURRENT);
if ((efd = open(file, O_RDWR, 0)) < 0) {
ret = dt_link_error(dtp, NULL, -1, NULL,
"failed to open file %s: %s",
file, strerror(errno));
goto done;
}
if ((e = elf_begin(efd, ELF_C_RDWR, NULL)) == NULL) {
close(efd);
ret = dt_link_error(dtp, NULL, -1, NULL,
"failed to open elf file: %s",
elf_errmsg(elf_errno()));
goto done;
}
/*
* Add the string '.SUWN_dof' to the shstrtab section.
*/
elf_getshdrstrndx(e, &stridx);
scn = elf_getscn(e, stridx);
gelf_getshdr(scn, &shdr);
data = elf_newdata(scn);
data->d_off = shdr.sh_size;
data->d_buf = ".SUNW_dof";
data->d_size = 10;
data->d_type = ELF_T_BYTE;
loc = shdr.sh_size;
shdr.sh_size += data->d_size;
gelf_update_shdr(scn, &shdr);
/*
* Construct the .SUNW_dof section.
*/
scn = elf_newscn(e);
data = elf_newdata(scn);
buf = mmap(NULL, dof->dofh_filesz, PROT_READ, MAP_SHARED,
fd, 0);
if (buf == MAP_FAILED) {
ret = dt_link_error(dtp, NULL, -1, NULL,
"failed to mmap buffer %s", strerror(errno));
elf_end(e);
close(efd);
goto done;
}
data->d_buf = buf;
data->d_align = 4;
data->d_size = dof->dofh_filesz;
data->d_version = EV_CURRENT;
gelf_getshdr(scn, &shdr);
shdr.sh_name = loc;
shdr.sh_flags = SHF_ALLOC;
/*
* Actually this should be SHT_SUNW_dof, but FreeBSD's ld(1)
* will remove this 'unknown' section when we try to create an
* executable using the object we are modifying, so we stop
* playing by the rules and use SHT_PROGBITS.
* Also, note that our drti has modifications to handle this.
*/
shdr.sh_type = SHT_PROGBITS;
shdr.sh_addralign = 4;
gelf_update_shdr(scn, &shdr);
if (elf_update(e, ELF_C_WRITE) < 0) {
ret = dt_link_error(dtp, NULL, -1, NULL,
"failed to add the SUNW_dof section: %s",
elf_errmsg(elf_errno()));
munmap(buf, dof->dofh_filesz);
elf_end(e);
close(efd);
goto done;
}
munmap(buf, dof->dofh_filesz);
elf_end(e);
close(efd);
#endif
(void) close(fd); /* release temporary file */
} else {
(void) close(fd);

View File

@ -29,6 +29,11 @@
#if defined(sun)
#include <sys/modctl.h>
#include <sys/systeminfo.h>
#else
/* FreeBSD */
#include <sys/param.h>
#include <sys/module.h>
#include <sys/linker.h>
#endif
#include <sys/resource.h>

View File

@ -36,6 +36,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
#include <dt_parser.h>

View File

@ -42,6 +42,7 @@
#include <widec.h>
#include "_range.h"
#else
#include <ctype.h>
/* DOODAD */ static int multibyte = 0;
#define WCHAR_CSMASK 0x30000000
#define valid_range(c1, c2) \

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
@ -1426,21 +1426,15 @@ zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile,
elem = NULL;
while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
verify(nvpair_value_nvlist(elem, &src) == 0);
src = fnvpair_value_nvlist(elem);
verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
name = fnvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME);
if (poolname != NULL && strcmp(poolname, name) != 0)
continue;
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0);
if (guid != 0) {
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0);
if (guid != this_guid)
continue;
}
this_guid = fnvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID);
if (guid != 0 && guid != this_guid)
continue;
if (pool_active(hdl, name, this_guid, &active) != 0) {
nvlist_free(raw);

View File

@ -650,6 +650,9 @@ dprintf_setup(int *argc, char **argv)
*/
if (dprintf_find_string("on"))
dprintf_print_all = 1;
if (dprintf_string != NULL)
zfs_flags |= ZFS_DEBUG_DPRINTF;
}
int

View File

@ -43,6 +43,7 @@
#define Pcreate_error strerror
#define Pdelbkpt proc_bkptdel
#define Pgrab_error strerror
#define Plmid(p, a, l) (-1)
#define Plmid_to_map(p, l, o) proc_obj2map((p), (o))
#define Plookup_by_addr proc_addr2sym
#define Pname_to_ctf(p, obj) NULL

View File

@ -541,7 +541,8 @@ EOF
#endif
static bfd_boolean
gld${EMULATION_NAME}_check_ld_elf_hints (const char *name, int force)
gld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
int force)
{
static bfd_boolean initialized;
static char *ld_elf_hints;
@ -584,10 +585,9 @@ gld${EMULATION_NAME}_check_ld_elf_hints (const char *name, int force)
if (ld_elf_hints == NULL)
return FALSE;
needed.by = NULL;
needed.name = name;
return gld${EMULATION_NAME}_search_needed (ld_elf_hints, & needed,
force);
needed.by = l->by;
needed.name = l->name;
return gld${EMULATION_NAME}_search_needed (ld_elf_hints, &needed, force);
}
EOF
# FreeBSD
@ -759,7 +759,8 @@ gld${EMULATION_NAME}_parse_ld_so_conf
}
static bfd_boolean
gld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force)
gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
int force)
{
static bfd_boolean initialized;
static char *ld_so_conf;
@ -794,8 +795,8 @@ gld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force)
return FALSE;
needed.by = NULL;
needed.name = name;
needed.by = l->by;
needed.name = l->name;
return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force);
}
@ -1037,7 +1038,7 @@ if [ "x${USE_LIBPATH}" = xyes ] ; then
case ${target} in
*-*-freebsd* | *-*-dragonfly*)
cat >>e${EMULATION_NAME}.c <<EOF
if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force))
if (gld${EMULATION_NAME}_check_ld_elf_hints (l, force))
break;
EOF
# FreeBSD
@ -1046,7 +1047,7 @@ EOF
*-*-linux-* | *-*-k*bsd*-*)
# Linux
cat >>e${EMULATION_NAME}.c <<EOF
if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
if (gld${EMULATION_NAME}_check_ld_so_conf (l, force))
break;
EOF

View File

@ -0,0 +1,68 @@
.\" Copyright (c) 2014 Microsoft Corp.
.\" 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.
.\"
.Dd September 10, 2013
.Dt HYPER-V 4
.Os
.Sh NAME
.Nm hv_kvp_daemon
.Nd Hyper-V Key Value Pair Daemon
.Sh SYNOPSIS
The \fBhv_kvp_daemon\fP daemon provides the ability to store, retrieve, modify and delete
Key Value pairs for FreeBSD guest partitions running on Hyper-V.
.Sh DESCRIPTION
Hyper-V allows administrators to store custom metadata in the form
of Key Value pairs inside the FreeBSD guest partition. Administrators can
use Windows Powershell scripts to add, read, modify and delete such
Key Value pairs.
The \fBhv_kvp_daemon\fP accepts Key Value pair management requests from the
\fBhv_utils\fP driver and performs the actual metadata management on the file-system.
The same daemon and driver combination is also used to set and get
IP addresses from a FreeBSD guest.
The set functionality is particularly
useful when the FreeBSD guest is assigned a static IP address and is failed
over from one Hyper-V host to another. After failover, Hyper-V uses the set IP
functionality to automatically
update the FreeBSD guest's IP address to its original static value.
On the other hand, the get IP functionality is used to update the guest IP
address in the Hyper-V management console window.
.Sh SEE ALSO
.Xr hv_vmbus 4 ,
.Xr hv_utils 4 ,
.Xr hv_netvsc 4 ,
.Xr hv_storvsc 4 ,
.Xr hv_ata_pci_disengage 4
.Sh HISTORY
Support for Hyper-V in the form of ports was first released in September 2013.
The daemon was developed through a joint effort between Citrix Inc.,
Microsoft Corp. and Network Appliance Inc..
.Sh AUTHORS
.An -nosplit
.Fx
support for \fBhv_kvp_daemon\fP was first added by
.An Microsoft BSD Integration Services Team Aq bsdic@microsoft.com .

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
#!/bin/sh
# This is the script retrieves the DHCP state of a given interface.
# The kvp daemon code invokes this external script to gather
# DHCP setting for the specific interface.
#
# Input: Name of the interface
#
# Output: The script prints the string "Enabled" to stdout to indicate
# that DHCP is enabled on the interface. If DHCP is not enabled,
# the script prints the string "Disabled" to stdout.
#
. /etc/rc.subr
. /etc/network.subr
load_rc_config netif
if dhcpif hn0;
then
echo "Enabled"
else
echo "Disabled"
fi

View File

@ -0,0 +1,12 @@
#!/bin/sh
# This script parses /etc/resolv.conf to retrive DNS information.
# Khe kvp daemon code invokes this external script to gather
# DNS information.
# This script is expected to print the nameserver values to stdout.
#if test -r /etc/resolv.conf
#then
# awk -- '/^nameserver/ { print $2 }' /etc/resolv.conf
#fi
cat /etc/resolv.conf 2>/dev/null | awk '/^nameserver/ { print $2 }'

View File

@ -0,0 +1,73 @@
#!/bin/sh
# This script activates an interface based on the specified
# configuration. The kvp daemon code invokes this external script
# to configure the interface.
#
# The only argument to this script is the configuration file that is to
# be used to configure the interface.
#
# Here is the format of the ip configuration file:
#
# HWADDR=macaddr
# IF_NAME=interface name
# DHCP=yes (This is optional; if yes, DHCP is configured)
#
# IPADDR=ipaddr1
# IPADDR_1=ipaddr2
# IPADDR_x=ipaddry (where y = x + 1)
#
# NETMASK=netmask1
# NETMASK_x=netmasky (where y = x + 1)
#
# GATEWAY=ipaddr1
# GATEWAY_x=ipaddry (where y = x + 1)
#
# DNSx=ipaddrx (where first DNS address is tagged as DNS1 etc)
#
# IPV6 addresses will be tagged as IPV6ADDR, IPV6 gateway will be
# tagged as IPV6_DEFAULTGW and IPV6 NETMASK will be tagged as
# IPV6NETMASK.
#
# The host can specify multiple ipv4 and ipv6 addresses to be
# configured for the interface. Furthermore, the configuration
# needs to be persistent. A subsequent GET call on the interface
# is expected to return the configuration that is set via the SET
# call.
#
. $1
sed -i".bak" '/ifconfig_hn0="SYNCDHCP"/d' /etc/rc.conf
sed -i".bak" '/ifconfig_hn0="DHCP"/d' /etc/rc.conf
# MAC Address
ifconfig $IF_NAME ether $HWADDR
# IP and Subnet Mask
ifconfig $IF_NAME inet $IP_ADDR netmask $SUBNET
# DNS
sed -i".bak" '/nameserver/d' /etc/resolv.conf
echo "nameserver" $DNS >> /etc/resolv.conf
#Gateway
# Need to implment if Gateway is not present
route flush
route add default $GATEWAY
#route change default $GATEWAY
#/etc/rc.d/netif restart
#/etc/rc.d/routing restart
# DHCP
if [ $DHCP -eq 1 ]
then
echo ifconfig_hn0=\"DHCP\" >> /etc/rc.conf
echo Enabled
else
echo Disabled DHCP >> /var/log/messages
echo Disabled
fi
echo "Set IP-Injection Success"

View File

@ -372,6 +372,21 @@ strip_components(const char *p, int elements)
}
}
static const char*
strip_leading_slashes(const char *p)
{
/* Remove leading "/../", "//", etc. */
while (p[0] == '/' || p[0] == '\\') {
if (p[1] == '.' && p[2] == '.' && (
p[3] == '/' || p[3] == '\\')) {
p += 3; /* Remove "/..", leave "/" for next pass. */
} else
p += 1; /* Remove "/". */
}
return (p);
}
/*
* Handle --strip-components and any future path-rewriting options.
* Returns non-zero if the pathname should not be extracted.
@ -474,16 +489,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
p += 2;
slashonly = 0;
}
/* Remove leading "/../", "//", etc. */
while (p[0] == '/' || p[0] == '\\') {
if (p[1] == '.' && p[2] == '.' &&
(p[3] == '/' || p[3] == '\\')) {
p += 3; /* Remove "/..", leave "/"
* for next pass. */
slashonly = 0;
} else
p += 1; /* Remove "/". */
}
p = strip_leading_slashes(p);
} while (rp != p);
if (p != name && !bsdtar->warned_lead_slash) {
@ -504,6 +510,19 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
name = ".";
else
name = p;
p = archive_entry_hardlink(entry);
if (p != NULL) {
rp = strip_leading_slashes(p);
if (rp == '\0')
return (1);
if (rp != p) {
char *linkname = strdup(rp);
archive_entry_copy_hardlink(entry, linkname);
free(linkname);
}
}
} else {
/* Strip redundant leading '/' characters. */
while (name[0] == '/' && name[1] == '/')

View File

@ -301,7 +301,7 @@ template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __is_nullptr_t
#if _LIBCPP_STD_VER > 11
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_null_pointer
: public ____is_nullptr_t<typename remove_cv<_Tp>::type> {};
: public __libcpp___is_nullptr<typename remove_cv<_Tp>::type> {};
#endif
// is_integral

View File

@ -1,4 +1,4 @@
/* $NetBSD: vis.c,v 1.60 2013/02/21 16:21:20 joerg Exp $ */
/* $NetBSD: vis.c,v 1.62 2014/09/08 17:35:01 christos Exp $ */
/*-
* Copyright (c) 1989, 1993
@ -57,7 +57,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: vis.c,v 1.60 2013/02/21 16:21:20 joerg Exp $");
__RCSID("$NetBSD: vis.c,v 1.62 2014/09/08 17:35:01 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#ifdef __FBSDID
__FBSDID("$FreeBSD$");
@ -357,7 +357,7 @@ istrsenvisx(char *mbdst, size_t *dlen, const char *mbsrc, size_t mblength,
ssize_t mbslength, maxolen;
_DIAGASSERT(mbdst != NULL);
_DIAGASSERT(mbsrc != NULL);
_DIAGASSERT(mbsrc != NULL || mblength == 0);
_DIAGASSERT(mbextra != NULL);
/*
@ -375,8 +375,6 @@ istrsenvisx(char *mbdst, size_t *dlen, const char *mbsrc, size_t mblength,
/* Allocate space for the wide char strings */
psrc = pdst = extra = NULL;
if (!mblength)
mblength = strlen(mbsrc);
if ((psrc = calloc(mblength + 1, sizeof(*psrc))) == NULL)
return -1;
if ((pdst = calloc((4 * mblength) + 1, sizeof(*pdst))) == NULL)
@ -528,6 +526,15 @@ out:
free(psrc);
return error;
}
static int
istrsenvisxl(char *mbdst, size_t *dlen, const char *mbsrc,
int flags, const char *mbextra, int *cerr_ptr)
{
return istrsenvisx(mbdst, dlen, mbsrc,
mbsrc != NULL ? strlen(mbsrc) : 0, flags, mbextra, cerr_ptr);
}
#endif
#if !HAVE_SVIS
@ -571,13 +578,13 @@ snvis(char *mbdst, size_t dlen, int c, int flags, int nextc, const char *mbextra
int
strsvis(char *mbdst, const char *mbsrc, int flags, const char *mbextra)
{
return istrsenvisx(mbdst, NULL, mbsrc, 0, flags, mbextra, NULL);
return istrsenvisxl(mbdst, NULL, mbsrc, flags, mbextra, NULL);
}
int
strsnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags, const char *mbextra)
{
return istrsenvisx(mbdst, &dlen, mbsrc, 0, flags, mbextra, NULL);
return istrsenvisxl(mbdst, &dlen, mbsrc, flags, mbextra, NULL);
}
int
@ -646,13 +653,13 @@ nvis(char *mbdst, size_t dlen, int c, int flags, int nextc)
int
strvis(char *mbdst, const char *mbsrc, int flags)
{
return istrsenvisx(mbdst, NULL, mbsrc, 0, flags, "", NULL);
return istrsenvisxl(mbdst, NULL, mbsrc, flags, "", NULL);
}
int
strnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags)
{
return istrsenvisx(mbdst, &dlen, mbsrc, 0, flags, "", NULL);
return istrsenvisxl(mbdst, &dlen, mbsrc, flags, "", NULL);
}
/*

View File

@ -437,6 +437,7 @@ enum {
R_PPC_GOT16_LO = 15,
R_PPC_GOT16_HI = 16,
R_PPC_GOT16_HA = 17,
R_PPC_PLTREL24 = 18,
R_PPC_REL32 = 26,
R_PPC_TLS = 67,
R_PPC_DTPMOD32 = 68,

View File

@ -507,6 +507,7 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_LO);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HI);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HA);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_PLTREL24);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLS);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPMOD32);

View File

@ -3248,7 +3248,8 @@ def : ARMPat<(ARMaddc GPR:$src, imm0_65535_neg:$imm),
def : ARMPat<(ARMadde GPR:$src, so_imm_not:$imm, CPSR),
(SBCri GPR:$src, so_imm_not:$imm)>;
def : ARMPat<(ARMadde GPR:$src, imm0_65535_neg:$imm, CPSR),
(SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>;
(SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>,
Requires<[IsARM, HasV6T2]>;
// Note: These are implemented in C++ code, because they have to generate
// ADD/SUBrs instructions, which use a complex pattern that a xform function

View File

@ -18,6 +18,7 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOpcodes.h"
@ -294,10 +295,16 @@ void PPCInstPrinter::printMemRegReg(const MCInst *MI, unsigned OpNo,
void PPCInstPrinter::printTLSCall(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
printBranchOperand(MI, OpNo, O);
// On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
// come at the _end_ of the expression.
const MCOperand &Op = MI->getOperand(OpNo);
const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*Op.getExpr());
O << refExp.getSymbol().getName();
O << '(';
printOperand(MI, OpNo+1, O);
O << ')';
if (refExp.getKind() != MCSymbolRefExpr::VK_None)
O << '@' << MCSymbolRefExpr::getVariantKindName(refExp.getKind());
}

View File

@ -64,7 +64,15 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
llvm_unreachable("Unimplemented");
case PPC::fixup_ppc_br24:
case PPC::fixup_ppc_br24abs:
Type = ELF::R_PPC_REL24;
switch (Modifier) {
default: llvm_unreachable("Unsupported Modifier");
case MCSymbolRefExpr::VK_None:
Type = ELF::R_PPC_REL24;
break;
case MCSymbolRefExpr::VK_PLT:
Type = ELF::R_PPC_PLTREL24;
break;
}
break;
case PPC::fixup_ppc_brcond14:
case PPC::fixup_ppc_brcond14abs:
@ -205,7 +213,10 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
break;
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
Type = ELF::R_PPC64_GOT_TLSGD16;
if (is64Bit())
Type = ELF::R_PPC64_GOT_TLSGD16;
else
Type = ELF::R_PPC_GOT_TLSGD16;
break;
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
Type = ELF::R_PPC64_GOT_TLSGD16_LO;
@ -217,7 +228,10 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
Type = ELF::R_PPC64_GOT_TLSGD16_HA;
break;
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
Type = ELF::R_PPC64_GOT_TLSLD16;
if (is64Bit())
Type = ELF::R_PPC64_GOT_TLSLD16;
else
Type = ELF::R_PPC_GOT_TLSLD16;
break;
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
Type = ELF::R_PPC64_GOT_TLSLD16_LO;
@ -313,13 +327,22 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
switch (Modifier) {
default: llvm_unreachable("Unsupported Modifier");
case MCSymbolRefExpr::VK_PPC_TLSGD:
Type = ELF::R_PPC64_TLSGD;
if (is64Bit())
Type = ELF::R_PPC64_TLSGD;
else
Type = ELF::R_PPC_TLSGD;
break;
case MCSymbolRefExpr::VK_PPC_TLSLD:
Type = ELF::R_PPC64_TLSLD;
if (is64Bit())
Type = ELF::R_PPC64_TLSLD;
else
Type = ELF::R_PPC_TLSLD;
break;
case MCSymbolRefExpr::VK_PPC_TLS:
Type = ELF::R_PPC64_TLS;
if (is64Bit())
Type = ELF::R_PPC64_TLS;
else
Type = ELF::R_PPC_TLS;
break;
}
break;

View File

@ -53,10 +53,11 @@ namespace llvm {
// PPC Specific MachineOperand flags.
MO_NO_FLAG,
/// MO_DARWIN_STUB - On a symbol operand "FOO", this indicates that the
/// reference is actually to the "FOO$stub" symbol. This is used for calls
/// and jumps to external functions on Tiger and earlier.
MO_DARWIN_STUB = 1,
/// MO_PLT_OR_STUB - On a symbol operand "FOO", this indicates that the
/// reference is actually to the "FOO$stub" or "FOO@plt" symbol. This is
/// used for calls and jumps to external functions on Tiger and earlier, and
/// for PIC calls on Linux and ELF systems.
MO_PLT_OR_STUB = 1,
/// MO_PIC_FLAG - If this bit is set, the symbol reference is relative to
/// the function's picbase, e.g. lo16(symbol-picbase).

View File

@ -19,6 +19,7 @@
#define DEBUG_TYPE "asmprinter"
#include "PPC.h"
#include "InstPrinter/PPCInstPrinter.h"
#include "PPCMachineFunctionInfo.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "MCTargetDesc/PPCMCExpr.h"
#include "PPCSubtarget.h"
@ -29,6 +30,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@ -100,6 +102,7 @@ namespace {
}
bool doFinalization(Module &M);
void EmitStartOfAsmFile(Module &M);
virtual void EmitFunctionEntryLabel();
@ -325,6 +328,7 @@ MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
///
void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst TmpInst;
bool isPPC64 = Subtarget.isPPC64();
// Lower multi-instruction pseudo operations.
switch (MI->getOpcode()) {
@ -349,6 +353,66 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitLabel(PICBase);
return;
}
case PPC::GetGBRO: {
// Get the offset from the GOT Base Register to the GOT
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
MCSymbol *PICOffset = MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
TmpInst.setOpcode(PPC::LWZ);
const MCExpr *Exp =
MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
const MCExpr *PB =
MCSymbolRefExpr::Create(MF->getPICBaseSymbol(),
MCSymbolRefExpr::VK_None,
OutContext);
const MCOperand MO = TmpInst.getOperand(1);
TmpInst.getOperand(1) = MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp,
PB,
OutContext));
TmpInst.addOperand(MO);
OutStreamer.EmitInstruction(TmpInst);
return;
}
case PPC::UpdateGBR: {
// Update the GOT Base Register to point to the GOT. It may be possible to
// merge this with the PPC::GetGBRO, doing it all in one step.
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
TmpInst.setOpcode(PPC::ADD4);
TmpInst.addOperand(TmpInst.getOperand(0));
OutStreamer.EmitInstruction(TmpInst);
return;
}
case PPC::LWZtoc: {
// Transform %X3 = LWZtoc <ga:@min1>, %X2
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
// Change the opcode to LWZ, and the global address operand to be a
// reference to the GOT entry we will synthesize later.
TmpInst.setOpcode(PPC::LWZ);
const MachineOperand &MO = MI->getOperand(1);
// Map symbol -> label of TOC entry
assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
MCSymbol *MOSymbol = NULL;
if (MO.isGlobal())
MOSymbol = getSymbol(MO.getGlobal());
else if (MO.isCPI())
MOSymbol = GetCPISymbol(MO.getIndex());
else if (MO.isJTI())
MOSymbol = GetJTISymbol(MO.getIndex());
MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
const MCExpr *Exp =
MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None,
OutContext);
const MCExpr *PB =
MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
OutContext);
Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext);
TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
OutStreamer.EmitInstruction(TmpInst);
return;
}
case PPC::LDtocJTI:
case PPC::LDtocCPT:
case PPC::LDtoc: {
@ -518,12 +582,13 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
.addExpr(SymGotTprel));
return;
}
case PPC::LDgotTprelL: {
case PPC::LDgotTprelL:
case PPC::LDgotTprelL32: {
// Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
// Change the opcode to LD.
TmpInst.setOpcode(PPC::LD);
TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
const MachineOperand &MO = MI->getOperand(1);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
@ -534,6 +599,52 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitInstruction(TmpInst);
return;
}
case PPC::PPC32PICGOT: {
MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
MCSymbol *GOTRef = OutContext.CreateTempSymbol();
MCSymbol *NextInstr = OutContext.CreateTempSymbol();
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL)
// FIXME: We would like an efficient form for this, so we don't have to do
// a lot of extra uniquing.
.addExpr(MCSymbolRefExpr::Create(NextInstr, OutContext)));
const MCExpr *OffsExpr =
MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, OutContext),
MCSymbolRefExpr::Create(GOTRef, OutContext),
OutContext);
OutStreamer.EmitLabel(GOTRef);
OutStreamer.EmitValue(OffsExpr, 4);
OutStreamer.EmitLabel(NextInstr);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR)
.addReg(MI->getOperand(0).getReg()));
OutStreamer.EmitInstruction(MCInstBuilder(PPC::LWZ)
.addReg(MI->getOperand(1).getReg())
.addImm(0)
.addReg(MI->getOperand(0).getReg()));
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADD4)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(1).getReg())
.addReg(MI->getOperand(0).getReg()));
return;
}
case PPC::PPC32GOT: {
MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
const MCExpr *SymGotTlsL =
MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO,
OutContext);
const MCExpr *SymGotTlsHA =
MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA,
OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::LI)
.addReg(MI->getOperand(0).getReg())
.addExpr(SymGotTlsL));
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(0).getReg())
.addExpr(SymGotTlsHA));
return;
}
case PPC::ADDIStlsgdHA: {
// Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
// Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
@ -550,38 +661,50 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
.addExpr(SymGotTlsGD));
return;
}
case PPC::ADDItlsgdL: {
case PPC::ADDItlsgdL:
// Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
// Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
case PPC::ADDItlsgdL32: {
// Transform: %Rd = ADDItlsgdL32 %Rs, <ga:@sym>
// Into: %Rd = ADDI %Rs, sym@got@tlsgd
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymGotTlsGD =
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO,
MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ?
MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO :
MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(1).getReg())
.addExpr(SymGotTlsGD));
OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(1).getReg())
.addExpr(SymGotTlsGD));
return;
}
case PPC::GETtlsADDR: {
case PPC::GETtlsADDR:
// Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
// Into: BL8_NOP_TLS __tls_get_addr(sym@tlsgd)
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
case PPC::GETtlsADDR32: {
// Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym>
// Into: BL_TLS __tls_get_addr(sym@tlsgd)@PLT
StringRef Name = "__tls_get_addr";
MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
TM.getRelocationModel() == Reloc::PIC_)
Kind = MCSymbolRefExpr::VK_PLT;
const MCSymbolRefExpr *TlsRef =
MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymVar =
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ?
PPC::BL8_NOP_TLS : PPC::BL_TLS)
.addExpr(TlsRef)
.addExpr(SymVar));
return;
@ -602,69 +725,88 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
.addExpr(SymGotTlsLD));
return;
}
case PPC::ADDItlsldL: {
case PPC::ADDItlsldL:
// Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
// Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
case PPC::ADDItlsldL32: {
// Transform: %Rd = ADDItlsldL32 %Rs, <ga:@sym>
// Into: %Rd = ADDI %Rs, sym@got@tlsld
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymGotTlsLD =
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO,
MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ?
MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO :
MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(1).getReg())
.addExpr(SymGotTlsLD));
return;
}
case PPC::GETtlsldADDR: {
case PPC::GETtlsldADDR:
// Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
// Into: BL8_NOP_TLS __tls_get_addr(sym@tlsld)
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
case PPC::GETtlsldADDR32: {
// Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym>
// Into: BL_TLS __tls_get_addr(sym@tlsld)@PLT
StringRef Name = "__tls_get_addr";
MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
TM.getRelocationModel() == Reloc::PIC_)
Kind = MCSymbolRefExpr::VK_PLT;
const MCSymbolRefExpr *TlsRef =
MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymVar =
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ?
PPC::BL8_NOP_TLS : PPC::BL_TLS)
.addExpr(TlsRef)
.addExpr(SymVar));
return;
}
case PPC::ADDISdtprelHA: {
case PPC::ADDISdtprelHA:
// Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
// Into: %Xd = ADDIS8 %X3, sym@dtprel@ha
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
case PPC::ADDISdtprelHA32: {
// Transform: %Rd = ADDISdtprelHA32 %R3, <ga:@sym>
// Into: %Rd = ADDIS %R3, sym@dtprel@ha
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymDtprel =
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDIS8 : PPC::ADDIS)
.addReg(MI->getOperand(0).getReg())
.addReg(PPC::X3)
.addExpr(SymDtprel));
return;
}
case PPC::ADDIdtprelL: {
case PPC::ADDIdtprelL:
// Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
// Into: %Xd = ADDI8 %Xs, sym@dtprel@l
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
case PPC::ADDIdtprelL32: {
// Transform: %Rd = ADDIdtprelL32 %Rs, <ga:@sym>
// Into: %Rd = ADDI %Rs, sym@dtprel@l
const MachineOperand &MO = MI->getOperand(2);
const GlobalValue *GValue = MO.getGlobal();
MCSymbol *MOSymbol = getSymbol(GValue);
const MCExpr *SymDtprel =
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
OutContext);
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(1).getReg())
.addExpr(SymDtprel));
@ -726,9 +868,60 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitInstruction(TmpInst);
}
void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_)
return AsmPrinter::EmitStartOfAsmFile(M);
// FIXME: The use of .got2 assumes large GOT model (-fPIC), which is not
// optimal for some cases. We should consider supporting small model (-fpic)
// as well in the future.
assert(TM.getCodeModel() != CodeModel::Small &&
"Small code model PIC is currently unsupported.");
OutStreamer.SwitchSection(OutContext.getELFSection(".got2",
ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
SectionKind::getReadOnly()));
MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC."));
MCSymbol *CurrentPos = OutContext.CreateTempSymbol();
OutStreamer.EmitLabel(CurrentPos);
// The GOT pointer points to the middle of the GOT, in order to reference the
// entire 64kB range. 0x8000 is the midpoint.
const MCExpr *tocExpr =
MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos, OutContext),
MCConstantExpr::Create(0x8000, OutContext),
OutContext);
OutStreamer.EmitAssignment(TOCSym, tocExpr);
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
}
void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label.
// linux/ppc32 - Normal entry label.
if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_)
return AsmPrinter::EmitFunctionEntryLabel();
if (!Subtarget.isPPC64()) {
const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
if (PPCFI->usesPICBase()) {
MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
MCSymbol *PICBase = MF->getPICBaseSymbol();
OutStreamer.EmitLabel(RelocSymbol);
const MCExpr *OffsExpr =
MCBinaryExpr::CreateSub(
MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
OutContext),
MCSymbolRefExpr::Create(PICBase, OutContext),
OutContext);
OutStreamer.EmitValue(OffsExpr, 4);
OutStreamer.EmitLabel(CurrentFnSym);
return;
} else
return AsmPrinter::EmitFunctionEntryLabel();
}
// Emit an official procedure descriptor.
MCSectionSubPair Current = OutStreamer.getCurrentSection();
@ -768,8 +961,15 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
PPCTargetStreamer &TS =
static_cast<PPCTargetStreamer &>(OutStreamer.getTargetStreamer());
if (isPPC64 && !TOC.empty()) {
const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
if (!TOC.empty()) {
const MCSectionELF *Section;
if (isPPC64)
Section = OutStreamer.getContext().getELFSection(".toc",
ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
SectionKind::getReadOnly());
else
Section = OutStreamer.getContext().getELFSection(".got2",
ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
SectionKind::getReadOnly());
OutStreamer.SwitchSection(Section);
@ -778,7 +978,10 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
E = TOC.end(); I != E; ++I) {
OutStreamer.EmitLabel(I->second);
MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
TS.emitTCEntry(*S);
if (isPPC64)
TS.emitTCEntry(*S);
else
OutStreamer.EmitSymbolValue(S, 4);
}
}

View File

@ -299,7 +299,7 @@ void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const {
const PPCRegisterInfo *RegInfo =
static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo());
bool HasBP = RegInfo->hasBasePointer(MF);
unsigned BPReg = HasBP ? (unsigned) PPC::R30 : FPReg;
unsigned BPReg = HasBP ? (unsigned) RegInfo->getBaseRegister(MF): FPReg;
unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FPReg;
for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
@ -344,6 +344,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
DebugLoc dl;
bool needsFrameMoves = MMI.hasDebugInfo() ||
MF.getFunction()->needsUnwindTableEntry();
bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_;
// Get processor type.
bool isPPC64 = Subtarget.isPPC64();
@ -387,7 +388,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
bool HasBP = RegInfo->hasBasePointer(MF);
unsigned SPReg = isPPC64 ? PPC::X1 : PPC::R1;
unsigned BPReg = isPPC64 ? PPC::X30 : PPC::R30;
unsigned BPReg = RegInfo->getBaseRegister(MF);
unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31;
unsigned LRReg = isPPC64 ? PPC::LR8 : PPC::LR;
unsigned ScratchReg = isPPC64 ? PPC::X0 : PPC::R0;
@ -442,7 +443,9 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
BPOffset = FFI->getObjectOffset(BPIndex);
} else {
BPOffset =
PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI);
PPCFrameLowering::getBasePointerSaveOffset(isPPC64,
isDarwinABI,
isPIC);
}
}
@ -675,6 +678,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
// Get the ABI.
bool isDarwinABI = Subtarget.isDarwinABI();
bool isSVR4ABI = Subtarget.isSVR4ABI();
bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_;
// Check if the link register (LR) has been saved.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
@ -685,7 +689,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
bool HasBP = RegInfo->hasBasePointer(MF);
unsigned SPReg = isPPC64 ? PPC::X1 : PPC::R1;
unsigned BPReg = isPPC64 ? PPC::X30 : PPC::R30;
unsigned BPReg = RegInfo->getBaseRegister(MF);
unsigned FPReg = isPPC64 ? PPC::X31 : PPC::R31;
unsigned ScratchReg = isPPC64 ? PPC::X0 : PPC::R0;
unsigned TempReg = isPPC64 ? PPC::X12 : PPC::R12; // another scratch reg
@ -725,7 +729,9 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
BPOffset = FFI->getObjectOffset(BPIndex);
} else {
BPOffset =
PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI);
PPCFrameLowering::getBasePointerSaveOffset(isPPC64,
isDarwinABI,
isPIC);
}
}
@ -902,6 +908,7 @@ PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
int FPSI = FI->getFramePointerSaveIndex();
bool isPPC64 = Subtarget.isPPC64();
bool isDarwinABI = Subtarget.isDarwinABI();
bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_;
MachineFrameInfo *MFI = MF.getFrameInfo();
// If the frame pointer save index hasn't been defined yet.
@ -916,7 +923,7 @@ PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
int BPSI = FI->getBasePointerSaveIndex();
if (!BPSI && RegInfo->hasBasePointer(MF)) {
int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI);
int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI, isPIC);
// Allocate the frame index for the base pointer save area.
BPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, BPOffset, true);
// Save the result.

View File

@ -96,12 +96,14 @@ public:
/// getBasePointerSaveOffset - Return the previous frame offset to save the
/// base pointer.
static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI) {
static unsigned getBasePointerSaveOffset(bool isPPC64,
bool isDarwinABI,
bool isPIC) {
if (isDarwinABI)
return isPPC64 ? -16U : -8U;
// SVR4 ABI: First slot in the general register save area.
return isPPC64 ? -16U : -8U;
return isPPC64 ? -16U : isPIC ? -12U : -8U;
}
/// getLinkageSize - Return the size of the PowerPC ABI linkage area.

View File

@ -15,6 +15,7 @@
#define DEBUG_TYPE "ppc-codegen"
#include "PPC.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "PPCMachineFunctionInfo.h"
#include "PPCTargetMachine.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@ -261,9 +262,21 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
DebugLoc dl;
if (PPCLowering.getPointerTy() == MVT::i32) {
GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass);
if (PPCSubTarget.isTargetELF())
GlobalBaseReg = PPC::R30;
else
GlobalBaseReg =
RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass);
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR));
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
if (PPCSubTarget.isTargetELF()) {
unsigned TempReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
BuildMI(FirstMBB, MBBI, dl,
TII.get(PPC::GetGBRO), TempReg).addReg(GlobalBaseReg);
BuildMI(FirstMBB, MBBI, dl,
TII.get(PPC::UpdateGBR)).addReg(GlobalBaseReg).addReg(TempReg);
MF->getInfo<PPCFunctionInfo>()->setUsesPICBase(true);
}
} else {
GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_NOX0RegClass);
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR8));
@ -1260,7 +1273,13 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
return CurDAG->SelectNodeTo(N, Reg, MVT::Other, Chain);
}
case PPCISD::TOC_ENTRY: {
assert (PPCSubTarget.isPPC64() && "Only supported for 64-bit ABI");
if (PPCSubTarget.isSVR4ABI() && !PPCSubTarget.isPPC64()) {
SDValue GA = N->getOperand(0);
return CurDAG->getMachineNode(PPC::LWZtoc, dl, MVT::i32, GA,
N->getOperand(1));
}
assert (PPCSubTarget.isPPC64() &&
"Only supported for 64-bit ABI and 32-bit SVR4");
// For medium and large code model, we generate two instructions as
// described below. Otherwise we allow SelectCodeCommon to handle this,
@ -1306,6 +1325,12 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
return CurDAG->getMachineNode(PPC::ADDItocL, dl, MVT::i64,
SDValue(Tmp, 0), GA);
}
case PPCISD::PPC32_PICGOT: {
// Generate a PIC-safe GOT reference.
assert(!PPCSubTarget.isPPC64() && PPCSubTarget.isSVR4ABI() &&
"PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
return CurDAG->SelectNodeTo(N, PPC::PPC32PICGOT, PPCLowering.getPointerTy(), MVT::i32);
}
case PPCISD::VADD_SPLAT: {
// This expands into one of three sequences, depending on whether
// the first operand is odd or even, positive or negative.

View File

@ -670,6 +670,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
case PPCISD::ADDIS_TOC_HA: return "PPCISD::ADDIS_TOC_HA";
case PPCISD::LD_TOC_L: return "PPCISD::LD_TOC_L";
case PPCISD::ADDI_TOC_L: return "PPCISD::ADDI_TOC_L";
case PPCISD::PPC32_GOT: return "PPCISD::PPC32_GOT";
case PPCISD::ADDIS_GOT_TPREL_HA: return "PPCISD::ADDIS_GOT_TPREL_HA";
case PPCISD::LD_GOT_TPREL_L: return "PPCISD::LD_GOT_TPREL_L";
case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS";
@ -1307,10 +1308,7 @@ static bool GetLabelAccessInfo(const TargetMachine &TM, unsigned &HiOpFlags,
HiOpFlags = PPCII::MO_HA;
LoOpFlags = PPCII::MO_LO;
// Don't use the pic base if not in PIC relocation model. Or if we are on a
// non-darwin platform. We don't support PIC on other platforms yet.
bool isPIC = TM.getRelocationModel() == Reloc::PIC_ &&
TM.getSubtarget<PPCSubtarget>().isDarwin();
bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
if (isPIC) {
HiOpFlags |= PPCII::MO_PIC_FLAG;
LoOpFlags |= PPCII::MO_PIC_FLAG;
@ -1366,6 +1364,15 @@ SDValue PPCTargetLowering::LowerConstantPool(SDValue Op,
unsigned MOHiFlag, MOLoFlag;
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
if (isPIC && PPCSubTarget.isSVR4ABI()) {
SDValue GA = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(),
PPCII::MO_PIC_FLAG);
SDLoc DL(CP);
return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(CP), MVT::i32, GA,
DAG.getNode(PPCISD::GlobalBaseReg, DL, PtrVT));
}
SDValue CPIHi =
DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0, MOHiFlag);
SDValue CPILo =
@ -1387,6 +1394,15 @@ SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
unsigned MOHiFlag, MOLoFlag;
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
if (isPIC && PPCSubTarget.isSVR4ABI()) {
SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT,
PPCII::MO_PIC_FLAG);
SDLoc DL(GA);
return DAG.getNode(PPCISD::TOC_ENTRY, SDLoc(JT), PtrVT, GA,
DAG.getNode(PPCISD::GlobalBaseReg, DL, PtrVT));
}
SDValue JTIHi = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOHiFlag);
SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOLoFlag);
return LowerLabelRef(JTIHi, JTILo, isPIC, DAG);
@ -1400,6 +1416,7 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op,
unsigned MOHiFlag, MOLoFlag;
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
SDValue TgtBAHi = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOHiFlag);
SDValue TgtBALo = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOLoFlag);
return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
@ -1431,64 +1448,79 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
return DAG.getNode(PPCISD::Lo, dl, PtrVT, TGALo, Hi);
}
if (!is64bit)
llvm_unreachable("only local-exec is currently supported for ppc32");
if (Model == TLSModel::InitialExec) {
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
SDValue TGATLS = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
PPCII::MO_TLS);
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
SDValue TPOffsetHi = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl,
PtrVT, GOTReg, TGA);
SDValue GOTPtr;
if (is64bit) {
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
GOTPtr = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl,
PtrVT, GOTReg, TGA);
} else
GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl,
PtrVT, TGA, TPOffsetHi);
PtrVT, TGA, GOTPtr);
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
}
if (Model == TLSModel::GeneralDynamic) {
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
SDValue GOTEntryHi = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
GOTReg, TGA);
SDValue GOTPtr;
if (is64bit) {
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
GOTReg, TGA);
} else {
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
}
SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT,
GOTEntryHi, TGA);
GOTPtr, TGA);
// We need a chain node, and don't have one handy. The underlying
// call has no side effects, so using the function entry node
// suffices.
SDValue Chain = DAG.getEntryNode();
Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, GOTEntry);
SDValue ParmReg = DAG.getRegister(PPC::X3, MVT::i64);
Chain = DAG.getCopyToReg(Chain, dl,
is64bit ? PPC::X3 : PPC::R3, GOTEntry);
SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
is64bit ? MVT::i64 : MVT::i32);
SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLS_ADDR, dl,
PtrVT, ParmReg, TGA);
// The return value from GET_TLS_ADDR really is in X3 already, but
// some hacks are needed here to tie everything together. The extra
// copies dissolve during subsequent transforms.
Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, TLSAddr);
return DAG.getCopyFromReg(Chain, dl, PPC::X3, PtrVT);
Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
return DAG.getCopyFromReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, PtrVT);
}
if (Model == TLSModel::LocalDynamic) {
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
SDValue GOTEntryHi = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
GOTReg, TGA);
SDValue GOTPtr;
if (is64bit) {
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
GOTPtr = DAG.getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
GOTReg, TGA);
} else {
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
}
SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT,
GOTEntryHi, TGA);
GOTPtr, TGA);
// We need a chain node, and don't have one handy. The underlying
// call has no side effects, so using the function entry node
// suffices.
SDValue Chain = DAG.getEntryNode();
Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, GOTEntry);
SDValue ParmReg = DAG.getRegister(PPC::X3, MVT::i64);
Chain = DAG.getCopyToReg(Chain, dl,
is64bit ? PPC::X3 : PPC::R3, GOTEntry);
SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
is64bit ? MVT::i64 : MVT::i32);
SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLSLD_ADDR, dl,
PtrVT, ParmReg, TGA);
// The return value from GET_TLSLD_ADDR really is in X3 already, but
// some hacks are needed here to tie everything together. The extra
// copies dissolve during subsequent transforms.
Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, TLSAddr);
Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
SDValue DtvOffsetHi = DAG.getNode(PPCISD::ADDIS_DTPREL_HA, dl, PtrVT,
Chain, ParmReg, TGA);
return DAG.getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
@ -1515,6 +1547,14 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
unsigned MOHiFlag, MOLoFlag;
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag, GV);
if (isPIC && PPCSubTarget.isSVR4ABI()) {
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT,
GSDN->getOffset(),
PPCII::MO_PIC_FLAG);
return DAG.getNode(PPCISD::TOC_ENTRY, DL, MVT::i32, GA,
DAG.getNode(PPCISD::GlobalBaseReg, DL, MVT::i32));
}
SDValue GAHi =
DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset(), MOHiFlag);
SDValue GALo =
@ -3214,15 +3254,18 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
// far-call stubs may be outside relocation limits for a BL instruction.
if (!DAG.getTarget().getSubtarget<PPCSubtarget>().isJITCodeModel()) {
unsigned OpFlags = 0;
if (DAG.getTarget().getRelocationModel() != Reloc::Static &&
if ((DAG.getTarget().getRelocationModel() != Reloc::Static &&
(PPCSubTarget.getTargetTriple().isMacOSX() &&
PPCSubTarget.getTargetTriple().isMacOSXVersionLT(10, 5)) &&
(G->getGlobal()->isDeclaration() ||
G->getGlobal()->isWeakForLinker())) {
G->getGlobal()->isWeakForLinker())) ||
(PPCSubTarget.isTargetELF() && !isPPC64 &&
!G->getGlobal()->hasLocalLinkage() &&
DAG.getTarget().getRelocationModel() == Reloc::PIC_)) {
// PC-relative references to external symbols should go through $stub,
// unless we're building with the leopard linker or later, which
// automatically synthesizes these stubs.
OpFlags = PPCII::MO_DARWIN_STUB;
OpFlags = PPCII::MO_PLT_OR_STUB;
}
// If the callee is a GlobalAddress/ExternalSymbol node (quite common,
@ -3244,7 +3287,7 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
// PC-relative references to external symbols should go through $stub,
// unless we're building with the leopard linker or later, which
// automatically synthesizes these stubs.
OpFlags = PPCII::MO_DARWIN_STUB;
OpFlags = PPCII::MO_PLT_OR_STUB;
}
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType(),
@ -6255,7 +6298,10 @@ PPCTargetLowering::emitEHSjLjLongJmp(MachineInstr *MI,
// Since FP is only updated here but NOT referenced, it's treated as GPR.
unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
unsigned BP = (PVT == MVT::i64) ? PPC::X30 : PPC::R30;
unsigned BP = (PVT == MVT::i64) ? PPC::X30 :
(PPCSubTarget.isSVR4ABI() &&
MF->getTarget().getRelocationModel() == Reloc::PIC_ ?
PPC::R29 : PPC::R30);
MachineInstrBuilder MIB;

View File

@ -177,6 +177,12 @@ namespace llvm {
CR6SET,
CR6UNSET,
PPC32_GOT,
/// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and
/// local dynamic TLS on PPC32.
PPC32_PICGOT,
/// G8RC = ADDIS_GOT_TPREL_HA %X2, Symbol - Used by the initial-exec
/// TLS model, produces an ADDIS8 instruction that adds the GOT
/// base to sym\@got\@tprel\@ha.

View File

@ -36,10 +36,6 @@ def s17imm64 : Operand<i64> {
def tocentry : Operand<iPTR> {
let MIOperandInfo = (ops i64imm:$imm);
}
def PPCTLSRegOperand : AsmOperandClass {
let Name = "TLSReg"; let PredicateMethod = "isTLSReg";
let RenderMethod = "addTLSRegOperands";
}
def tlsreg : Operand<i64> {
let EncoderMethod = "getTLSRegEncoding";
let ParserMatchClass = PPCTLSRegOperand;

View File

@ -57,6 +57,9 @@ def SDT_PPCTC_ret : SDTypeProfile<0, 2, [
SDTCisPtrTy<0>, SDTCisVT<1, i32>
]>;
def tocentry32 : Operand<iPTR> {
let MIOperandInfo = (ops i32imm:$imm);
}
//===----------------------------------------------------------------------===//
// PowerPC specific DAG Nodes.
@ -99,6 +102,8 @@ def PPCtoc_entry: SDNode<"PPCISD::TOC_ENTRY", SDTIntBinOp, [SDNPMayLoad]>;
def PPCvmaddfp : SDNode<"PPCISD::VMADDFP", SDTFPTernaryOp, []>;
def PPCvnmsubfp : SDNode<"PPCISD::VNMSUBFP", SDTFPTernaryOp, []>;
def PPCppc32GOT : SDNode<"PPCISD::PPC32_GOT", SDTIntLeaf, []>;
def PPCaddisGotTprelHA : SDNode<"PPCISD::ADDIS_GOT_TPREL_HA", SDTIntBinOp>;
def PPCldGotTprelL : SDNode<"PPCISD::LD_GOT_TPREL_L", SDTIntBinOp,
[SDNPMayLoad]>;
@ -555,6 +560,20 @@ def memrix : Operand<iPTR> { // memri where the imm is 4-aligned.
def memr : Operand<iPTR> {
let MIOperandInfo = (ops ptr_rc:$ptrreg);
}
def PPCTLSRegOperand : AsmOperandClass {
let Name = "TLSReg"; let PredicateMethod = "isTLSReg";
let RenderMethod = "addTLSRegOperands";
}
def tlsreg32 : Operand<i32> {
let EncoderMethod = "getTLSRegEncoding";
let ParserMatchClass = PPCTLSRegOperand;
}
def tlsgd32 : Operand<i32> {}
def tlscall32 : Operand<i32> {
let PrintMethod = "printTLSCall";
let MIOperandInfo = (ops calltarget:$func, tlsgd32:$sym);
let EncoderMethod = "getTLSCallEncoding";
}
// PowerPC Predicate operand.
def pred : Operand<OtherVT> {
@ -1003,6 +1022,8 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR] in {
"bla $func", BrB, [(PPCcall (i32 imm:$func))]>;
let isCodeGenOnly = 1 in {
def BL_TLS : IForm<18, 0, 1, (outs), (ins tlscall32:$func),
"bl $func", BrB, []>;
def BCCL : BForm<16, 0, 1, (outs), (ins pred:$cond, condbrtarget:$dst),
"b${cond:cc}l${cond:pm} ${cond:reg}, $dst">;
def BCCLA : BForm<16, 1, 1, (outs), (ins pred:$cond, abscondbrtarget:$dst),
@ -1995,6 +2016,10 @@ let PPC970_Unit = 1, neverHasSideEffects = 1 in { // FXU Operations.
defm ADD4 : XOForm_1r<31, 266, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
"add", "$rT, $rA, $rB", IntSimple,
[(set i32:$rT, (add i32:$rA, i32:$rB))]>;
let isCodeGenOnly = 1 in
def ADD4TLS : XOForm_1<31, 266, 0, (outs gprc:$rT), (ins gprc:$rA, tlsreg32:$rB),
"add $rT, $rA, $rB", IntSimple,
[(set i32:$rT, (add i32:$rA, tglobaltlsaddr:$rB))]>;
defm ADDC : XOForm_1rc<31, 10, 0, (outs gprc:$rT), (ins gprc:$rA, gprc:$rB),
"addc", "$rT, $rA, $rB", IntGeneral,
[(set i32:$rT, (addc i32:$rA, i32:$rB))]>,
@ -2260,6 +2285,61 @@ def : Pat<(add i32:$in, (PPChi tjumptable:$g, 0)),
def : Pat<(add i32:$in, (PPChi tblockaddress:$g, 0)),
(ADDIS $in, tblockaddress:$g)>;
// Support for Position-independent code
def LWZtoc: Pseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg),
"#LWZtoc",
[(set i32:$rD,
(PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
// Get Global (GOT) Base Register offset, from the word immediately preceding
// the function label.
def GetGBRO: Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#GetGBRO", []>;
// Update the Global(GOT) Base Register with the above offset.
def UpdateGBR: Pseudo<(outs gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>;
// Support for thread-local storage.
def PPC32GOT: Pseudo<(outs gprc:$rD), (ins), "#PPC32GOT",
[(set i32:$rD, (PPCppc32GOT))]>;
// Get the _GLOBAL_OFFSET_TABLE_ in PIC mode.
// This uses two output registers, the first as the real output, the second as a
// temporary register, used internally in code generation.
def PPC32PICGOT: Pseudo<(outs gprc:$rD, gprc:$rT), (ins), "#PPC32PICGOT",
[]>, NoEncode<"$rT">;
def LDgotTprelL32: Pseudo<(outs gprc:$rD), (ins s16imm:$disp, gprc_nor0:$reg),
"#LDgotTprelL32",
[(set i32:$rD,
(PPCldGotTprelL tglobaltlsaddr:$disp, i32:$reg))]>;
def : Pat<(PPCaddTls i32:$in, tglobaltlsaddr:$g),
(ADD4TLS $in, tglobaltlsaddr:$g)>;
def ADDItlsgdL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
"#ADDItlsgdL32",
[(set i32:$rD,
(PPCaddiTlsgdL i32:$reg, tglobaltlsaddr:$disp))]>;
def GETtlsADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
"#GETtlsADDR32",
[(set i32:$rD,
(PPCgetTlsAddr i32:$reg, tglobaltlsaddr:$sym))]>;
def ADDItlsldL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
"#ADDItlsldL32",
[(set i32:$rD,
(PPCaddiTlsldL i32:$reg, tglobaltlsaddr:$disp))]>;
def GETtlsldADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
"#GETtlsldADDR32",
[(set i32:$rD,
(PPCgetTlsldAddr i32:$reg, tglobaltlsaddr:$sym))]>;
def ADDIdtprelL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
"#ADDIdtprelL32",
[(set i32:$rD,
(PPCaddiDtprelL i32:$reg, tglobaltlsaddr:$disp))]>;
def ADDISdtprelHA32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
"#ADDISdtprelHA32",
[(set i32:$rD,
(PPCaddisDtprelHA i32:$reg,
tglobaltlsaddr:$disp))]>;
// Standard shifts. These are represented separately from the real shifts above
// so that we can distinguish between shifts that allow 5-bit and 6-bit shift
// amounts.

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "PPC.h"
#include "PPCSubtarget.h"
#include "MCTargetDesc/PPCMCExpr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
@ -24,6 +25,7 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) {
@ -32,7 +34,9 @@ static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) {
static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){
const TargetMachine &TM = AP.TM;
MCContext &Ctx = AP.OutContext;
bool isDarwin = TM.getSubtarget<PPCSubtarget>().isDarwin();
SmallString<128> Name;
if (!MO.isGlobal()) {
@ -42,7 +46,7 @@ static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){
} else {
const GlobalValue *GV = MO.getGlobal();
bool isImplicitlyPrivate = false;
if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB ||
if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB ||
(MO.getTargetFlags() & PPCII::MO_NLP_FLAG))
isImplicitlyPrivate = true;
@ -51,7 +55,7 @@ static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){
// If the target flags on the operand changes the name of the symbol, do that
// before we return the symbol.
if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB) {
if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && isDarwin) {
Name += "$stub";
const char *PGP = AP.MAI->getPrivateGlobalPrefix();
const char *Prefix = "";
@ -132,6 +136,9 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
break;
}
if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && !isDarwin)
RefKind = MCSymbolRefExpr::VK_PLT;
const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
if (!MO.isJTI() && MO.getOffset())

View File

@ -8,8 +8,16 @@
//===----------------------------------------------------------------------===//
#include "PPCMachineFunctionInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
void PPCFunctionInfo::anchor() { }
MCSymbol *PPCFunctionInfo::getPICOffsetSymbol() const {
const MCAsmInfo *MAI = MF.getTarget().getMCAsmInfo();
return MF.getContext().GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix())+
Twine(MF.getFunctionNumber())+"$poff");
}

View File

@ -92,6 +92,12 @@ class PPCFunctionInfo : public MachineFunctionInfo {
/// 64-bit SVR4 ABI.
SmallVector<unsigned, 3> MustSaveCRs;
/// Hold onto our MachineFunction context.
MachineFunction &MF;
/// Whether this uses the PIC Base register or not.
bool UsesPICBase;
public:
explicit PPCFunctionInfo(MachineFunction &MF)
: FramePointerSaveIndex(0),
@ -109,7 +115,9 @@ public:
VarArgsStackOffset(0),
VarArgsNumGPR(0),
VarArgsNumFPR(0),
CRSpillFrameIndex(0) {}
CRSpillFrameIndex(0),
MF(MF),
UsesPICBase(0) {}
int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
@ -170,6 +178,11 @@ public:
const SmallVectorImpl<unsigned> &
getMustSaveCRs() const { return MustSaveCRs; }
void addMustSaveCR(unsigned Reg) { MustSaveCRs.push_back(Reg); }
void setUsesPICBase(bool uses) { UsesPICBase = uses; }
bool usesPICBase() const { return UsesPICBase; }
MCSymbol *getPICOffsetSymbol() const;
};
} // end of namespace llvm

View File

@ -199,7 +199,16 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
if (PPCFI->needsFP(MF))
Reserved.set(PPC::R31);
if (hasBasePointer(MF))
if (hasBasePointer(MF)) {
if (Subtarget.isSVR4ABI() && !Subtarget.isPPC64() &&
MF.getTarget().getRelocationModel() == Reloc::PIC_)
Reserved.set(PPC::R29);
else
Reserved.set(PPC::R30);
}
if (Subtarget.isSVR4ABI() && !Subtarget.isPPC64() &&
MF.getTarget().getRelocationModel() == Reloc::PIC_)
Reserved.set(PPC::R30);
// Reserve Altivec registers when Altivec is unavailable.
@ -695,7 +704,14 @@ unsigned PPCRegisterInfo::getBaseRegister(const MachineFunction &MF) const {
if (!hasBasePointer(MF))
return getFrameRegister(MF);
return Subtarget.isPPC64() ? PPC::X30 : PPC::R30;
if (Subtarget.isPPC64())
return PPC::X30;
if (Subtarget.isSVR4ABI() &&
MF.getTarget().getRelocationModel() == Reloc::PIC_)
return PPC::R29;
return PPC::R30;
}
bool PPCRegisterInfo::hasBasePointer(const MachineFunction &MF) const {

View File

@ -189,6 +189,9 @@ public:
/// isBGQ - True if this is a BG/Q platform.
bool isBGQ() const { return TargetTriple.getVendor() == Triple::BGQ; }
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
// bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
bool isDarwinABI() const { return isDarwin(); }
bool isSVR4ABI() const { return !isDarwin(); }

View File

@ -300,6 +300,8 @@ void X86TargetLowering::resetOperationActions() {
setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
setTruncStoreAction(MVT::i16, MVT::i8, Expand);
setTruncStoreAction(MVT::f64, MVT::f32, Expand);
// SETOEQ and SETUNE require checking two conditions.
setCondCodeAction(ISD::SETOEQ, MVT::f32, Expand);
setCondCodeAction(ISD::SETOEQ, MVT::f64, Expand);
@ -1011,8 +1013,6 @@ void X86TargetLowering::resetOperationActions() {
AddPromotedToType (ISD::SELECT, VT, MVT::v2i64);
}
setTruncStoreAction(MVT::f64, MVT::f32, Expand);
// Custom lower v2i64 and v2f64 selects.
setOperationAction(ISD::LOAD, MVT::v2f64, Legal);
setOperationAction(ISD::LOAD, MVT::v2i64, Legal);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
Index: lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- lib/Target/ARM/ARMInstrInfo.td (revision 271024)
+++ lib/Target/ARM/ARMInstrInfo.td (revision 271026)
@@ -3248,7 +3248,8 @@
def : ARMPat<(ARMadde GPR:$src, so_imm_not:$imm, CPSR),
(SBCri GPR:$src, so_imm_not:$imm)>;
def : ARMPat<(ARMadde GPR:$src, imm0_65535_neg:$imm, CPSR),
- (SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>;
+ (SBCrr GPR:$src, (MOVi16 (imm_not_XFORM imm:$imm)))>,
+ Requires<[IsARM, HasV6T2]>;
// Note: These are implemented in C++ code, because they have to generate
// ADD/SUBrs instructions, which use a complex pattern that a xform function

View File

@ -0,0 +1,51 @@
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 59ba47c..dddc7e7 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -2251,9 +2251,10 @@ llvm::DICompositeType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
if (T && (!T.isForwardDecl() || !RD->getDefinition()))
return T;
- // If this is just a forward declaration, construct an appropriately
- // marked node and just return it.
- if (!RD->getDefinition())
+ // If this is just a forward or incomplete declaration, construct an
+ // appropriately marked node and just return it.
+ const RecordDecl *D = RD->getDefinition();
+ if (!D || !D->isCompleteDefinition())
return getOrCreateRecordFwdDecl(Ty, RDContext);
uint64_t Size = CGM.getContext().getTypeSize(Ty);
diff --git a/test/CodeGenCXX/debug-info-template-fwd.cpp b/test/CodeGenCXX/debug-info-template-fwd.cpp
new file mode 100644
index 0000000..b2b7073
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template-fwd.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -g -emit-llvm -o - | FileCheck %s
+// This test is for a crash when emitting debug info for not-yet-completed
+// types.
+// Test that we don't actually emit a forward decl for the offending class:
+// CHECK: [ DW_TAG_structure_type ] [Derived<int>] {{.*}} [def]
+// rdar://problem/15931354
+template <class A> class Derived;
+
+template <class A> class Base {
+ static Derived<A> *create();
+};
+
+template <class A> struct Derived : Base<A> {
+};
+
+Base<int> *f;
+
+// During the instantiation of Derived<int>, Base<int> becomes required to be
+// complete - since the declaration has already been emitted (due to 'f',
+// above), we immediately try to build debug info for Base<int> which then
+// requires the (incomplete definition) of Derived<int> which is problematic.
+//
+// (if 'f' is not present, the point at which Base<int> becomes required to be
+// complete during the instantiation of Derived<int> is a no-op because
+// Base<int> was never emitted so we ignore it and carry on until we
+// wire up the base class of Derived<int> in the debug info later on)
+Derived<int> d;

View File

@ -0,0 +1,46 @@
commit 96365aef99ec463375dfdaf6eb260823e0477b6a
Author: Adrian Prantl <aprantl@apple.com>
Date: Tue Apr 1 17:52:06 2014 +0000
Debug info: fix a crash when emitting IndirectFieldDecls, which were
previously not handled at all.
rdar://problem/16348575
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205331 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 82db942..2556cf9 100644
--- tools/clang/lib/CodeGen/CGDebugInfo.cpp
+++ tools/clangb/lib/CodeGen/CGDebugInfo.cpp
@@ -1252,7 +1252,7 @@ CollectTemplateParams(const TemplateParameterList *TPList,
V = CGM.GetAddrOfFunction(FD);
// Member data pointers have special handling too to compute the fixed
// offset within the object.
- if (isa<FieldDecl>(D)) {
+ if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
// These five lines (& possibly the above member function pointer
// handling) might be able to be refactored to use similar code in
// CodeGenModule::getMemberPointerConstant
diff --git a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
new file mode 100644
index 0000000..131ceba
--- /dev/null
+++ tools/clang/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
+//
+// Test that indirect field decls are handled gracefully.
+// rdar://problem/16348575
+//
+template <class T, int T::*ptr> class Foo { };
+
+struct Bar {
+ int i1;
+ // CHECK: [ DW_TAG_member ] [line [[@LINE+1]], size 32, align 32, offset 32] [from _ZTSN3BarUt_E]
+ union {
+ // CHECK: [ DW_TAG_member ] [i2] [line [[@LINE+1]], size 32, align 32, offset 0] [from int]
+ int i2;
+ };
+};
+
+Foo<Bar, &Bar::i2> the_foo;

View File

@ -1241,7 +1241,7 @@ CollectTemplateParams(const TemplateParameterList *TPList,
V = CGM.GetAddrOfFunction(FD);
// Member data pointers have special handling too to compute the fixed
// offset within the object.
if (isa<FieldDecl>(D)) {
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
// These five lines (& possibly the above member function pointer
// handling) might be able to be refactored to use similar code in
// CodeGenModule::getMemberPointerConstant
@ -2235,9 +2235,10 @@ llvm::DICompositeType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
if (T && (!T.isForwardDecl() || !RD->getDefinition()))
return T;
// If this is just a forward declaration, construct an appropriately
// marked node and just return it.
if (!RD->getDefinition())
// If this is just a forward or incomplete declaration, construct an
// appropriately marked node and just return it.
const RecordDecl *D = RD->getDefinition();
if (!D || !D->isCompleteDefinition())
return getOrCreateRecordFwdDecl(Ty, RDContext);
uint64_t Size = CGM.getContext().getTypeSize(Ty);

View File

@ -643,7 +643,7 @@ recv_thread(void *arg __unused)
* we can use that.
*/
if (TAILQ_EMPTY(&adist_recv_list)) {
rw_unlock(&adist_remote_lock);
mtx_unlock(&adist_recv_list_lock);
continue;
}
mtx_unlock(&adist_recv_list_lock);

View File

@ -228,6 +228,11 @@ wait_for_file_init(int fd)
PJDLOG_ASSERT(fd != -1);
#ifdef HAVE_KQUEUE
if (wait_for_file_kq != -1) {
close(wait_for_file_kq);
wait_for_file_kq = -1;
}
kq = kqueue();
if (kq == -1) {
pjdlog_errno(LOG_WARNING, "kqueue() failed");

View File

@ -15,6 +15,8 @@ directly or indirectly, with patches, criticism, suggestions, or
ideas:
Andrew Morgan <morgan@transmeta.com>
Ankita Pal <pal.ankita.ankita@gmail.com>
Baptiste Daroussin <bapt@freebsd.org>
Brian Fundakowski Feldman <green@freebsd.org>
Christos Zoulas <christos@netbsd.org>
Daniel Richard G. <skunk@iskunk.org>
@ -25,6 +27,7 @@ ideas:
Eric Melville <eric@freebsd.org>
Espen Grøndahl <espegro@usit.uio.no>
Gary Winiger <gary.winiger@sun.com>
Gavin Atkinson <gavin@freebsd.org>
Gleb Smirnoff <glebius@freebsd.org>
Hubert Feyrer <hubert@feyrer.de>
Jason Evans <jasone@freebsd.org>
@ -46,5 +49,3 @@ ideas:
Takanori Saneto <sanewo@ba2.so-net.ne.jp>
Wojciech A. Koszek <wkoszek@freebsd.org>
Yar Tikhiy <yar@freebsd.org>
$Id: CREDITS 648 2013-03-05 17:54:27Z des $

View File

@ -1,3 +1,24 @@
OpenPAM Ourouparia 2014-09-12
- ENHANCE: When executing a chain, require at least one service
function to succeed. This mitigates fail-open scenarios caused by
misconfigurations or missing modules.
- ENHANCE: Make sure to overwrite buffers which may have contained an
authentication token when they're no longer needed.
- BUGFIX: Under certain circumstances, specifying a non-existent
module (or misspelling the name of a module) in a policy could
result in a fail-open scenario. (CVE-2014-3879)
- FEATURE: Add a search path for modules. This was implemented in
Nummularia but inadvertently left out of the release notes.
- BUGFIX: The is_upper() predicate only accepted the letter A as an
upper-case character instead of the entire A-Z range. As a result,
service and module names containing upper-case letters other than A
would be rejected.
============================================================================
OpenPAM Nummularia 2013-09-07
- ENHANCE: Rewrite the dynamic loader to improve readability and
@ -97,7 +118,7 @@ OpenPAM Lycopsida 2011-12-18
module before loading it.
- ENHANCE: added / improved input validation in many cases, including
the policy file and some function arguments.
the policy file and some function arguments. (CVE-2011-4122)
============================================================================
OpenPAM Hydrangea 2007-12-21
@ -427,5 +448,3 @@ Fixed a number of bugs in the previous release, including:
OpenPAM Calamite 2002-02-09
First (beta) release.
============================================================================
$Id: HISTORY 737 2013-09-07 12:53:55Z des $

View File

@ -54,5 +54,3 @@
directory:
# make install
$Id: INSTALL 648 2013-03-05 17:54:27Z des $

View File

@ -31,5 +31,3 @@ 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.
$Id: LICENSE 648 2013-03-05 17:54:27Z des $

Some files were not shown because too many files have changed in this diff Show More